From 4833dd931b5946ee3a9c82bda08fefcf4d76b8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 21 Jul 2023 12:24:35 +0200 Subject: [PATCH 1/8] Makesdna: more verbose `Align struct error` Change the `makesdna` error message from: ``` Align struct error: Bone color ``` to: ``` Align struct error: Bone::color (starts at 180 on the native platform; 180 % 8 = 4 bytes) ``` This has a few advantages: - The colon notation (`Bone::color`) makes it easier to recognise that this is about a specific struct field. - It makes it clear that this is about the start/offset of the inner struct. - It includes the math the check is actually doing, providing concrete information on how to change the code to fix the issue. Pull Request: https://projects.blender.org/blender/blender/pulls/110291 --- source/blender/makesdna/intern/makesdna.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/blender/makesdna/intern/makesdna.cc b/source/blender/makesdna/intern/makesdna.cc index e1634241d64..f00f8518249 100644 --- a/source/blender/makesdna/intern/makesdna.cc +++ b/source/blender/makesdna/intern/makesdna.cc @@ -1073,7 +1073,15 @@ static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char /* struct alignment */ if (type >= firststruct) { if (sizeof(void *) == 8 && (size_native % 8)) { - fprintf(stderr, "Align struct error: %s %s\n", types[structtype], cp); + fprintf(stderr, + "Align struct error: %s::%s (starts at %d on the native platform; " + "%d %% %lu = %d bytes)\n", + types[structtype], + cp, + size_native, + size_native, + sizeof(void *), + size_native % 8); dna_error = 1; } } -- 2.30.2 From 8dd0faec5498c2b1d3b459958f39d27f6c54d7a0 Mon Sep 17 00:00:00 2001 From: Falk David Date: Fri, 21 Jul 2023 12:44:36 +0200 Subject: [PATCH 2/8] GPv3: Refactor: `ramer_douglas_peucker_simplify` This refactors the `ramer_douglas_peucker_simplify` function to be more generic. No functional changes expected. Pull Request: https://projects.blender.org/blender/blender/pulls/110338 --- .../intern/grease_pencil_edit.cc | 63 ++++++++++++------- .../editors/include/ED_grease_pencil.h | 5 +- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc index 88b248d94fc..0c272674086 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc @@ -403,45 +403,52 @@ static void GREASE_PENCIL_OT_stroke_smooth(wmOperatorType *ot) /** * An implementation of the Ramer-Douglas-Peucker algorithm. * + * \param range: The range to simplify. * \param epsilon: The threshold distance from the coord between two points for when a point * in-between needs to be kept. + * \param dist_function: A function that computes the distance to a point at an index in the range. + * The IndexRange is a subrange of \a range and the index is an index relative to the subrange. * \param points_to_delete: Writes true to the indecies for which the points should be removed. + * \returns the total number of points to remove. */ -void ramer_douglas_peucker_simplify(const Span src, - const float epsilon, - MutableSpan points_to_delete) +int64_t ramer_douglas_peucker_simplify(const IndexRange range, + const float epsilon, + const FunctionRef dist_function, + MutableSpan points_to_delete) { - BLI_assert(src.size() == points_to_delete.size()); - /* Mark all points to not be removed. */ - points_to_delete.fill(false); + points_to_delete.slice(range).fill(false); + int64_t total_points_to_remove = 0; Stack stack; - stack.push(src.index_range()); + stack.push(range); while (!stack.is_empty()) { - const IndexRange range = stack.pop(); - const Span slice = src.slice(range); + const IndexRange sub_range = stack.pop(); + /* Compute the maximum distance and the corresponding distance. */ float max_dist = -1.0f; int max_index = -1; - for (const int64_t index : slice.index_range().drop_front(1).drop_back(1)) { - const float dist = dist_to_line_v3(slice[index], slice.first(), slice.last()); + for (const int64_t sub_index : sub_range.index_range().drop_front(1).drop_back(1)) { + const float dist = dist_function(sub_range, sub_index); if (dist > max_dist) { max_dist = dist; - max_index = index; + max_index = sub_index; } } if (max_dist > epsilon) { - /* Found point outside the epsilon-sized tube. Repeat the search on the left & right side. */ - stack.push(IndexRange(range.first(), max_index + 1)); - stack.push(IndexRange(range.first() + max_index, range.size() - max_index)); + /* Found point outside the epsilon-sized strip. Repeat the search on the left & right side. */ + stack.push(sub_range.slice(IndexRange(max_index + 1))); + stack.push(sub_range.slice(IndexRange(max_index, sub_range.size() - max_index))); } else { - /* Points in `range` are inside the epsilon-sized tube. Mark them to be deleted. */ - points_to_delete.slice(range.drop_front(1).drop_back(1)).fill(true); + /* Points in `sub_range` are inside the epsilon-sized strip. Mark them to be deleted. */ + const IndexRange inside_range = sub_range.drop_front(1).drop_back(1); + total_points_to_remove += inside_range.size(); + points_to_delete.slice(inside_range).fill(true); } } + return total_points_to_remove; } static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op) @@ -466,6 +473,15 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op) } const Span positions = curves.positions(); + + /* Distance function for `ramer_douglas_peucker_simplify`. */ + auto dist_func = [&](IndexRange range, int64_t index_in_range) { + const Span position_slice = positions.slice(range); + const float dist_position = dist_to_line_v3( + position_slice[index_in_range], position_slice.first(), position_slice.last()); + return dist_position; + }; + const VArray cyclic = curves.cyclic(); const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray selection = *curves.attributes().lookup_or_default( @@ -474,6 +490,7 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op) Array points_to_delete(curves.points_num()); selection.materialize(points_to_delete); + std::atomic total_points_to_delete = 0; threading::parallel_for(curves.curves_range(), 128, [&](const IndexRange range) { for (const int curve_i : range) { const IndexRange points = points_by_curve[curve_i]; @@ -488,13 +505,14 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op) const Vector selection_ranges = array_utils::find_all_ranges( curve_selection, true); threading::parallel_for( - selection_ranges.index_range(), 16, [&](const IndexRange range_of_ranges) { + selection_ranges.index_range(), 1024, [&](const IndexRange range_of_ranges) { for (const IndexRange range : selection_ranges.as_span().slice(range_of_ranges)) { - ramer_douglas_peucker_simplify( - positions.slice(range.shift(points.start())), + total_points_to_delete += ramer_douglas_peucker_simplify( + range.shift(points.start()), epsilon, - points_to_delete.as_mutable_span().slice(range.shift(points.start()))); + dist_func, + points_to_delete.as_mutable_span()); } }); @@ -504,12 +522,13 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op) positions[points.last()], positions[points.last(1)], positions[points.first()]); if (dist <= epsilon) { points_to_delete[points.last()] = true; + total_points_to_delete++; } } } }); - if (points_to_delete.as_span().contains(true)) { + if (total_points_to_delete > 0) { IndexMaskMemory memory; curves.remove_points(IndexMask::from_bools(points_to_delete, memory)); drawing.tag_topology_changed(); diff --git a/source/blender/editors/include/ED_grease_pencil.h b/source/blender/editors/include/ED_grease_pencil.h index 466205e1a86..670c20a4224 100644 --- a/source/blender/editors/include/ED_grease_pencil.h +++ b/source/blender/editors/include/ED_grease_pencil.h @@ -72,7 +72,10 @@ void gaussian_blur_1D(const GSpan src, bool is_cyclic, GMutableSpan dst); -void ramer_douglas_peucker_simplify(const Span src, float epsilon, MutableSpan dst); +int64_t ramer_douglas_peucker_simplify(IndexRange range, + float epsilon, + FunctionRef dist_function, + MutableSpan dst); } // namespace blender::ed::greasepencil #endif -- 2.30.2 From 29b67ad31b11944051c0a1adbe325367a6924319 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 21 Jul 2023 14:18:46 +0200 Subject: [PATCH 3/8] Manual Reference: Includes the copyright This was an oversight on the license headers copyright pass [1]. Also since the manual reference is generated by this script we can update the copyright year every time. [1] - 8f109712ee6d --- tools/utils_doc/rna_manual_reference_updater.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/utils_doc/rna_manual_reference_updater.py b/tools/utils_doc/rna_manual_reference_updater.py index 65acc83a133..73f965c55e6 100644 --- a/tools/utils_doc/rna_manual_reference_updater.py +++ b/tools/utils_doc/rna_manual_reference_updater.py @@ -33,6 +33,7 @@ import os import argparse import re import sys +import datetime try: import sphobjinv @@ -73,8 +74,12 @@ def write_mappings(inv, output): # Write the file file = open(output, "w", encoding="utf-8") fw = file.write + year = datetime.date.today().year + fw(f"# SPDX-FileCopyrightText: 2019-%d Blender Foundation\n" % (year)) + fw("#\n") fw("# SPDX-License-Identifier: GPL-2.0-or-later\n") + fw("\n") fw("# Do not edit this file.") fw(" This file is auto generated from rna_manual_reference_updater.py\n\n") # Prevent systems with autopep8 configured from re-formatting the file. -- 2.30.2 From a51b38dec57012f2593f8e2529a40ab9164cd72b Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 21 Jul 2023 14:23:49 +0200 Subject: [PATCH 4/8] Cleanup: make format --- scripts/startup/bl_ui/space_toolsystem_toolbar.py | 2 +- .../blender/editors/grease_pencil/intern/grease_pencil_edit.cc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 030390c5e95..1ad647fd25c 100644 --- a/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1741,7 +1741,7 @@ class _defs_paint_grease_pencil: icon="brush.gpencil_draw.draw", data_block='DRAW', ) - + @ToolDef.from_fn def erase(): def draw_settings(context, layout, _tool): diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc index 0c272674086..3a46e7a4f29 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc @@ -437,7 +437,8 @@ int64_t ramer_douglas_peucker_simplify(const IndexRange range, } if (max_dist > epsilon) { - /* Found point outside the epsilon-sized strip. Repeat the search on the left & right side. */ + /* Found point outside the epsilon-sized strip. Repeat the search on the left & right side. + */ stack.push(sub_range.slice(IndexRange(max_index + 1))); stack.push(sub_range.slice(IndexRange(max_index, sub_range.size() - max_index))); } -- 2.30.2 From 9ec018e1df176713726f9a6db90c12b2e7dc5108 Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Fri, 21 Jul 2023 08:40:56 -0400 Subject: [PATCH 5/8] Fix: Bump BLENDER_FILE_SUBVERSION to 11 used in #108286 --- source/blender/blenkernel/BKE_blender_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index dedc081597c..09a86dd66c1 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 10 +#define BLENDER_FILE_SUBVERSION 11 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file -- 2.30.2 From 126fd4a18161ce14e7417c072ad9bd3f283e319d Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 21 Jul 2023 14:41:45 +0200 Subject: [PATCH 6/8] Fix #110341: Appended text looses user after reload Even if a text datablock was "used" by in the Text Editor, it would be lost after save/reload if no fake user is set. This is not in line with other datablocks if they are used by an editor (e.g. images, clips, masks etc.). Now handle this with `IDWALK_CB_USER_ONE` (instead of `IDWALK_CB_NOP`) in `id_refcount_recompute_callback` > `BKE_screen_foreach_id_screen_area` which re-ensures a user is set. (Bit on shaky ground here, but this seems like this is how this is handled for other editors "consuming" a datablock). Pull Request: https://projects.blender.org/blender/blender/pulls/110344 --- source/blender/blenkernel/intern/screen.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/screen.cc b/source/blender/blenkernel/intern/screen.cc index 5aaede93d8f..df161545251 100644 --- a/source/blender/blenkernel/intern/screen.cc +++ b/source/blender/blenkernel/intern/screen.cc @@ -174,7 +174,7 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area } case SPACE_TEXT: { SpaceText *st = (SpaceText *)sl; - BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, st->text, IDWALK_CB_NOP); + BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, st->text, IDWALK_CB_USER_ONE); break; } case SPACE_SCRIPT: { -- 2.30.2 From b853f21562ac63fc807bd288413509401032ecc6 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 21 Jul 2023 15:01:05 +0200 Subject: [PATCH 7/8] Docs: Update RNA to user manual url map --- scripts/modules/rna_manual_reference.py | 162 ++++++++++++++++++------ 1 file changed, 124 insertions(+), 38 deletions(-) diff --git a/scripts/modules/rna_manual_reference.py b/scripts/modules/rna_manual_reference.py index 13f7a5d6259..de3451fd70e 100644 --- a/scripts/modules/rna_manual_reference.py +++ b/scripts/modules/rna_manual_reference.py @@ -69,6 +69,7 @@ url_manual_mapping = ( ("bpy.types.spacespreadsheet.display_context_path_collapsed*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-display-context-path-collapsed"), ("bpy.types.toolsettings.annotation_stroke_placement_view2d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view2d"), ("bpy.types.toolsettings.annotation_stroke_placement_view3d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view3d"), + ("bpy.ops.object.simulation_nodes_cache_calculate_to_frame*", "physics/simulation_nodes.html#bpy-ops-object-simulation-nodes-cache-calculate-to-frame"), ("bpy.types.brushcurvessculptsettings.density_add_attempts*", "sculpt_paint/curves_sculpting/tools/density_curves.html#bpy-types-brushcurvessculptsettings-density-add-attempts"), ("bpy.types.brushgpencilsettings.use_random_press_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-strength"), ("bpy.types.fluiddomainsettings.use_collision_border_front*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-front"), @@ -92,6 +93,7 @@ url_manual_mapping = ( ("bpy.types.fluiddomainsettings.use_collision_border_left*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-left"), ("bpy.types.lineartgpencilmodifier.use_intersection_match*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection-match"), ("bpy.types.rendersettings_simplify_gpencil_view_modifier*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-modifier"), + ("bpy.types.spaceoutliner.use_filter_object_grease_pencil*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-grease-pencil"), ("bpy.types.brushcurvessculptsettings.interpolate_length*", "sculpt_paint/curves_sculpting/tools/add_curves.html#bpy-types-brushcurvessculptsettings-interpolate-length"), ("bpy.types.brushgpencilsettings.eraser_thickness_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-thickness-factor"), ("bpy.types.brushgpencilsettings.use_random_press_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-radius"), @@ -283,6 +285,7 @@ url_manual_mapping = ( ("bpy.types.materialgpencilstyle.use_stroke_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-stroke-holdout"), ("bpy.types.movietrackingplanetrack.use_auto_keying*", "movie_clip/tracking/clip/sidebar/track/plane_track.html#bpy-types-movietrackingplanetrack-use-auto-keying"), ("bpy.types.movietrackingsettings.use_tripod_solver*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-tripod-solver"), + ("bpy.types.nodesmodifier.simulation_bake_directory*", "modeling/modifiers/generate/geometry_nodes.html#bpy-types-nodesmodifier-simulation-bake-directory"), ("bpy.types.rendersettings.simplify_child_particles*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-child-particles"), ("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"), ("bpy.types.sculpt.automasking_start_normal_falloff*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-automasking-start-normal-falloff"), @@ -408,6 +411,7 @@ url_manual_mapping = ( ("bpy.types.spacesequenceeditor.proxy_render_size*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-proxy-render-size"), ("bpy.types.spacespreadsheetrowfilter.column_name*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-column-name"), ("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"), + ("bpy.types.toolsettings.snap_elements_individual*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements-individual"), ("bpy.types.toolsettings.use_keyframe_cycle_aware*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-cycle-aware"), ("bpy.types.toolsettings.use_keyframe_insert_auto*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-insert-auto"), ("bpy.types.view3doverlay.show_sculpt_curves_cage*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-view3doverlay-show-sculpt-curves-cage"), @@ -545,8 +549,10 @@ url_manual_mapping = ( ("bpy.types.transformsequence.use_uniform_scale*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-use-uniform-scale"), ("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"), ("bpy.types.view3doverlay.show_viewer_attribute*", "modeling/geometry_nodes/output/viewer.html#bpy-types-view3doverlay-show-viewer-attribute"), + ("bpy.types.viewlayereevee.use_pass_transparent*", "render/layers/passes.html#bpy-types-viewlayereevee-use-pass-transparent"), ("bpy.ops.gpencil.bake_grease_pencil_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-grease-pencil-animation"), ("bpy.ops.object.multires_higher_levels_delete*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-higher-levels-delete"), + ("bpy.ops.object.simulation_nodes_cache_delete*", "physics/simulation_nodes.html#bpy-ops-object-simulation-nodes-cache-delete"), ("bpy.ops.object.vertex_group_copy_to_selected*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-selected"), ("bpy.ops.outliner.collection_duplicate_linked*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate-linked"), ("bpy.ops.view3d.edit_mesh_extrude_move_normal*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-move-normal"), @@ -615,6 +621,8 @@ url_manual_mapping = ( ("bpy.types.spacespreadsheet.object_eval_state*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-object-eval-state"), ("bpy.types.spaceuveditor.display_stretch_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-display-stretch-type"), ("bpy.types.spaceuveditor.show_grid_over_image*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-grid-over-image"), + ("bpy.types.textcharacterformat.use_small_caps*", "modeling/texts/properties.html#bpy-types-textcharacterformat-use-small-caps"), + ("bpy.types.toolsettings.proportional_distance*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-proportional-distance"), ("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"), ("bpy.types.toolsettings.use_proportional_edit*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit"), ("bpy.types.toolsettings.uv_sticky_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-sticky-select-mode"), @@ -623,6 +631,7 @@ url_manual_mapping = ( ("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"), ("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"), ("bpy.ops.object.geometry_nodes_move_to_nodes*", "modeling/modifiers/generate/geometry_nodes.html#bpy-ops-object-geometry-nodes-move-to-nodes"), + ("bpy.ops.preferences.script_directory_remove*", "editors/preferences/file_paths.html#bpy-ops-preferences-script-directory-remove"), ("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"), ("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"), ("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"), @@ -682,6 +691,7 @@ url_manual_mapping = ( ("bpy.types.spaceuveditor.show_modified_edges*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-modified-edges"), ("bpy.types.spaceview3d.transform_orientation*", "editors/3dview/controls/orientation.html#bpy-types-spaceview3d-transform-orientation"), ("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-collections"), + ("bpy.types.textcharacterformat.use_underline*", "modeling/texts/properties.html#bpy-types-textcharacterformat-use-underline"), ("bpy.types.toolsettings.use_snap_peel_object*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-peel-object"), ("bpy.types.transformsequence.translate_start*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-translate-start"), ("bpy.types.view3doverlay.fade_inactive_alpha*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-fade-inactive-alpha"), @@ -692,6 +702,7 @@ url_manual_mapping = ( ("bpy.ops.geometry.color_attribute_duplicate*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-duplicate"), ("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"), ("bpy.ops.object.material_slot_remove_unused*", "scene_layout/object/editing/cleanup.html#bpy-ops-object-material-slot-remove-unused"), + ("bpy.ops.object.simulation_nodes_cache_bake*", "physics/simulation_nodes.html#bpy-ops-object-simulation-nodes-cache-bake"), ("bpy.ops.outliner.collection_disable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable-render"), ("bpy.ops.scene.freestyle_alpha_modifier_add*", "render/freestyle/view_layer/line_style/alpha.html#bpy-ops-scene-freestyle-alpha-modifier-add"), ("bpy.ops.scene.freestyle_color_modifier_add*", "render/freestyle/view_layer/line_style/color.html#bpy-ops-scene-freestyle-color-modifier-add"), @@ -739,6 +750,8 @@ url_manual_mapping = ( ("bpy.types.geometrynodesamplenearestsurface*", "modeling/geometry_nodes/mesh/sample/sample_nearest_surface.html#bpy-types-geometrynodesamplenearestsurface"), ("bpy.types.gpencillayer.use_viewlayer_masks*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-viewlayer-masks"), ("bpy.types.greasepencil.onion_keyframe_type*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-keyframe-type"), + ("bpy.types.imagetexture.use_calculate_alpha*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-use-calculate-alpha"), + ("bpy.types.imagetexture.use_filter_size_min*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-use-filter-size-min"), ("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"), ("bpy.types.lineartgpencilmodifier.use_loose*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-loose"), ("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-stroke"), @@ -775,7 +788,8 @@ url_manual_mapping = ( ("bpy.ops.outliner.collection_enable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-enable-render"), ("bpy.ops.outliner.collection_exclude_clear*", "editors/outliner/editing.html#bpy-ops-outliner-collection-exclude-clear"), ("bpy.ops.outliner.collection_holdout_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-clear"), - ("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-set-change-visibility"), + ("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-face-set-change-visibility"), + ("bpy.ops.sculpt.face_set_invert_visibility*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-set-invert-visibility"), ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-randomize-colors"), ("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"), ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), @@ -850,12 +864,15 @@ url_manual_mapping = ( ("bpy.types.spaceuveditor.show_pixel_coords*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-show-pixel-coords"), ("bpy.types.spaceview3d.show_reconstruction*", "editors/3dview/display/overlays.html#bpy-types-spaceview3d-show-reconstruction"), ("bpy.types.toolsettings.gpencil_selectmode*", "grease_pencil/selecting.html#bpy-types-toolsettings-gpencil-selectmode"), + ("bpy.types.toolsettings.snap_elements_base*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements-base"), ("bpy.types.toolsettings.use_auto_normalize*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-auto-normalize"), ("bpy.types.toolsettings.use_mesh_automerge*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge"), ("bpy.types.toolsettings.use_snap_sequencer*", "video_editing/edit/montage/editing.html#bpy-types-toolsettings-use-snap-sequencer"), ("bpy.types.toolsettings.use_snap_translate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-translate"), ("bpy.types.toolsettings.use_uv_select_sync*", "editors/uv/selecting.html#bpy-types-toolsettings-use-uv-select-sync"), ("bpy.types.transformsequence.interpolation*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-interpolation"), + ("bpy.types.view3doverlay.retopology_offset*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-retopology-offset"), + ("bpy.types.view3doverlay.show_light_colors*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-light-colors"), ("bpy.types.view3doverlay.wireframe_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-opacity"), ("bpy.ops.asset.open_containing_blend_file*", "editors/asset_browser.html#bpy-ops-asset-open-containing-blend-file"), ("bpy.ops.geometry.color_attribute_convert*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-convert"), @@ -865,6 +882,7 @@ url_manual_mapping = ( ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), ("bpy.ops.object.modifier_copy_to_selected*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy-to-selected"), ("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"), + ("bpy.ops.preferences.script_directory_add*", "editors/preferences/file_paths.html#bpy-ops-preferences-script-directory-add"), ("bpy.types.animvizmotionpaths.frame_after*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-after"), ("bpy.types.animvizmotionpaths.frame_start*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-start"), ("bpy.types.bakesettings.use_pass_indirect*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-indirect"), @@ -914,6 +932,7 @@ url_manual_mapping = ( ("bpy.types.greasepencil.ghost_after_range*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-ghost-after-range"), ("bpy.types.greasepencil.use_ghosts_always*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-ghosts-always"), ("bpy.types.imageformatsettings.color_mode*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-mode"), + ("bpy.types.imagetexture.use_interpolation*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-use-interpolation"), ("bpy.types.linestyle*modifier_alongstroke*", "render/freestyle/view_layer/line_style/modifiers/color/along_stroke.html#bpy-types-linestyle-modifier-alongstroke"), ("bpy.types.linestyle*modifier_creaseangle*", "render/freestyle/view_layer/line_style/modifiers/color/crease_angle.html#bpy-types-linestyle-modifier-creaseangle"), ("bpy.types.linestylecolormodifier_tangent*", "render/freestyle/view_layer/line_style/modifiers/color/tangent.html#bpy-types-linestylecolormodifier-tangent"), @@ -947,7 +966,9 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"), ("bpy.types.spaceuveditor.pixel_round_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-round-mode"), ("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"), + ("bpy.types.textcharacterformat.use_italic*", "modeling/texts/properties.html#bpy-types-textcharacterformat-use-italic"), ("bpy.types.toolsettings.use_lock_relative*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-lock-relative"), + ("bpy.types.toolsettings.vertex_group_user*", "editors/3dview/display/overlays.html#bpy-types-toolsettings-vertex-group-user"), ("bpy.types.vertexpaint.use_group_restrict*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-vertexpaint-use-group-restrict"), ("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"), ("bpy.types.windowmanager.asset_path_dummy*", "editors/asset_browser.html#bpy-types-windowmanager-asset-path-dummy"), @@ -1017,6 +1038,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodematerialselection*", "modeling/geometry_nodes/material/material_selection.html#bpy-types-geometrynodematerialselection"), ("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"), ("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"), + ("bpy.types.imagetexture.use_mipmap_gauss*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-use-mipmap-gauss"), ("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"), ("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"), ("bpy.types.material.use_backface_culling*", "render/eevee/materials/settings.html#bpy-types-material-use-backface-culling"), @@ -1041,6 +1063,7 @@ url_manual_mapping = ( ("bpy.types.spacesequenceeditor.view_type*", "editors/video_sequencer/introduction.html#bpy-types-spacesequenceeditor-view-type"), ("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"), ("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"), + ("bpy.types.spacetexteditor.use_live_edit*", "editors/text_editor.html#bpy-types-spacetexteditor-use-live-edit"), ("bpy.types.spaceuveditor.tile_grid_shape*", "editors/uv/overlays.html#bpy-types-spaceuveditor-tile-grid-shape"), ("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"), ("bpy.types.spaceview3d.use_render_border*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-render-border"), @@ -1048,14 +1071,14 @@ url_manual_mapping = ( ("bpy.types.toolsettings.lock_object_mode*", "interface/window_system/topbar.html#bpy-types-toolsettings-lock-object-mode"), ("bpy.types.toolsettings.mesh_select_mode*", "modeling/meshes/selecting/introduction.html#bpy-types-toolsettings-mesh-select-mode"), ("bpy.types.toolsettings.use_snap_nonedit*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-nonedit"), - ("bpy.types.toolsettings.use_snap_project*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-project"), ("bpy.types.transformorientationslot.type*", "editors/3dview/controls/orientation.html#bpy-types-transformorientationslot-type"), ("bpy.types.transformsequence.scale_start*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-scale-start"), ("bpy.types.unitsettings.temperature_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-temperature-unit"), ("bpy.types.vertexweightproximitymodifier*", "modeling/modifiers/modify/weight_proximity.html#bpy-types-vertexweightproximitymodifier"), + ("bpy.types.view3doverlay.show_retopology*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-retopology"), ("bpy.types.view3doverlay.show_wireframes*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-wireframes"), ("bpy.types.view3dshading.background_type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-background-type"), - ("bpy.types.windowmanager.poselib_flipped*", "animation/armatures/posing/editing/pose_library.html#bpy-types-windowmanager-poselib-flipped"), + ("bpy.types.viewlayereevee.use_pass_bloom*", "render/layers/passes.html#bpy-types-viewlayereevee-use-pass-bloom"), ("bpy.types.workspace.use_filter_by_owner*", "interface/window_system/workspaces.html#bpy-types-workspace-use-filter-by-owner"), ("bpy.ops.brush.stencil_fit_image_aspect*", "sculpt_paint/brush/texture.html#bpy-ops-brush-stencil-fit-image-aspect"), ("bpy.ops.gpencil.image_to_grease_pencil*", "editors/image/editing.html#bpy-ops-gpencil-image-to-grease-pencil"), @@ -1101,6 +1124,7 @@ url_manual_mapping = ( ("bpy.types.geometrynoderealizeinstances*", "modeling/geometry_nodes/instances/realize_instances.html#bpy-types-geometrynoderealizeinstances"), ("bpy.types.geometrynodeseparategeometry*", "modeling/geometry_nodes/geometry/operations/separate_geometry.html#bpy-types-geometrynodeseparategeometry"), ("bpy.types.geometrynodesetmaterialindex*", "modeling/geometry_nodes/material/set_material_index.html#bpy-types-geometrynodesetmaterialindex"), + ("bpy.types.geometrynodesimulationoutput*", "modeling/geometry_nodes/simulation/simulation_zone.html#bpy-types-geometrynodesimulationoutput"), ("bpy.types.greasepencil.edit_line_color*", "grease_pencil/properties/display.html#bpy-types-greasepencil-edit-line-color"), ("bpy.types.material.preview_render_type*", "render/materials/preview.html#bpy-types-material-preview-render-type"), ("bpy.types.materialgpencilstyle.pattern*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-pattern"), @@ -1131,14 +1155,16 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"), ("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"), ("bpy.types.spaceview3d.use_local_camera*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-camera"), + ("bpy.types.textcharacterformat.use_bold*", "modeling/texts/properties.html#bpy-types-textcharacterformat-use-bold"), + ("bpy.types.textcurve.underline_position*", "modeling/texts/properties.html#bpy-types-textcurve-underline-position"), ("bpy.types.toolsettings.snap_uv_element*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-snap-uv-element"), ("bpy.types.toolsettings.use_snap_rotate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-rotate"), ("bpy.types.toolsettings.uv_relax_method*", "modeling/meshes/uv/tools/relax.html#bpy-types-toolsettings-uv-relax-method"), ("bpy.types.unitsettings.system_rotation*", "scene_layout/scene/properties.html#bpy-types-unitsettings-system-rotation"), ("bpy.types.view3doverlay.display_handle*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-display-handle"), ("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"), - ("bpy.ops.anim.channels_editable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-editable-toggle"), - ("bpy.ops.anim.channels_setting_disable*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-setting-disable"), + ("bpy.ops.anim.channels_editable_toggle*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-editable-toggle"), + ("bpy.ops.anim.channels_setting_disable*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-setting-disable"), ("bpy.ops.brush.stencil_reset_transform*", "sculpt_paint/brush/texture.html#bpy-ops-brush-stencil-reset-transform"), ("bpy.ops.curve.normals_make_consistent*", "modeling/curves/editing/control_points.html#bpy-ops-curve-normals-make-consistent"), ("bpy.ops.curves.snap_curves_to_surface*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-curves-snap-curves-to-surface"), @@ -1187,7 +1213,7 @@ url_manual_mapping = ( ("bpy.types.compositornodeseparatecolor*", "compositing/types/converter/separate_color.html#bpy-types-compositornodeseparatecolor"), ("bpy.types.compositornodesetalpha.mode*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha-mode"), ("bpy.types.curves.use_sculpt_collision*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-curves-use-sculpt-collision"), - ("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels.html#bpy-types-dopesheet-use-filter-invert"), + ("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels/introduction.html#bpy-types-dopesheet-use-filter-invert"), ("bpy.types.editbone.use_local_location*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-local-location"), ("bpy.types.ffmpegsettings.audio_volume*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-volume"), ("bpy.types.ffmpegsettings.max_b_frames*", "render/output/properties/output.html#bpy-types-ffmpegsettings-max-b-frames"), @@ -1212,6 +1238,7 @@ url_manual_mapping = ( ("bpy.types.geometrynoderotateinstances*", "modeling/geometry_nodes/instances/rotate_instances.html#bpy-types-geometrynoderotateinstances"), ("bpy.types.geometrynodesampleuvsurface*", "modeling/geometry_nodes/mesh/sample/sample_uv_surface.html#bpy-types-geometrynodesampleuvsurface"), ("bpy.types.geometrynodesetsplinecyclic*", "modeling/geometry_nodes/curve/write/set_spline_cyclic.html#bpy-types-geometrynodesetsplinecyclic"), + ("bpy.types.geometrynodesimulationinput*", "modeling/geometry_nodes/simulation/simulation_zone.html#bpy-types-geometrynodesimulationinput"), ("bpy.types.geometrynodesplineparameter*", "modeling/geometry_nodes/curve/read/spline_parameter.html#bpy-types-geometrynodesplineparameter"), ("bpy.types.gpencillayer.use_mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-mask-layer"), ("bpy.types.greasepencil.use_curve_edit*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-curve-edit"), @@ -1222,6 +1249,7 @@ url_manual_mapping = ( ("bpy.types.motionpath.use_custom_color*", "animation/motion_paths.html#bpy-types-motionpath-use-custom-color"), ("bpy.types.movietrackingcamera.brown_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-k"), ("bpy.types.movietrackingcamera.brown_p*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-p"), + ("bpy.types.object.use_simulation_cache*", "physics/simulation_nodes.html#bpy-types-object-use-simulation-cache"), ("bpy.types.object.visible_transmission*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-transmission"), ("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"), ("bpy.types.pointlight.shadow_soft_size*", "render/lights/light_object.html#bpy-types-pointlight-shadow-soft-size"), @@ -1252,12 +1280,13 @@ url_manual_mapping = ( ("bpy.types.toolsettings.use_snap_scale*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-scale"), ("bpy.types.toolsettings.uv_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-select-mode"), ("bpy.types.viewlayer.material_override*", "render/layers/introduction.html#bpy-types-viewlayer-material-override"), - ("bpy.ops.anim.channels_fcurves_enable*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-fcurves-enable"), - ("bpy.ops.anim.channels_setting_enable*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-setting-enable"), - ("bpy.ops.anim.channels_setting_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-setting-toggle"), + ("bpy.ops.anim.channels_fcurves_enable*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-fcurves-enable"), + ("bpy.ops.anim.channels_setting_enable*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-setting-enable"), + ("bpy.ops.anim.channels_setting_toggle*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-setting-toggle"), ("bpy.ops.clip.set_viewport_background*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-viewport-background"), ("bpy.ops.geometry.color_attribute_add*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-add"), ("bpy.ops.gpencil.interpolate_sequence*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-interpolate-sequence"), + ("bpy.ops.graph.driver_variables_paste*", "animation/drivers/drivers_panel.html#bpy-ops-graph-driver-variables-paste"), ("bpy.ops.mask.normals_make_consistent*", "movie_clip/masking/editing.html#bpy-ops-mask-normals-make-consistent"), ("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-make-consistent"), ("bpy.ops.mesh.offset_edge_loops_slide*", "modeling/meshes/editing/edge/offset_edge_slide.html#bpy-ops-mesh-offset-edge-loops-slide"), @@ -1303,6 +1332,7 @@ url_manual_mapping = ( ("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierfunctiongenerator"), ("bpy.types.geometrynodecollectioninfo*", "modeling/geometry_nodes/input/scene/collection_info.html#bpy-types-geometrynodecollectioninfo"), ("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/operations/delete_geometry.html#bpy-types-geometrynodedeletegeometry"), + ("bpy.types.geometrynodeindexofnearest*", "modeling/geometry_nodes/geometry/sample/index_of_nearest.html#bpy-types-geometrynodeindexofnearest"), ("bpy.types.geometrynodeinputcurvetilt*", "modeling/geometry_nodes/curve/read/curve_tilt.html#bpy-types-geometrynodeinputcurvetilt"), ("bpy.types.geometrynodeinputscenetime*", "modeling/geometry_nodes/input/scene/scene_time.html#bpy-types-geometrynodeinputscenetime"), ("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/point/points_to_volume.html#bpy-types-geometrynodepointstovolume"), @@ -1317,6 +1347,7 @@ url_manual_mapping = ( ("bpy.types.gpencillayer.channel_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-channel-color"), ("bpy.types.gpencillayer.use_solo_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-solo-mode"), ("bpy.types.greasepencil.use_multiedit*", "grease_pencil/multiframe.html#bpy-types-greasepencil-use-multiedit"), + ("bpy.types.imagetexture.use_flip_axis*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-use-flip-axis"), ("bpy.types.keyframe.handle_right_type*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-right-type"), ("bpy.types.materialgpencilstyle.color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-color"), ("bpy.types.movietrackingcamera.nuke_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-nuke-k"), @@ -1342,12 +1373,13 @@ url_manual_mapping = ( ("bpy.types.spaceoutliner.filter_state*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-state"), ("bpy.types.spaceuveditor.show_stretch*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-stretch"), ("bpy.types.spotlight.shadow_soft_size*", "render/lights/light_object.html#bpy-types-spotlight-shadow-soft-size"), + ("bpy.types.textcurve.small_caps_scale*", "modeling/texts/properties.html#bpy-types-textcurve-small-caps-scale"), ("bpy.types.toolsettings.keyframe_type*", "editors/timeline.html#bpy-types-toolsettings-keyframe-type"), - ("bpy.types.toolsettings.snap_elements*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements"), ("bpy.types.toolsettings.use_snap_edit*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-edit"), ("bpy.types.toolsettings.use_snap_node*", "interface/controls/nodes/arranging.html#bpy-types-toolsettings-use-snap-node"), ("bpy.types.toolsettings.use_snap_self*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-self"), ("bpy.types.viewlayer.active_aov_index*", "render/layers/passes.html#bpy-types-viewlayer-active-aov-index"), + ("bpy.ops.anim.channels_view_selected*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-view-selected"), ("bpy.ops.clip.tracking_object_remove*", "movie_clip/tracking/clip/sidebar/track/objects.html#bpy-ops-clip-tracking-object-remove"), ("bpy.ops.constraint.copy_to_selected*", "animation/constraints/interface/header.html#bpy-ops-constraint-copy-to-selected"), ("bpy.ops.curves.set_selection_domain*", "modeling/curves/primitives.html#bpy-ops-curves-set-selection-domain"), @@ -1358,6 +1390,7 @@ url_manual_mapping = ( ("bpy.ops.gpencil.stroke_cyclical_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-cyclical-set"), ("bpy.ops.gpencil.vertex_color_invert*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-invert"), ("bpy.ops.gpencil.vertex_color_levels*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-levels"), + ("bpy.ops.graph.driver_variables_copy*", "animation/drivers/drivers_panel.html#bpy-ops-graph-driver-variables-copy"), ("bpy.ops.mask.slide_spline_curvature*", "movie_clip/masking/editing.html#bpy-ops-mask-slide-spline-curvature"), ("bpy.ops.mesh.flip_quad_tessellation*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-flip-quad-tessellation"), ("bpy.ops.mesh.primitive_cylinder_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cylinder-add"), @@ -1377,6 +1410,7 @@ url_manual_mapping = ( ("bpy.ops.poselib.convert_old_poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-convert-old-poselib"), ("bpy.ops.render.shutter_curve_preset*", "render/cycles/render_settings/motion_blur.html#bpy-ops-render-shutter-curve-preset"), ("bpy.ops.scene.view_layer_remove_aov*", "render/layers/passes.html#bpy-ops-scene-view-layer-remove-aov"), + ("bpy.ops.sculpt.project_line_gesture*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-project-line-gesture"), ("bpy.ops.sculpt_curves.select_random*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-random"), ("bpy.ops.sequencer.view_ghost_border*", "editors/video_sequencer/preview/sidebar.html#bpy-ops-sequencer-view-ghost-border"), ("bpy.ops.ui.override_idtemplate_make*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-override-idtemplate-make"), @@ -1419,9 +1453,10 @@ url_manual_mapping = ( ("bpy.types.freestylelineset.qi_start*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-qi-start"), ("bpy.types.freestylelinestyle.rounds*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-rounds"), ("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/utilities/text/replace_string.html#bpy-types-functionnodereplacestring"), - ("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"), + ("bpy.types.functionnodeseparatecolor*", "editors/texture_node/types/color/separate_color.html#bpy-types-functionnodeseparatecolor"), ("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"), ("bpy.types.geometrynodeblurattribute*", "modeling/geometry_nodes/attribute/blur_attribute.html#bpy-types-geometrynodeblurattribute"), + ("bpy.types.geometrynodecornersofedge*", "modeling/geometry_nodes/mesh/topology/corners_of_edge.html#bpy-types-geometrynodecornersofedge"), ("bpy.types.geometrynodecornersofface*", "modeling/geometry_nodes/mesh/topology/corners_of_face.html#bpy-types-geometrynodecornersofface"), ("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"), ("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"), @@ -1439,6 +1474,7 @@ url_manual_mapping = ( ("bpy.types.greasepencil.before_color*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-before-color"), ("bpy.types.greasepencil.onion_factor*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-factor"), ("bpy.types.greasepencil.pixel_factor*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-pixel-factor"), + ("bpy.types.imagetexture.invert_alpha*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-invert-alpha"), ("bpy.types.keyframe.handle_left_type*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-left-type"), ("bpy.types.light.use_custom_distance*", "render/eevee/lighting.html#bpy-types-light-use-custom-distance"), ("bpy.types.material.refraction_depth*", "render/eevee/materials/settings.html#bpy-types-material-refraction-depth"), @@ -1460,7 +1496,7 @@ url_manual_mapping = ( ("bpy.types.sculpt.use_smooth_shading*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-use-smooth-shading"), ("bpy.types.sequence.frame_offset_end*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-frame-offset-end"), ("bpy.types.sequenceeditor.show_cache*", "editors/video_sequencer/sequencer/navigating.html#bpy-types-sequenceeditor-show-cache"), - ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/anisotropic.html#bpy-types-shadernodebsdfanisotropic"), + ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/glossy.html#bpy-types-shadernodebsdfanisotropic"), ("bpy.types.shadernodebsdftranslucent*", "render/shader_nodes/shader/translucent.html#bpy-types-shadernodebsdftranslucent"), ("bpy.types.shadernodebsdftransparent*", "render/shader_nodes/shader/transparent.html#bpy-types-shadernodebsdftransparent"), ("bpy.types.shadernodetexpointdensity*", "render/shader_nodes/textures/point_density.html#bpy-types-shadernodetexpointdensity"), @@ -1479,9 +1515,11 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor.tab_width*", "editors/text_editor.html#bpy-types-spacetexteditor-tab-width"), ("bpy.types.spaceuveditor.lock_bounds*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-lock-bounds"), ("bpy.types.spline.tilt_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-tilt-interpolation"), + ("bpy.types.textcurve.space_character*", "modeling/texts/properties.html#bpy-types-textcurve-space-character"), ("bpy.types.transformorientation.name*", "editors/3dview/controls/orientation.html#bpy-types-transformorientation-name"), ("bpy.types.unitsettings.scale_length*", "scene_layout/scene/properties.html#bpy-types-unitsettings-scale-length"), ("bpy.types.unitsettings.use_separate*", "scene_layout/scene/properties.html#bpy-types-unitsettings-use-separate"), + ("bpy.types.view3doverlay.show_weight*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-weight"), ("bpy.types.viewlayer.use_motion_blur*", "render/layers/introduction.html#bpy-types-viewlayer-use-motion-blur"), ("bpy.types.volumedisplay.slice_depth*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-depth"), ("bpy.types.worldmistsettings.falloff*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-falloff"), @@ -1512,6 +1550,7 @@ url_manual_mapping = ( ("bpy.ops.sculpt.set_persistent_base*", "sculpt_paint/sculpting/tools/layer.html#bpy-ops-sculpt-set-persistent-base"), ("bpy.ops.sequencer.crossfade_sounds*", "video_editing/edit/montage/strips/transitions/sound_crossfade.html#bpy-ops-sequencer-crossfade-sounds"), ("bpy.ops.sequencer.export_subtitles*", "editors/video_sequencer/preview/header.html#bpy-ops-sequencer-export-subtitles"), + ("bpy.ops.text.jump_to_file_at_point*", "editors/text_editor.html#bpy-ops-text-jump-to-file-at-point"), ("bpy.ops.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"), ("bpy.ops.view3d.clear_render_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clear-render-border"), ("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"), @@ -1548,7 +1587,7 @@ url_manual_mapping = ( ("bpy.types.freestylelineset.exclude*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-exclude"), ("bpy.types.freestylelinestyle.alpha*", "render/freestyle/view_layer/line_style/alpha.html#bpy-types-freestylelinestyle-alpha"), ("bpy.types.freestylelinestyle.color*", "render/freestyle/view_layer/line_style/color.html#bpy-types-freestylelinestyle-color"), - ("bpy.types.functionnodecombinecolor*", "modeling/geometry_nodes/utilities/color/combine_color.html#bpy-types-functionnodecombinecolor"), + ("bpy.types.functionnodecombinecolor*", "editors/texture_node/types/color/combine_color.html#bpy-types-functionnodecombinecolor"), ("bpy.types.functionnodestringlength*", "modeling/geometry_nodes/utilities/text/string_length.html#bpy-types-functionnodestringlength"), ("bpy.types.geometrynodecurveofpoint*", "modeling/geometry_nodes/curve/topology/curve_of_point.html#bpy-types-geometrynodecurveofpoint"), ("bpy.types.geometrynodefaceofcorner*", "modeling/geometry_nodes/mesh/topology/face_of_corner.html#bpy-types-geometrynodefaceofcorner"), @@ -1560,6 +1599,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodemeshtopoints*", "modeling/geometry_nodes/mesh/operations/mesh_to_points.html#bpy-types-geometrynodemeshtopoints"), ("bpy.types.geometrynodemeshtovolume*", "modeling/geometry_nodes/mesh/operations/mesh_to_volume.html#bpy-types-geometrynodemeshtovolume"), ("bpy.types.geometrynodemeshuvsphere*", "modeling/geometry_nodes/mesh/primitives/uv_sphere.html#bpy-types-geometrynodemeshuvsphere"), + ("bpy.types.geometrynoderepeatoutput*", "modeling/geometry_nodes/utilities/repeat_zone.html#bpy-types-geometrynoderepeatoutput"), ("bpy.types.geometrynodereversecurve*", "modeling/geometry_nodes/curve/operations/reverse_curve.html#bpy-types-geometrynodereversecurve"), ("bpy.types.geometrynodesetcurvetilt*", "modeling/geometry_nodes/curve/write/set_curve_tilt.html#bpy-types-geometrynodesetcurvetilt"), ("bpy.types.geometrynodesplinelength*", "modeling/geometry_nodes/curve/read/spline_length.html#bpy-types-geometrynodesplinelength"), @@ -1571,6 +1611,8 @@ url_manual_mapping = ( ("bpy.types.image.use_half_precision*", "editors/image/image_settings.html#bpy-types-image-use-half-precision"), ("bpy.types.image.use_view_as_render*", "editors/image/image_settings.html#bpy-types-image-use-view-as-render"), ("bpy.types.imagepaint.interpolation*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-interpolation"), + ("bpy.types.imagetexture.filter_size*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-filter-size"), + ("bpy.types.imagetexture.filter_type*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-filter-type"), ("bpy.types.linestyle*modifier_noise*", "render/freestyle/view_layer/line_style/modifiers/color/noise.html#bpy-types-linestyle-modifier-noise"), ("bpy.types.maintainvolumeconstraint*", "animation/constraints/transform/maintain_volume.html#bpy-types-maintainvolumeconstraint"), ("bpy.types.material.alpha_threshold*", "render/eevee/materials/settings.html#bpy-types-material-alpha-threshold"), @@ -1641,6 +1683,7 @@ url_manual_mapping = ( ("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"), ("bpy.ops.render.play_rendered_anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"), ("bpy.ops.sculpt.set_pivot_position*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-set-pivot-position"), + ("bpy.ops.sculpt.trim_lasso_gesture*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-trim-lasso-gesture"), ("bpy.ops.sculpt_curves.select_grow*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-grow"), ("bpy.ops.sequencer.image_strip_add*", "video_editing/edit/montage/strips/image.html#bpy-ops-sequencer-image-strip-add"), ("bpy.ops.sequencer.images_separate*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-images-separate"), @@ -1700,6 +1743,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodeinputradius*", "modeling/geometry_nodes/geometry/read/radius.html#bpy-types-geometrynodeinputradius"), ("bpy.types.geometrynodemeshboolean*", "modeling/geometry_nodes/mesh/operations/mesh_boolean.html#bpy-types-geometrynodemeshboolean"), ("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/mesh/operations/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"), + ("bpy.types.geometrynoderepeatinput*", "modeling/geometry_nodes/utilities/repeat_zone.html#bpy-types-geometrynoderepeatinput"), ("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/sample/sample_curve.html#bpy-types-geometrynodesamplecurve"), ("bpy.types.geometrynodesampleindex*", "modeling/geometry_nodes/geometry/sample/sample_index.html#bpy-types-geometrynodesampleindex"), ("bpy.types.geometrynodesetmaterial*", "modeling/geometry_nodes/material/set_material.html#bpy-types-geometrynodesetmaterial"), @@ -1713,6 +1757,7 @@ url_manual_mapping = ( ("bpy.types.greasepencil.onion_mode*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-mode"), ("bpy.types.greasepencilgrid.offset*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-offset"), ("bpy.types.imagepaint.normal_angle*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-normal-angle"), + ("bpy.types.imagetexture.use_mipmap*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-use-mipmap"), ("bpy.types.laplaciandeformmodifier*", "modeling/modifiers/deform/laplacian_deform.html#bpy-types-laplaciandeformmodifier"), ("bpy.types.laplaciansmoothmodifier*", "modeling/modifiers/deform/laplacian_smooth.html#bpy-types-laplaciansmoothmodifier"), ("bpy.types.layercollection.exclude*", "editors/outliner/interface.html#bpy-types-layercollection-exclude"), @@ -1741,6 +1786,7 @@ url_manual_mapping = ( ("bpy.types.spaceview3d.lock_cursor*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock-cursor"), ("bpy.types.spaceview3d.lock_object*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock-object"), ("bpy.types.spaceview3d.show_viewer*", "modeling/geometry_nodes/output/viewer.html#bpy-types-spaceview3d-show-viewer"), + ("bpy.types.textcurve.use_fast_edit*", "modeling/texts/properties.html#bpy-types-textcurve-use-fast-edit"), ("bpy.types.texturenodecombinecolor*", "editors/texture_node/types/color/combine_color.html#bpy-types-texturenodecombinecolor"), ("bpy.types.texturenodetexdistnoise*", "editors/texture_node/types/textures/distorted_noise.html#bpy-types-texturenodetexdistnoise"), ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), @@ -1759,8 +1805,9 @@ url_manual_mapping = ( ("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"), ("bpy.ops.gpencil.vertex_color_hsv*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-hsv"), ("bpy.ops.gpencil.vertex_color_set*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-set"), - ("bpy.ops.graph.extrapolation_type*", "editors/graph_editor/channels.html#bpy-ops-graph-extrapolation-type"), + ("bpy.ops.graph.extrapolation_type*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-extrapolation-type"), ("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"), + ("bpy.ops.image.match_movie_length*", "editors/image/image_settings.html#bpy-ops-image-match-movie-length"), ("bpy.ops.mesh.customdata_skin_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-skin-add"), ("bpy.ops.mesh.dissolve_degenerate*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-dissolve-degenerate"), ("bpy.ops.mesh.face_split_by_edges*", "modeling/meshes/editing/face/weld_edges_faces.html#bpy-ops-mesh-face-split-by-edges"), @@ -1857,6 +1904,8 @@ url_manual_mapping = ( ("bpy.types.greasepencilgrid.scale*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-scale"), ("bpy.types.imagepaint.use_occlude*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-occlude"), ("bpy.types.imagesequence.use_flip*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-imagesequence-use-flip"), + ("bpy.types.imagetexture.extension*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-extension"), + ("bpy.types.imagetexture.use_alpha*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture-use-alpha"), ("bpy.types.keyframe.interpolation*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-interpolation"), ("bpy.types.latticegpencilmodifier*", "grease_pencil/modifiers/deform/lattice.html#bpy-types-latticegpencilmodifier"), ("bpy.types.lineartgpencilmodifier*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier"), @@ -1889,6 +1938,7 @@ url_manual_mapping = ( ("bpy.types.sound.use_memory_cache*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-memory-cache"), ("bpy.types.spaceview3d.clip_start*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-clip-start"), ("bpy.types.spaceview3d.show_gizmo*", "editors/3dview/display/gizmo.html#bpy-types-spaceview3d-show-gizmo"), + ("bpy.types.textcurve.follow_curve*", "modeling/texts/properties.html#bpy-types-textcurve-follow-curve"), ("bpy.types.texturegpencilmodifier*", "grease_pencil/modifiers/modify/texture_mapping.html#bpy-types-texturegpencilmodifier"), ("bpy.types.texturenodecoordinates*", "editors/texture_node/types/input/coordinates.html#bpy-types-texturenodecoordinates"), ("bpy.types.texturenodetexmusgrave*", "editors/texture_node/types/textures/musgrave.html#bpy-types-texturenodetexmusgrave"), @@ -1906,6 +1956,7 @@ url_manual_mapping = ( ("bpy.ops.armature.select_similar*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-similar"), ("bpy.ops.clip.create_plane_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-create-plane-track"), ("bpy.ops.curve.spline_weight_set*", "modeling/curves/editing/other.html#bpy-ops-curve-spline-weight-set"), + ("bpy.ops.file.external_operation*", "editors/file_browser.html#bpy-ops-file-external-operation"), ("bpy.ops.gpencil.blank_frame_add*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-blank-frame-add"), ("bpy.ops.gpencil.frame_duplicate*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-frame-duplicate"), ("bpy.ops.gpencil.layer_duplicate*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-layer-duplicate"), @@ -1940,7 +1991,6 @@ url_manual_mapping = ( ("bpy.ops.object.shape_key_remove*", "animation/shape_keys/shape_keys_panel.html#bpy-ops-object-shape-key-remove"), ("bpy.ops.object.shape_key_retime*", "animation/shape_keys/shape_keys_panel.html#bpy-ops-object-shape-key-retime"), ("bpy.ops.object.vertex_group_add*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-add"), - ("bpy.ops.object.vertex_group_fix*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-fix"), ("bpy.ops.outliner.collection_new*", "editors/outliner/editing.html#bpy-ops-outliner-collection-new"), ("bpy.ops.outliner.show_hierarchy*", "editors/outliner/editing.html#bpy-ops-outliner-show-hierarchy"), ("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"), @@ -1953,6 +2003,7 @@ url_manual_mapping = ( ("bpy.ops.scene.view_layer_remove*", "render/layers/introduction.html#bpy-ops-scene-view-layer-remove"), ("bpy.ops.screen.screen_full_area*", "interface/window_system/areas.html#bpy-ops-screen-screen-full-area"), ("bpy.ops.sculpt.face_sets_create*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-create"), + ("bpy.ops.sculpt.trim_box_gesture*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-trim-box-gesture"), ("bpy.ops.sequencer.select_linked*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-linked"), ("bpy.ops.transform.rotate_normal*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-transform-rotate-normal"), ("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/mesh/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"), @@ -1989,7 +2040,7 @@ url_manual_mapping = ( ("bpy.types.curves.surface_uv_map*", "modeling/curves/primitives.html#bpy-types-curves-surface-uv-map"), ("bpy.types.dampedtrackconstraint*", "animation/constraints/tracking/damped_track.html#bpy-types-dampedtrackconstraint"), ("bpy.types.distortednoisetexture*", "render/materials/legacy_textures/types/distorted_noise.html#bpy-types-distortednoisetexture"), - ("bpy.types.dopesheet.filter_text*", "editors/graph_editor/channels.html#bpy-types-dopesheet-filter-text"), + ("bpy.types.dopesheet.filter_text*", "editors/graph_editor/channels/introduction.html#bpy-types-dopesheet-filter-text"), ("bpy.types.editbone.bbone_easein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easein"), ("bpy.types.editbone.bbone_rollin*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollin"), ("bpy.types.fcurve.auto_smoothing*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-auto-smoothing"), @@ -2055,7 +2106,7 @@ url_manual_mapping = ( ("bpy.types.volumedisplay.density*", "modeling/volumes/properties.html#bpy-types-volumedisplay-density"), ("bpy.types.volumerender.clipping*", "modeling/volumes/properties.html#bpy-types-volumerender-clipping"), ("bpy.types.workspace.object_mode*", "interface/window_system/workspaces.html#bpy-types-workspace-object-mode"), - ("bpy.ops.anim.channels_collapse*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-collapse"), + ("bpy.ops.anim.channels_collapse*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-collapse"), ("bpy.ops.anim.driver_button_add*", "animation/drivers/usage.html#bpy-ops-anim-driver-button-add"), ("bpy.ops.armature.click_extrude*", "animation/armatures/bones/editing/extrude.html#bpy-ops-armature-click-extrude"), ("bpy.ops.armature.select_linked*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-linked"), @@ -2107,7 +2158,7 @@ url_manual_mapping = ( ("bpy.types.compositornodefilter*", "compositing/types/filter/filter_node.html#bpy-types-compositornodefilter"), ("bpy.types.compositornodehuesat*", "compositing/types/color/hue_saturation.html#bpy-types-compositornodehuesat"), ("bpy.types.compositornodeidmask*", "compositing/types/converter/id_mask.html#bpy-types-compositornodeidmask"), - ("bpy.types.compositornodeinvert*", "compositing/types/color/invert.html#bpy-types-compositornodeinvert"), + ("bpy.types.compositornodeinvert*", "compositing/types/color/invert_color.html#bpy-types-compositornodeinvert"), ("bpy.types.compositornodekeying*", "compositing/types/matte/keying.html#bpy-types-compositornodekeying"), ("bpy.types.compositornodelevels*", "compositing/types/output/levels.html#bpy-types-compositornodelevels"), ("bpy.types.compositornodemixrgb*", "compositing/types/color/mix.html#bpy-types-compositornodemixrgb"), @@ -2152,7 +2203,6 @@ url_manual_mapping = ( ("bpy.types.scene.background_set*", "scene_layout/scene/properties.html#bpy-types-scene-background-set"), ("bpy.types.sequence.frame_start*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-frame-start"), ("bpy.types.shadernodebackground*", "render/shader_nodes/shader/background.html#bpy-types-shadernodebackground"), - ("bpy.types.shadernodebsdfglossy*", "render/shader_nodes/shader/glossy.html#bpy-types-shadernodebsdfglossy"), ("bpy.types.shadernodebsdfvelvet*", "render/shader_nodes/shader/velvet.html#bpy-types-shadernodebsdfvelvet"), ("bpy.types.shadernodecameradata*", "render/shader_nodes/input/camera_data.html#bpy-types-shadernodecameradata"), ("bpy.types.shadernodecombinexyz*", "render/shader_nodes/converter/combine_xyz.html#bpy-types-shadernodecombinexyz"), @@ -2171,6 +2221,8 @@ url_manual_mapping = ( ("bpy.types.spaceview3d.clip_end*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-clip-end"), ("bpy.types.speedcontrolsequence*", "video_editing/edit/montage/strips/effects/speed_control.html#bpy-types-speedcontrolsequence"), ("bpy.types.spotlight.spot_blend*", "render/lights/light_object.html#bpy-types-spotlight-spot-blend"), + ("bpy.types.textcurve.space_line*", "modeling/texts/properties.html#bpy-types-textcurve-space-line"), + ("bpy.types.textcurve.space_word*", "modeling/texts/properties.html#bpy-types-textcurve-space-word"), ("bpy.types.texturenodecurvetime*", "editors/texture_node/types/input/time.html#bpy-types-texturenodecurvetime"), ("bpy.types.texturenodetexclouds*", "editors/texture_node/types/textures/clouds.html#bpy-types-texturenodetexclouds"), ("bpy.types.texturenodetexmarble*", "editors/texture_node/types/textures/marble.html#bpy-types-texturenodetexmarble"), @@ -2182,7 +2234,7 @@ url_manual_mapping = ( ("bpy.types.volume.sequence_mode*", "modeling/volumes/properties.html#bpy-types-volume-sequence-mode"), ("bpy.types.volumetomeshmodifier*", "modeling/modifiers/generate/volume_to_mesh.html#bpy-types-volumetomeshmodifier"), ("bpy.types.whitebalancemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-whitebalancemodifier"), - ("bpy.ops.anim.channels_ungroup*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-ungroup"), + ("bpy.ops.anim.channels_ungroup*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-ungroup"), ("bpy.ops.armature.extrude_move*", "animation/armatures/bones/editing/extrude.html#bpy-ops-armature-extrude-move"), ("bpy.ops.armature.parent_clear*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-clear"), ("bpy.ops.clip.clear_track_path*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clear-track-path"), @@ -2197,6 +2249,7 @@ url_manual_mapping = ( ("bpy.ops.gpencil.select_random*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-random"), ("bpy.ops.gpencil.stroke_sample*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-sample"), ("bpy.ops.gpencil.stroke_smooth*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-stroke-smooth"), + ("bpy.ops.graph.gaussian_smooth*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-gaussian-smooth"), ("bpy.ops.graph.keyframe_insert*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-keyframe-insert"), ("bpy.ops.image.read_viewlayers*", "editors/image/editing.html#bpy-ops-image-read-viewlayers"), ("bpy.ops.mask.add_vertex_slide*", "movie_clip/masking/editing.html#bpy-ops-mask-add-vertex-slide"), @@ -2270,6 +2323,8 @@ url_manual_mapping = ( ("bpy.types.curves.use_mirror_z*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-curves-use-mirror-z"), ("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"), ("bpy.types.dashgpencilmodifier*", "grease_pencil/modifiers/generate/dash.html#bpy-types-dashgpencilmodifier"), + ("bpy.types.drivervariable.name*", "animation/drivers/drivers_panel.html#bpy-types-drivervariable-name"), + ("bpy.types.drivervariable.type*", "animation/drivers/drivers_panel.html#bpy-types-drivervariable-type"), ("bpy.types.fieldsettings.noise*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-noise"), ("bpy.types.fieldsettings.shape*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-shape"), ("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"), @@ -2327,8 +2382,8 @@ url_manual_mapping = ( ("bpy.types.viewlayer.use_solid*", "render/layers/introduction.html#bpy-types-viewlayer-use-solid"), ("bpy.types.volume.frame_offset*", "modeling/volumes/properties.html#bpy-types-volume-frame-offset"), ("bpy.types.windowmanager.addon*", "editors/preferences/addons.html#bpy-types-windowmanager-addon"), - ("bpy.ops.anim.channels_delete*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-delete"), - ("bpy.ops.anim.channels_expand*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-expand"), + ("bpy.ops.anim.channels_delete*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-delete"), + ("bpy.ops.anim.channels_expand*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-expand"), ("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"), ("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"), ("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"), @@ -2460,6 +2515,9 @@ url_manual_mapping = ( ("bpy.types.shrinkwrapmodifier*", "modeling/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapmodifier"), ("bpy.types.spaceview3d.camera*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-camera"), ("bpy.types.splineikconstraint*", "animation/constraints/tracking/spline_ik.html#bpy-types-splineikconstraint"), + ("bpy.types.textcurve.offset_x*", "modeling/texts/properties.html#bpy-types-textcurve-offset-x"), + ("bpy.types.textcurve.offset_y*", "modeling/texts/properties.html#bpy-types-textcurve-offset-y"), + ("bpy.types.textcurve.overflow*", "modeling/texts/properties.html#bpy-types-textcurve-overflow"), ("bpy.types.texturenodechecker*", "editors/texture_node/types/patterns/checker.html#bpy-types-texturenodechecker"), ("bpy.types.texturenodergbtobw*", "editors/texture_node/types/converter/rgb_to_bw.html#bpy-types-texturenodergbtobw"), ("bpy.types.texturenodetexture*", "editors/texture_node/types/input/texture.html#bpy-types-texturenodetexture"), @@ -2469,7 +2527,7 @@ url_manual_mapping = ( ("bpy.types.volume.frame_start*", "modeling/volumes/properties.html#bpy-types-volume-frame-start"), ("bpy.types.volume.is_sequence*", "modeling/volumes/properties.html#bpy-types-volume-is-sequence"), ("bpy.types.volumerender.space*", "modeling/volumes/properties.html#bpy-types-volumerender-space"), - ("bpy.ops.anim.channels_group*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-group"), + ("bpy.ops.anim.channels_group*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-group"), ("bpy.ops.anim.keyframe_clear*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-clear"), ("bpy.ops.armature.flip_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-flip-names"), ("bpy.ops.armature.parent_set*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-set"), @@ -2495,7 +2553,7 @@ url_manual_mapping = ( ("bpy.ops.gpencil.stroke_join*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-join"), ("bpy.ops.gpencil.stroke_trim*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-trim"), ("bpy.ops.gpencil.trace_image*", "grease_pencil/modes/object/trace_image.html#bpy-ops-gpencil-trace-image"), - ("bpy.ops.graph.fmodifier_add*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-fmodifier-add"), + ("bpy.ops.graph.fmodifier_add*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-fmodifier-add"), ("bpy.ops.image.external_edit*", "editors/image/editing.html#bpy-ops-image-external-edit"), ("bpy.ops.mesh.colors_reverse*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-reverse"), ("bpy.ops.mesh.dissolve_edges*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-edges"), @@ -2537,6 +2595,7 @@ url_manual_mapping = ( ("bpy.ops.ui.eyedropper_color*", "interface/controls/templates/color_picker.html#bpy-ops-ui-eyedropper-color"), ("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"), ("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"), + ("bpy.ops.uv.select_edge_loop*", "editors/uv/selecting.html#bpy-ops-uv-select-edge-loop"), ("bpy.ops.uv.select_edge_ring*", "editors/uv/selecting.html#bpy-ops-uv-select-edge-ring"), ("bpy.ops.wm.save_as_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-as-mainfile"), ("bpy.types.action.use_cyclic*", "animation/actions.html#bpy-types-action-use-cyclic"), @@ -2554,6 +2613,7 @@ url_manual_mapping = ( ("bpy.types.compositornodergb*", "compositing/types/input/rgb.html#bpy-types-compositornodergb"), ("bpy.types.curve.bevel_depth*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-depth"), ("bpy.types.curve.use_stretch*", "modeling/curves/properties/shape.html#bpy-types-curve-use-stretch"), + ("bpy.types.driver.expression*", "animation/drivers/drivers_panel.html#bpy-types-driver-expression"), ("bpy.types.edgesplitmodifier*", "modeling/modifiers/generate/edge_split.html#bpy-types-edgesplitmodifier"), ("bpy.types.fcurve.color_mode*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-color-mode"), ("bpy.types.fluidflowsettings*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings"), @@ -2563,6 +2623,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodesetid*", "modeling/geometry_nodes/geometry/write/set_id.html#bpy-types-geometrynodesetid"), ("bpy.types.gpencillayer.hide*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-hide"), ("bpy.types.gpencillayer.lock*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-lock"), + ("bpy.types.image.seam_margin*", "editors/image/image_settings.html#bpy-types-image-seam-margin"), ("bpy.types.imagepaint.dither*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-dither"), ("bpy.types.material.metallic*", "render/materials/settings.html#bpy-types-material-metallic"), ("bpy.types.materialslot.link*", "render/materials/assignment.html#bpy-types-materialslot-link"), @@ -2593,13 +2654,16 @@ url_manual_mapping = ( ("bpy.types.shadernodetexwave*", "render/shader_nodes/textures/wave.html#bpy-types-shadernodetexwave"), ("bpy.types.soundsequence.pan*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-soundsequence-pan"), ("bpy.types.spline.use_smooth*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-smooth"), + ("bpy.types.textcurve.align_x*", "modeling/texts/properties.html#bpy-types-textcurve-align-x"), + ("bpy.types.textcurve.align_y*", "modeling/texts/properties.html#bpy-types-textcurve-align-y"), ("bpy.types.texturenodebricks*", "editors/texture_node/types/patterns/bricks.html#bpy-types-texturenodebricks"), - ("bpy.types.texturenodeinvert*", "editors/texture_node/types/color/invert.html#bpy-types-texturenodeinvert"), + ("bpy.types.texturenodeinvert*", "editors/texture_node/types/color/invert_color.html#bpy-types-texturenodeinvert"), ("bpy.types.texturenodemixrgb*", "editors/texture_node/types/color/mix_rgb.html#bpy-types-texturenodemixrgb"), ("bpy.types.texturenodeoutput*", "editors/texture_node/types/output/output.html#bpy-types-texturenodeoutput"), ("bpy.types.texturenoderotate*", "editors/texture_node/types/distort/rotate.html#bpy-types-texturenoderotate"), ("bpy.types.texturenodeviewer*", "editors/texture_node/types/output/viewer.html#bpy-types-texturenodeviewer"), ("bpy.types.textureslot.scale*", "sculpt_paint/brush/texture.html#bpy-types-textureslot-scale"), + ("bpy.types.themebonecolorset*", "animation/armatures/properties/bone_groups.html#bpy-types-themebonecolorset"), ("bpy.types.tracktoconstraint*", "animation/constraints/tracking/track_to.html#bpy-types-tracktoconstraint"), ("bpy.types.transformsequence*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence"), ("bpy.types.uvprojectmodifier*", "modeling/modifiers/modify/uv_project.html#bpy-types-uvprojectmodifier"), @@ -2607,7 +2671,7 @@ url_manual_mapping = ( ("bpy.types.viewlayer.use_sky*", "render/layers/introduction.html#bpy-types-viewlayer-use-sky"), ("bpy.types.wireframemodifier*", "modeling/modifiers/generate/wireframe.html#bpy-types-wireframemodifier"), ("bpy.types.worldmistsettings*", "render/cycles/world_settings.html#bpy-types-worldmistsettings"), - ("bpy.ops.anim.channels_move*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-move"), + ("bpy.ops.anim.channels_move*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-move"), ("bpy.ops.armature.subdivide*", "animation/armatures/bones/editing/subdivide.html#bpy-ops-armature-subdivide"), ("bpy.ops.asset.catalog_redo*", "editors/asset_browser.html#bpy-ops-asset-catalog-redo"), ("bpy.ops.asset.catalog_undo*", "editors/asset_browser.html#bpy-ops-asset-catalog-undo"), @@ -2620,7 +2684,7 @@ url_manual_mapping = ( ("bpy.ops.curve.extrude_move*", "modeling/curves/editing/control_points.html#bpy-ops-curve-extrude-move"), ("bpy.ops.curve.make_segment*", "modeling/curves/editing/control_points.html#bpy-ops-curve-make-segment"), ("bpy.ops.file.directory_new*", "editors/file_browser.html#bpy-ops-file-directory-new"), - ("bpy.ops.graph.euler_filter*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-euler-filter"), + ("bpy.ops.graph.euler_filter*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-euler-filter"), ("bpy.ops.marker.camera_bind*", "animation/markers.html#bpy-ops-marker-camera-bind"), ("bpy.ops.mask.cyclic_toggle*", "movie_clip/masking/editing.html#bpy-ops-mask-cyclic-toggle"), ("bpy.ops.mask.hide_view_set*", "movie_clip/masking/editing.html#bpy-ops-mask-hide-view-set"), @@ -2658,13 +2722,14 @@ url_manual_mapping = ( ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/editing/expand.html#bpy-ops-sculpt-mask-expand"), ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-filter"), + ("bpy.ops.sculpt.mesh_filter*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-mesh-filter"), ("bpy.ops.transform.tosphere*", "modeling/meshes/editing/mesh/transform/to_sphere.html#bpy-ops-transform-tosphere"), ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), ("bpy.ops.view3d.toggle_xray*", "modeling/meshes/selecting/introduction.html#bpy-ops-view3d-toggle-xray"), ("bpy.ops.view3d.view_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-camera"), ("bpy.ops.view3d.zoom_border*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-zoom-border"), ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), - ("bpy.ops.wm.properties_edit*", "files/data_blocks.html#bpy-ops-wm-properties-edit"), + ("bpy.ops.wm.properties_edit*", "files/custom_properties.html#bpy-ops-wm-properties-edit"), ("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"), ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), @@ -2713,7 +2778,7 @@ url_manual_mapping = ( ("bpy.types.sequencemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier"), ("bpy.types.shaderfxcolorize*", "grease_pencil/visual_effects/colorize.html#bpy-types-shaderfxcolorize"), ("bpy.types.shaderfxpixelate*", "grease_pencil/visual_effects/pixelate.html#bpy-types-shaderfxpixelate"), - ("bpy.types.shadernodeinvert*", "render/shader_nodes/color/invert.html#bpy-types-shadernodeinvert"), + ("bpy.types.shadernodeinvert*", "render/shader_nodes/color/invert_color.html#bpy-types-shadernodeinvert"), ("bpy.types.shadernodemixrgb*", "modeling/geometry_nodes/utilities/color/mix_rgb.html#bpy-types-shadernodemixrgb"), ("bpy.types.shadernodenormal*", "render/shader_nodes/vector/normal.html#bpy-types-shadernodenormal"), ("bpy.types.shadernodescript*", "render/shader_nodes/osl.html#bpy-types-shadernodescript"), @@ -2733,6 +2798,7 @@ url_manual_mapping = ( ("bpy.types.spotlight.energy*", "render/lights/light_object.html#bpy-types-spotlight-energy"), ("bpy.types.subtractsequence*", "video_editing/edit/montage/strips/effects/subtract.html#bpy-types-subtractsequence"), ("bpy.types.text.indentation*", "editors/text_editor.html#bpy-types-text-indentation"), + ("bpy.types.textcurve.family*", "modeling/texts/properties.html#bpy-types-textcurve-family"), ("bpy.types.texture.contrast*", "render/materials/legacy_textures/colors.html#bpy-types-texture-contrast"), ("bpy.types.texturenodegroup*", "editors/texture_node/types/groups.html#bpy-types-texturenodegroup"), ("bpy.types.texturenodeimage*", "editors/texture_node/types/input/image.html#bpy-types-texturenodeimage"), @@ -2805,6 +2871,7 @@ url_manual_mapping = ( ("bpy.types.constraint.name*", "animation/constraints/interface/header.html#bpy-types-constraint-name"), ("bpy.types.curve.eval_time*", "modeling/curves/properties/path_animation.html#bpy-types-curve-eval-time"), ("bpy.types.curve.fill_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-fill-mode"), + ("bpy.types.driver.use_self*", "animation/drivers/drivers_panel.html#bpy-types-driver-use-self"), ("bpy.types.editbone.layers*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-layers"), ("bpy.types.editbone.parent*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-parent"), ("bpy.types.explodemodifier*", "modeling/modifiers/physics/explode.html#bpy-types-explodemodifier"), @@ -2838,6 +2905,8 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor*", "editors/text_editor.html#bpy-types-spacetexteditor"), ("bpy.types.subsurfmodifier*", "modeling/modifiers/generate/subdivision_surface.html#bpy-types-subsurfmodifier"), ("bpy.types.sunlight.energy*", "render/lights/light_object.html#bpy-types-sunlight-energy"), + ("bpy.types.text.use_module*", "editors/text_editor.html#bpy-types-text-use-module"), + ("bpy.types.textcurve.shear*", "modeling/texts/properties.html#bpy-types-textcurve-shear"), ("bpy.types.texturenodemath*", "editors/texture_node/types/converter/math.html#bpy-types-texturenodemath"), ("bpy.types.volume.filepath*", "modeling/volumes/properties.html#bpy-types-volume-filepath"), ("bpy.ops.asset.tag_remove*", "editors/asset_browser.html#bpy-ops-asset-tag-remove"), @@ -2849,9 +2918,10 @@ url_manual_mapping = ( ("bpy.ops.fluid.bake_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-ops-fluid-bake-noise"), ("bpy.ops.fluid.free_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-ops-fluid-free-noise"), ("bpy.ops.font.move_select*", "modeling/texts/selecting.html#bpy-ops-font-move-select"), + ("bpy.ops.font.textbox_add*", "modeling/texts/properties.html#bpy-ops-font-textbox-add"), ("bpy.ops.gpencil.dissolve*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-dissolve"), ("bpy.ops.graph.frame_jump*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-frame-jump"), - ("bpy.ops.graph.sound_bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-sound-bake"), + ("bpy.ops.graph.sound_bake*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-sound-bake"), ("bpy.ops.marker.duplicate*", "animation/markers.html#bpy-ops-marker-duplicate"), ("bpy.ops.mask.select_less*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-less"), ("bpy.ops.mask.select_more*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-more"), @@ -2901,6 +2971,8 @@ url_manual_mapping = ( ("bpy.types.curves.surface*", "modeling/curves/primitives.html#bpy-types-curves-surface"), ("bpy.types.curvesmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-curvesmodifier"), ("bpy.types.ffmpegsettings*", "render/output/properties/output.html#bpy-types-ffmpegsettings"), + ("bpy.types.fmodifier.mute*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifier-mute"), + ("bpy.types.fmodifier.name*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifier-name"), ("bpy.types.fmodifiernoise*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiernoise"), ("bpy.types.image.filepath*", "editors/image/image_settings.html#bpy-types-image-filepath"), ("bpy.types.keyframe.co_ui*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-co-ui"), @@ -2926,6 +2998,7 @@ url_manual_mapping = ( ("bpy.types.sound.use_mono*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-mono"), ("bpy.types.spline.order_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-order-u"), ("bpy.types.sunlight.angle*", "render/lights/light_object.html#bpy-types-sunlight-angle"), + ("bpy.types.textcurve.size*", "modeling/texts/properties.html#bpy-types-textcurve-size"), ("bpy.types.timelinemarker*", "animation/markers.html#bpy-types-timelinemarker"), ("bpy.types.usersolidlight*", "editors/preferences/lights.html#bpy-types-usersolidlight"), ("bpy.types.uvwarpmodifier*", "modeling/modifiers/modify/uv_warp.html#bpy-types-uvwarpmodifier"), @@ -2966,7 +3039,6 @@ url_manual_mapping = ( ("bpy.ops.node.links_mute*", "interface/controls/nodes/editing.html#bpy-ops-node-links-mute"), ("bpy.ops.node.parent_set*", "interface/controls/nodes/frame.html#bpy-ops-node-parent-set"), ("bpy.ops.object.armature*", "animation/armatures/index.html#bpy-ops-object-armature"), - ("bpy.ops.object.face_map*", "modeling/meshes/properties/object_data.html#bpy-ops-object-face-map"), ("bpy.ops.object.join_uvs*", "scene_layout/object/editing/link_transfer/copy_uvmaps.html#bpy-ops-object-join-uvs"), ("bpy.ops.object.mode_set*", "editors/3dview/modes.html#bpy-ops-object-mode-set"), ("bpy.ops.outliner.delete*", "editors/outliner/editing.html#bpy-ops-outliner-delete"), @@ -2976,6 +3048,7 @@ url_manual_mapping = ( ("bpy.ops.rigidbody.world*", "physics/rigid_body/world.html#bpy-ops-rigidbody-world"), ("bpy.ops.sculpt.optimize*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-optimize"), ("bpy.ops.sequencer.split*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-split"), + ("bpy.ops.text.run_script*", "editors/text_editor.html#bpy-ops-text-run-script"), ("bpy.ops.transform.shear*", "modeling/meshes/editing/mesh/transform/shear.html#bpy-ops-transform-shear"), ("bpy.ops.uv.cube_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cube-project"), ("bpy.ops.uv.pack_islands*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pack-islands"), @@ -3038,6 +3111,7 @@ url_manual_mapping = ( ("bpy.types.spacetimeline*", "editors/timeline.html#bpy-types-spacetimeline"), ("bpy.types.spaceuveditor*", "editors/uv/index.html#bpy-types-spaceuveditor"), ("bpy.types.stuccitexture*", "render/materials/legacy_textures/types/stucci.html#bpy-types-stuccitexture"), + ("bpy.types.textbox.width*", "modeling/texts/properties.html#bpy-types-textbox-width"), ("bpy.types.texturenodeat*", "editors/texture_node/types/distort/at.html#bpy-types-texturenodeat"), ("bpy.types.view3doverlay*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay"), ("bpy.types.viewlayer.use*", "render/layers/view_layer.html#bpy-types-viewlayer-use"), @@ -3091,6 +3165,7 @@ url_manual_mapping = ( ("bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-jitter"), ("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"), ("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"), + ("bpy.types.drivertarget*", "animation/drivers/drivers_panel.html#bpy-types-drivertarget"), ("bpy.types.geometrynode*", "modeling/geometry_nodes/index.html#bpy-types-geometrynode"), ("bpy.types.glowsequence*", "video_editing/edit/montage/strips/effects/glow.html#bpy-types-glowsequence"), ("bpy.types.gpencillayer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer"), @@ -3159,7 +3234,9 @@ url_manual_mapping = ( ("bpy.ops.wm.debug_menu*", "advanced/operators.html#bpy-ops-wm-debug-menu"), ("bpy.ops.wm.obj_export*", "files/import_export/obj.html#bpy-ops-wm-obj-export"), ("bpy.ops.wm.obj_import*", "files/import_export/obj.html#bpy-ops-wm-obj-import"), - ("bpy.ops.wm.properties*", "files/data_blocks.html#bpy-ops-wm-properties"), + ("bpy.ops.wm.ply_export*", "files/import_export/ply.html#bpy-ops-wm-ply-export"), + ("bpy.ops.wm.ply_import*", "files/import_export/ply.html#bpy-ops-wm-ply-import"), + ("bpy.ops.wm.properties*", "files/custom_properties.html#bpy-ops-wm-properties"), ("bpy.ops.wm.stl_import*", "files/import_export/stl.html#bpy-ops-wm-stl-import"), ("bpy.ops.wm.usd_export*", "files/import_export/usd.html#bpy-ops-wm-usd-export"), ("bpy.types.addsequence*", "video_editing/edit/montage/strips/effects/add.html#bpy-types-addsequence"), @@ -3168,6 +3245,7 @@ url_manual_mapping = ( ("bpy.types.camera.show*", "render/cameras.html#bpy-types-camera-show"), ("bpy.types.consoleline*", "editors/python_console.html#bpy-types-consoleline"), ("bpy.types.curve.bevel*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel"), + ("bpy.types.driver.type*", "animation/drivers/drivers_panel.html#bpy-types-driver-type"), ("bpy.types.mesh.remesh*", "modeling/meshes/retopology.html#bpy-types-mesh-remesh"), ("bpy.types.meshstatvis*", "modeling/meshes/mesh_analysis.html#bpy-types-meshstatvis"), ("bpy.types.nodesetting*", "interface/controls/nodes/parts.html#bpy-types-nodesetting"), @@ -3195,10 +3273,10 @@ url_manual_mapping = ( ("bpy.ops.gpencil.copy*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-copy"), ("bpy.ops.graph.delete*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-delete"), ("bpy.ops.graph.mirror*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-mirror"), - ("bpy.ops.graph.reveal*", "editors/graph_editor/channels.html#bpy-ops-graph-reveal"), + ("bpy.ops.graph.reveal*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-reveal"), ("bpy.ops.graph.sample*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-sample"), ("bpy.ops.graph.smooth*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-smooth"), - ("bpy.ops.graph.unbake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-unbake"), + ("bpy.ops.graph.unbake*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-unbake"), ("bpy.ops.image.invert*", "editors/image/editing.html#bpy-ops-image-invert"), ("bpy.ops.image.reload*", "editors/image/editing.html#bpy-ops-image-reload"), ("bpy.ops.image.resize*", "editors/image/editing.html#bpy-ops-image-resize"), @@ -3208,12 +3286,13 @@ url_manual_mapping = ( ("bpy.ops.object.empty*", "modeling/empties.html#bpy-ops-object-empty"), ("bpy.ops.object.quick*", "physics/introduction.html#bpy-ops-object-quick"), ("bpy.ops.text.replace*", "editors/text_editor.html#bpy-ops-text-replace"), + ("bpy.ops.text.save_as*", "editors/text_editor.html#bpy-ops-text-save-as"), ("bpy.ops.uv.mark_seam*", "modeling/meshes/uv/unwrapping/seams.html#bpy-ops-uv-mark-seam"), ("bpy.ops.view3d.dolly*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-dolly"), ("bpy.ops.view3d.ruler*", "editors/3dview/toolbar/measure.html#bpy-ops-view3d-ruler"), ("bpy.types.areaspaces*", "interface/window_system/areas.html#bpy-types-areaspaces"), ("bpy.types.bonegroups*", "animation/armatures/properties/bone_groups.html#bpy-types-bonegroups"), - ("bpy.types.bpy_struct*", "files/data_blocks.html#bpy-types-bpy-struct"), + ("bpy.types.bpy_struct*", "files/custom_properties.html#bpy-types-bpy-struct"), ("bpy.types.brush.rate*", "sculpt_paint/brush/stroke.html#bpy-types-brush-rate"), ("bpy.types.brush.size*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-size"), ("bpy.types.collection*", "scene_layout/collections/collections.html#bpy-types-collection"), @@ -3239,7 +3318,9 @@ url_manual_mapping = ( ("bpy.ops.clip.reload*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-reload"), ("bpy.ops.curve.split*", "modeling/curves/editing/curve.html#bpy-ops-curve-split"), ("bpy.ops.file.cancel*", "editors/file_browser.html#bpy-ops-file-cancel"), + ("bpy.ops.file.delete*", "editors/file_browser.html#bpy-ops-file-delete"), ("bpy.ops.file.parent*", "editors/file_browser.html#bpy-ops-file-parent"), + ("bpy.ops.file.rename*", "editors/file_browser.html#bpy-ops-file-rename"), ("bpy.ops.graph.clean*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-clean"), ("bpy.ops.graph.paste*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-paste"), ("bpy.ops.marker.move*", "animation/markers.html#bpy-ops-marker-move"), @@ -3255,6 +3336,7 @@ url_manual_mapping = ( ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), ("bpy.ops.preferences*", "editors/preferences/index.html#bpy-ops-preferences"), ("bpy.ops.spreadsheet*", "editors/spreadsheet.html#bpy-ops-spreadsheet"), + ("bpy.ops.text.reload*", "editors/text_editor.html#bpy-ops-text-reload"), ("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"), ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), ("bpy.ops.view3d.walk*", "editors/3dview/navigate/walk_fly.html#bpy-ops-view3d-walk"), @@ -3274,6 +3356,8 @@ url_manual_mapping = ( ("bpy.types.nodegroup*", "interface/controls/nodes/groups.html#bpy-types-nodegroup"), ("bpy.types.scene.muv*", "addons/uv/magic_uv.html#bpy-types-scene-muv"), ("bpy.types.spotlight*", "render/lights/light_object.html#bpy-types-spotlight"), + ("bpy.types.textbox.x*", "modeling/texts/properties.html#bpy-types-textbox-x"), + ("bpy.types.textbox.y*", "modeling/texts/properties.html#bpy-types-textbox-y"), ("bpy.types.textcurve*", "modeling/texts/index.html#bpy-types-textcurve"), ("bpy.types.udimtiles*", "modeling/meshes/uv/workflows/udims.html#bpy-types-udimtiles"), ("bpy.types.uipiemenu*", "interface/controls/buttons/menus.html#bpy-types-uipiemenu"), @@ -3285,10 +3369,10 @@ url_manual_mapping = ( ("bpy.ops.curve.draw*", "modeling/curves/tools/draw.html#bpy-ops-curve-draw"), ("bpy.ops.curve.hide*", "modeling/curves/editing/curve.html#bpy-ops-curve-hide"), ("bpy.ops.curve.spin*", "modeling/surfaces/editing/surface.html#bpy-ops-curve-spin"), - ("bpy.ops.graph.bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-bake"), + ("bpy.ops.graph.bake*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-bake"), ("bpy.ops.graph.copy*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-copy"), ("bpy.ops.graph.ease*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-ease"), - ("bpy.ops.graph.hide*", "editors/graph_editor/channels.html#bpy-ops-graph-hide"), + ("bpy.ops.graph.hide*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-hide"), ("bpy.ops.graph.snap*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap"), ("bpy.ops.image.flip*", "editors/image/editing.html#bpy-ops-image-flip"), ("bpy.ops.image.open*", "editors/image/editing.html#bpy-ops-image-open"), @@ -3313,7 +3397,6 @@ url_manual_mapping = ( ("bpy.types.aov.type*", "render/layers/passes.html#bpy-types-aov-type"), ("bpy.types.armature*", "animation/armatures/index.html#bpy-types-armature"), ("bpy.types.editbone*", "animation/armatures/bones/editing/index.html#bpy-types-editbone"), - ("bpy.types.facemaps*", "modeling/meshes/properties/object_data.html#bpy-types-facemaps"), ("bpy.types.keyframe*", "animation/keyframes/index.html#bpy-types-keyframe"), ("bpy.types.linesets*", "render/freestyle/view_layer/line_set.html#bpy-types-linesets"), ("bpy.types.material*", "render/materials/index.html#bpy-types-material"), @@ -3343,6 +3426,8 @@ url_manual_mapping = ( ("bpy.ops.rigidbody*", "physics/rigid_body/index.html#bpy-ops-rigidbody"), ("bpy.ops.sequencer*", "video_editing/index.html#bpy-ops-sequencer"), ("bpy.ops.text.find*", "editors/text_editor.html#bpy-ops-text-find"), + ("bpy.ops.text.open*", "editors/text_editor.html#bpy-ops-text-open"), + ("bpy.ops.text.save*", "editors/text_editor.html#bpy-ops-text-save"), ("bpy.ops.transform*", "scene_layout/object/editing/transform/index.html#bpy-ops-transform"), ("bpy.ops.uv.reveal*", "modeling/meshes/uv/editing.html#bpy-ops-uv-reveal"), ("bpy.ops.uv.select*", "editors/uv/selecting.html#bpy-ops-uv-select"), @@ -3363,6 +3448,7 @@ url_manual_mapping = ( ("bpy.ops.nla.swap*", "editors/nla/editing.html#bpy-ops-nla-swap"), ("bpy.ops.outliner*", "editors/outliner/index.html#bpy-ops-outliner"), ("bpy.ops.particle*", "physics/particles/index.html#bpy-ops-particle"), + ("bpy.ops.text.new*", "editors/text_editor.html#bpy-ops-text-new"), ("bpy.ops.uv.align*", "modeling/meshes/uv/editing.html#bpy-ops-uv-align"), ("bpy.ops.uv.paste*", "modeling/meshes/uv/editing.html#bpy-ops-uv-paste"), ("bpy.ops.uv.reset*", "modeling/meshes/editing/uv.html#bpy-ops-uv-reset"), -- 2.30.2 From f6451304652ef56b0d015ba5ab83814933d7984d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 21 Jul 2023 15:03:18 +0200 Subject: [PATCH 8/8] Anim: Refactor the armature drawing code Introduces a strategy pattern for the implementation of the various armature drawing modes. Instead of having to `switch (arm->drawtype)` (or `if`/`else if`/`else` chains) everywhere, one function is used to select the appropriate `ArmatureBoneDrawStrategy` subclass. In the future this class could be expanded even further. Currently there are still places where there are explict checks for the draw type, making it cumbersome to add new types. For now I feel it's already a good enough move forward; future extensions can be done in later PRs. No functional changes. Pull Request: https://projects.blender.org/blender/blender/pulls/106232 --- .../draw/engines/overlay/overlay_armature.cc | 1144 ++++++++++------- 1 file changed, 660 insertions(+), 484 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 6b3dd2dea28..a928878af26 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -89,10 +89,72 @@ struct ArmatureDrawContext { bool do_relations; bool transparent; bool show_relations; + bool draw_relation_from_head; const ThemeWireColor *bcolor; /* pchan color */ }; +/** + * Bone drawing strategy class. + * + * Depending on the armature display mode, a different subclass is used to + * manage drawing. These subclasses are defined further down in the file. This + * abstract class needs to be defined before any function that uses it, though. + */ + +class ArmatureBoneDrawStrategy { + public: + virtual void update_display_matrix(EditBone *eBone, bPoseChannel *pchan) const = 0; + + /** + * Culling test. + * \return true when a part of this bPoseChannel is visible in the viewport. + */ + virtual bool culling_test(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) const = 0; + + virtual void draw_context_setup(ArmatureDrawContext *ctx, + OVERLAY_ArmatureCallBuffersInner *cb, + const bool is_filled, + const bool do_envelope_dist) const = 0; + + virtual void draw_bone(ArmatureDrawContext *ctx, + const EditBone *eBone, + const bPoseChannel *pchan, + const bArmature *arm, + const int boneflag, + const short constflag, + const int select_id) const = 0; + + /** Should the relationship line between this bone and its parent be drawn? */ + virtual bool should_draw_relation_to_parent(const EditBone *ebone, + const bPoseChannel *pchan, + const int boneflag) const + { + if (ebone && ebone->parent) { + /* Always draw for unconnected bones, regardless of selection, + * since riggers will want to know about the links between bones + */ + return (boneflag & BONE_CONNECTED) == 0; + } + + if (pchan && pchan->parent) { + /* Only draw between unconnected bones. */ + if (boneflag & BONE_CONNECTED) { + return false; + } + + /* Only draw if bone or its parent is selected - reduces viewport + * complexity with complex rigs */ + return (boneflag & BONE_SELECTED) || + (pchan->parent->bone && (pchan->parent->bone->flag & BONE_SELECTED)); + } + + return false; + } +}; + bool OVERLAY_armature_is_pose_mode(Object *ob, const DRWContextState *draw_ctx) { Object *active_ob = draw_ctx->obact; @@ -1379,6 +1441,7 @@ static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_B ebone->segments = BKE_pchan_bbone_spline_compute(¶m, false, (Mat4 *)result_array); } +/* This function is used for both B-Bone and Wire matrix updates. */ static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pchan) { float s[4][4], ebmat[4][4]; @@ -1447,33 +1510,6 @@ static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pc draw_bone_update_disp_matrix_default(eBone, pchan); } -static void draw_bone_update_disp_matrix_custom(bPoseChannel *pchan) -{ - float bone_scale[3]; - float(*bone_mat)[4]; - float(*disp_mat)[4]; - float(*disp_tail_mat)[4]; - float rot_mat[3][3]; - - /* See TODO: above. */ - mul_v3_v3fl(bone_scale, pchan->custom_scale_xyz, PCHAN_CUSTOM_BONE_LENGTH(pchan)); - bone_mat = pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat; - disp_mat = pchan->disp_mat; - disp_tail_mat = pchan->disp_tail_mat; - - eulO_to_mat3(rot_mat, pchan->custom_rotation_euler, ROT_MODE_XYZ); - - copy_m4_m4(disp_mat, bone_mat); - translate_m4(disp_mat, - pchan->custom_translation[0], - pchan->custom_translation[1], - pchan->custom_translation[2]); - mul_m4_m4m3(disp_mat, disp_mat, rot_mat); - rescale_m4(disp_mat, bone_scale); - copy_m4_m4(disp_tail_mat, disp_mat); - translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f); -} - static void draw_axes(ArmatureDrawContext *ctx, const EditBone *eBone, const bPoseChannel *pchan, @@ -1615,268 +1651,6 @@ static void draw_points(ArmatureDrawContext *ctx, /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Draw Bones - * \{ */ - -static void draw_bone_custom_shape(ArmatureDrawContext *ctx, - EditBone *eBone, - bPoseChannel *pchan, - bArmature *arm, - const int boneflag, - const short constflag, - const int select_id) -{ - const float *col_solid = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); - const float(*disp_mat)[4] = pchan->disp_mat; - - if (select_id != -1) { - DRW_select_load_id(select_id | BONESEL_BONE); - } - - if (pchan->custom->type == OB_EMPTY) { - Object *ob = pchan->custom; - if (ob->empty_drawtype != OB_EMPTY_IMAGE) { - drw_shgroup_bone_custom_empty(ctx, disp_mat, col_wire, pchan->custom); - } - } - if ((boneflag & BONE_DRAWWIRE) == 0 && (boneflag & BONE_DRAW_LOCKED_WEIGHT) == 0) { - drw_shgroup_bone_custom_solid(ctx, disp_mat, col_solid, col_hint, col_wire, pchan->custom); - } - else { - drw_shgroup_bone_custom_wire(ctx, disp_mat, col_wire, pchan->custom); - } - - if (select_id != -1) { - DRW_select_load_id(-1); - } -} - -static void draw_bone_envelope(ArmatureDrawContext *ctx, - EditBone *eBone, - bPoseChannel *pchan, - bArmature *arm, - const int boneflag, - const short constflag, - const int select_id) -{ - const float *col_solid = get_bone_solid_with_consts_color( - ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); - - float *rad_head, *rad_tail, *distance; - if (eBone) { - rad_tail = &eBone->rad_tail; - distance = &eBone->dist; - rad_head = (eBone->parent && (boneflag & BONE_CONNECTED)) ? &eBone->parent->rad_tail : - &eBone->rad_head; - } - else { - rad_tail = &pchan->bone->rad_tail; - distance = &pchan->bone->dist; - rad_head = (pchan->parent && (boneflag & BONE_CONNECTED)) ? &pchan->parent->bone->rad_tail : - &pchan->bone->rad_head; - } - - if ((select_id == -1) && (boneflag & BONE_NO_DEFORM) == 0 && - ((boneflag & BONE_SELECTED) || (eBone && (boneflag & (BONE_ROOTSEL | BONE_TIPSEL))))) - { - drw_shgroup_bone_envelope_distance( - ctx, BONE_VAR(eBone, pchan, disp_mat), rad_head, rad_tail, distance); - } - - if (select_id != -1) { - DRW_select_load_id(select_id | BONESEL_BONE); - } - - drw_shgroup_bone_envelope( - ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire, rad_head, rad_tail); - - if (select_id != -1) { - DRW_select_load_id(-1); - } - - draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); -} - -static void draw_bone_line(ArmatureDrawContext *ctx, - EditBone *eBone, - bPoseChannel *pchan, - bArmature *arm, - const int boneflag, - const short constflag, - const int select_id) -{ - const float *col_bone = get_bone_solid_with_consts_color( - ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); - const float no_display[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - const float *col_head = no_display; - const float *col_tail = col_bone; - - if (ctx->const_color != nullptr) { - col_wire = no_display; /* actually shrink the display. */ - col_bone = col_head = col_tail = ctx->const_color; - } - else { - if (eBone) { - if (eBone->flag & BONE_TIPSEL) { - col_tail = G_draw.block.color_vertex_select; - } - if (boneflag & BONE_SELECTED) { - col_bone = G_draw.block.color_bone_active; - } - col_wire = G_draw.block.color_wire; - } - - /* Draw root point if we are not connected to our parent. */ - if (!(eBone ? (eBone->parent && (boneflag & BONE_CONNECTED)) : - (pchan->bone->parent && (boneflag & BONE_CONNECTED)))) - { - - if (eBone) { - col_head = (eBone->flag & BONE_ROOTSEL) ? &G_draw.block.color_vertex_select.x : col_bone; - } - else { - col_head = col_bone; - } - } - } - - if (select_id == -1) { - /* Not in selection mode, draw everything at once. */ - drw_shgroup_bone_stick( - ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, col_head, col_tail); - } - else { - /* In selection mode, draw bone, root and tip separately. */ - DRW_select_load_id(select_id | BONESEL_BONE); - drw_shgroup_bone_stick( - ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, no_display, no_display); - - if (col_head[3] > 0.0f) { - DRW_select_load_id(select_id | BONESEL_ROOT); - drw_shgroup_bone_stick( - ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, col_head, no_display); - } - - DRW_select_load_id(select_id | BONESEL_TIP); - drw_shgroup_bone_stick( - ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, no_display, col_tail); - - DRW_select_load_id(-1); - } -} - -static void draw_bone_wire(ArmatureDrawContext *ctx, - EditBone *eBone, - bPoseChannel *pchan, - bArmature *arm, - const int boneflag, - const short constflag, - const int select_id) -{ - const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); - - if (select_id != -1) { - DRW_select_load_id(select_id | BONESEL_BONE); - } - - if (pchan) { - Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix; - BLI_assert(bbones_mat != nullptr); - - for (int i = pchan->bone->segments; i--; bbones_mat++) { - drw_shgroup_bone_wire(ctx, bbones_mat->mat, col_wire); - } - } - else if (eBone) { - for (int i = 0; i < eBone->segments; i++) { - drw_shgroup_bone_wire(ctx, eBone->disp_bbone_mat[i], col_wire); - } - } - - if (select_id != -1) { - DRW_select_load_id(-1); - } - - if (eBone) { - draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); - } -} - -static void draw_bone_box(ArmatureDrawContext *ctx, - EditBone *eBone, - bPoseChannel *pchan, - bArmature *arm, - const int boneflag, - const short constflag, - const int select_id) -{ - const float *col_solid = get_bone_solid_with_consts_color( - ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); - - if (select_id != -1) { - DRW_select_load_id(select_id | BONESEL_BONE); - } - - if (pchan) { - Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix; - BLI_assert(bbones_mat != nullptr); - - for (int i = pchan->bone->segments; i--; bbones_mat++) { - drw_shgroup_bone_box(ctx, bbones_mat->mat, col_solid, col_hint, col_wire); - } - } - else if (eBone) { - for (int i = 0; i < eBone->segments; i++) { - drw_shgroup_bone_box(ctx, eBone->disp_bbone_mat[i], col_solid, col_hint, col_wire); - } - } - - if (select_id != -1) { - DRW_select_load_id(-1); - } - - if (eBone) { - draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); - } -} - -static void draw_bone_octahedral(ArmatureDrawContext *ctx, - EditBone *eBone, - bPoseChannel *pchan, - bArmature *arm, - const int boneflag, - const short constflag, - const int select_id) -{ - const float *col_solid = get_bone_solid_with_consts_color( - ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); - const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); - - if (select_id != -1) { - DRW_select_load_id(select_id | BONESEL_BONE); - } - - drw_shgroup_bone_octahedral( - ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire); - - if (select_id != -1) { - DRW_select_load_id(-1); - } - - draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); -} - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Draw Degrees of Freedom * \{ */ @@ -2029,10 +1803,9 @@ static void pchan_draw_ik_lines(ArmatureDrawContext *ctx, static void draw_bone_bone_relationship_line(ArmatureDrawContext *ctx, const float bone_head[3], const float parent_head[3], - const float parent_tail[3], - const eArmature_Flag armature_flags) + const float parent_tail[3]) { - if (armature_flags & ARM_DRAW_RELATION_FROM_HEAD) { + if (ctx->draw_relation_from_head) { drw_shgroup_bone_relationship_lines(ctx, bone_head, parent_head); } else { @@ -2041,6 +1814,7 @@ static void draw_bone_bone_relationship_line(ArmatureDrawContext *ctx, } static void draw_bone_relations(ArmatureDrawContext *ctx, + const ArmatureBoneDrawStrategy &draw_strategy, EditBone *ebone, bPoseChannel *pchan, bArmature *arm, @@ -2048,31 +1822,16 @@ static void draw_bone_relations(ArmatureDrawContext *ctx, const short constflag) { if (ebone && ebone->parent) { - if (ctx->do_relations) { - /* Always draw for unconnected bones, regardless of selection, - * since riggers will want to know about the links between bones - */ - if ((boneflag & BONE_CONNECTED) == 0) { - draw_bone_bone_relationship_line( - ctx, ebone->head, ebone->parent->head, ebone->parent->tail, eArmature_Flag(arm->flag)); - } + if (ctx->do_relations && draw_strategy.should_draw_relation_to_parent(ebone, pchan, boneflag)) + { + draw_bone_bone_relationship_line(ctx, ebone->head, ebone->parent->head, ebone->parent->tail); } } else if (pchan && pchan->parent) { - if (ctx->do_relations) { - /* Only draw if bone or its parent is selected - reduces viewport complexity with complex - * rigs */ - if ((boneflag & BONE_SELECTED) || - (pchan->parent->bone && (pchan->parent->bone->flag & BONE_SELECTED))) - { - if ((boneflag & BONE_CONNECTED) == 0) { - draw_bone_bone_relationship_line(ctx, - pchan->pose_head, - pchan->parent->pose_head, - pchan->parent->pose_tail, - eArmature_Flag(arm->flag)); - } - } + if (ctx->do_relations && draw_strategy.should_draw_relation_to_parent(ebone, pchan, boneflag)) + { + draw_bone_bone_relationship_line( + ctx, pchan->pose_head, pchan->parent->pose_head, pchan->parent->pose_tail); } /* Draw a line to IK root bone if bone is selected. */ @@ -2165,79 +1924,549 @@ static bool pchan_culling_test_with_radius_scale(const DRWView *view, return DRW_culling_sphere_test(view, &bsphere); } -static bool pchan_culling_test_custom(const DRWView *view, - const Object *ob, - const bPoseChannel *pchan) -{ - /* For more aggressive culling the bounding box of the custom-object could be used. */ - return pchan_culling_test_simple(view, ob, pchan); -} +/** \} */ -static bool pchan_culling_test_wire(const DRWView *view, - const Object *ob, - const bPoseChannel *pchan) -{ - BLI_assert(((const bArmature *)ob->data)->drawtype == ARM_WIRE); - return pchan_culling_test_simple(view, ob, pchan); -} +/* -------------------------------------------------------------------- */ +/** \name Bone Drawing Strategies + * + * Bone drawing uses a strategy pattern for the different armature drawing modes. + * + * \{ */ -static bool pchan_culling_test_line(const DRWView *view, - const Object *ob, - const bPoseChannel *pchan) -{ - BLI_assert(((const bArmature *)ob->data)->drawtype == ARM_LINE); - /* Account for the end-points, as the line end-points size is in pixels, this is a rough value. - * Since the end-points are small the difference between having any margin or not is unlikely - * to be noticeable. */ - const float scale = 1.1f; - return pchan_culling_test_with_radius_scale(view, ob, pchan, scale); -} +/** Bone drawing strategy for unknown draw types. + * This doesn't do anything, except call the default matrix update function. + */ +class ArmatureBoneDrawStrategyEmpty : public ArmatureBoneDrawStrategy { + public: + void update_display_matrix(EditBone *eBone, bPoseChannel *pchan) const override + { + draw_bone_update_disp_matrix_default(eBone, pchan); + } -static bool pchan_culling_test_envelope(const DRWView *view, - const Object *ob, - const bPoseChannel *pchan) -{ - const bArmature *arm = static_cast(ob->data); - BLI_assert(arm->drawtype == ARM_ENVELOPE); - UNUSED_VARS_NDEBUG(arm); - BoundSphere bsphere; - pchan_culling_calc_bsphere(ob, pchan, &bsphere); - bsphere.radius += max_ff(pchan->bone->rad_head, pchan->bone->rad_tail) * - mat4_to_size_max_axis(ob->object_to_world) * - mat4_to_size_max_axis(pchan->disp_mat); - return DRW_culling_sphere_test(view, &bsphere); -} + bool culling_test(const DRWView * /*view*/, + const Object * /*ob*/, + const bPoseChannel * /*pchan*/) const override + { + return false; + } -static bool pchan_culling_test_bbone(const DRWView *view, - const Object *ob, - const bPoseChannel *pchan) -{ - const bArmature *arm = static_cast(ob->data); - BLI_assert(arm->drawtype == ARM_B_BONE); - UNUSED_VARS_NDEBUG(arm); - const float ob_scale = mat4_to_size_max_axis(ob->object_to_world); - const Mat4 *bbones_mat = (const Mat4 *)pchan->draw_data->bbone_matrix; - for (int i = pchan->bone->segments; i--; bbones_mat++) { - BoundSphere bsphere; - float size[3]; - mat4_to_size(size, bbones_mat->mat); - mul_v3_m4v3(bsphere.center, ob->object_to_world, bbones_mat->mat[3]); - bsphere.radius = len_v3(size) * ob_scale; - if (DRW_culling_sphere_test(view, &bsphere)) { - return true; + void draw_context_setup(ArmatureDrawContext * /*ctx*/, + OVERLAY_ArmatureCallBuffersInner * /*cb*/, + const bool /*is_filled*/, + const bool /*do_envelope_dist*/) const override + { + } + + void draw_bone(ArmatureDrawContext * /*ctx*/, + const EditBone * /*eBone*/, + const bPoseChannel * /*pchan*/, + const bArmature * /*arm*/, + const int /*boneflag*/, + const short /*constflag*/, + const int /*select_id*/) const override + { + } +}; + +/** Bone drawing strategy for custom bone shapes. */ +class ArmatureBoneDrawStrategyCustomShape : public ArmatureBoneDrawStrategy { + public: + void update_display_matrix(EditBone * /*eBone*/, bPoseChannel *pchan) const override + { + float bone_scale[3]; + float(*bone_mat)[4]; + float(*disp_mat)[4]; + float(*disp_tail_mat)[4]; + float rot_mat[3][3]; + + /* TODO: This should be moved to depsgraph or armature refresh + * and not be tight to the draw pass creation. + * This would refresh armature without invalidating the draw cache. */ + mul_v3_v3fl(bone_scale, pchan->custom_scale_xyz, PCHAN_CUSTOM_BONE_LENGTH(pchan)); + bone_mat = pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat; + disp_mat = pchan->disp_mat; + disp_tail_mat = pchan->disp_tail_mat; + + eulO_to_mat3(rot_mat, pchan->custom_rotation_euler, ROT_MODE_XYZ); + + copy_m4_m4(disp_mat, bone_mat); + translate_m4(disp_mat, + pchan->custom_translation[0], + pchan->custom_translation[1], + pchan->custom_translation[2]); + mul_m4_m4m3(disp_mat, disp_mat, rot_mat); + rescale_m4(disp_mat, bone_scale); + copy_m4_m4(disp_tail_mat, disp_mat); + translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f); + } + + bool culling_test(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) const override + { + /* For more aggressive culling the bounding box of the custom-object could be used. */ + return pchan_culling_test_simple(view, ob, pchan); + } + + void draw_context_setup(ArmatureDrawContext * /*ctx*/, + OVERLAY_ArmatureCallBuffersInner * /*cb*/, + const bool /*is_filled*/, + const bool /*do_envelope_dist*/) const override + { + } + + void draw_bone(ArmatureDrawContext *ctx, + const EditBone *eBone, + const bPoseChannel *pchan, + const bArmature *arm, + const int boneflag, + const short constflag, + const int select_id) const override + { + const float *col_solid = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); + const float(*disp_mat)[4] = pchan->disp_mat; + + if (select_id != -1) { + DRW_select_load_id(select_id | BONESEL_BONE); + } + + if (pchan->custom->type == OB_EMPTY) { + Object *ob = pchan->custom; + if (ob->empty_drawtype != OB_EMPTY_IMAGE) { + drw_shgroup_bone_custom_empty(ctx, disp_mat, col_wire, pchan->custom); + } + } + if ((boneflag & BONE_DRAWWIRE) == 0 && (boneflag & BONE_DRAW_LOCKED_WEIGHT) == 0) { + drw_shgroup_bone_custom_solid(ctx, disp_mat, col_solid, col_hint, col_wire, pchan->custom); + } + else { + drw_shgroup_bone_custom_wire(ctx, disp_mat, col_wire, pchan->custom); + } + + if (select_id != -1) { + DRW_select_load_id(-1); } } - return false; -} +}; -static bool pchan_culling_test_octohedral(const DRWView *view, - const Object *ob, - const bPoseChannel *pchan) +/** Bone drawing strategy for ARM_OCTA. */ +class ArmatureBoneDrawStrategyOcta : public ArmatureBoneDrawStrategy { + public: + void update_display_matrix(EditBone *eBone, bPoseChannel *pchan) const override + { + draw_bone_update_disp_matrix_default(eBone, pchan); + } + + bool culling_test(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) const override + { + /* No type assertion as this is a fallback (files from the future will end up here). */ + /* Account for spheres on the end-points. */ + const float scale = 1.2f; + return pchan_culling_test_with_radius_scale(view, ob, pchan, scale); + } + + void draw_context_setup(ArmatureDrawContext *ctx, + OVERLAY_ArmatureCallBuffersInner *cb, + const bool is_filled, + const bool /*do_envelope_dist*/) const override + { + ctx->outline = cb->octa_outline; + ctx->solid = (is_filled) ? cb->octa_fill : nullptr; + } + + void draw_bone(ArmatureDrawContext *ctx, + const EditBone *eBone, + const bPoseChannel *pchan, + const bArmature *arm, + const int boneflag, + const short constflag, + const int select_id) const override + { + const float *col_solid = get_bone_solid_with_consts_color( + ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); + + if (select_id != -1) { + DRW_select_load_id(select_id | BONESEL_BONE); + } + + drw_shgroup_bone_octahedral( + ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire); + + if (select_id != -1) { + DRW_select_load_id(-1); + } + + draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); + } +}; + +/** Bone drawing strategy for ARM_LINE. */ +class ArmatureBoneDrawStrategyLine : public ArmatureBoneDrawStrategy { + public: + void update_display_matrix(EditBone *eBone, bPoseChannel *pchan) const override + { + draw_bone_update_disp_matrix_default(eBone, pchan); + } + + bool culling_test(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) const override + { + /* Account for the end-points, as the line end-points size is in pixels, this is a rough + * value. Since the end-points are small the difference between having any margin or not is + * unlikely to be noticeable. */ + const float scale = 1.1f; + return pchan_culling_test_with_radius_scale(view, ob, pchan, scale); + } + + void draw_context_setup(ArmatureDrawContext *ctx, + OVERLAY_ArmatureCallBuffersInner *cb, + const bool /*is_filled*/, + const bool /*do_envelope_dist*/) const override + { + ctx->stick = cb->stick; + } + + void draw_bone(ArmatureDrawContext *ctx, + const EditBone *eBone, + const bPoseChannel *pchan, + const bArmature *arm, + const int boneflag, + const short constflag, + const int select_id) const override + { + const float *col_bone = get_bone_solid_with_consts_color( + ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); + const float no_display[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float *col_head = no_display; + const float *col_tail = col_bone; + + if (ctx->const_color != nullptr) { + col_wire = no_display; /* actually shrink the display. */ + col_bone = col_head = col_tail = ctx->const_color; + } + else { + if (eBone) { + if (eBone->flag & BONE_TIPSEL) { + col_tail = G_draw.block.color_vertex_select; + } + if (boneflag & BONE_SELECTED) { + col_bone = G_draw.block.color_bone_active; + } + col_wire = G_draw.block.color_wire; + } + + /* Draw root point if we are not connected to our parent. */ + if (!(eBone ? (eBone->parent && (boneflag & BONE_CONNECTED)) : + (pchan->bone->parent && (boneflag & BONE_CONNECTED)))) + { + + if (eBone) { + col_head = (eBone->flag & BONE_ROOTSEL) ? &G_draw.block.color_vertex_select.x : col_bone; + } + else { + col_head = col_bone; + } + } + } + + if (select_id == -1) { + /* Not in selection mode, draw everything at once. */ + drw_shgroup_bone_stick( + ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, col_head, col_tail); + } + else { + /* In selection mode, draw bone, root and tip separately. */ + DRW_select_load_id(select_id | BONESEL_BONE); + drw_shgroup_bone_stick( + ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, no_display, no_display); + + if (col_head[3] > 0.0f) { + DRW_select_load_id(select_id | BONESEL_ROOT); + drw_shgroup_bone_stick( + ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, col_head, no_display); + } + + DRW_select_load_id(select_id | BONESEL_TIP); + drw_shgroup_bone_stick( + ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, no_display, col_tail); + + DRW_select_load_id(-1); + } + } +}; + +/** Bone drawing strategy for ARM_B_BONE. */ +class ArmatureBoneDrawStrategyBBone : public ArmatureBoneDrawStrategy { + public: + void update_display_matrix(EditBone *eBone, bPoseChannel *pchan) const override + { + draw_bone_update_disp_matrix_bbone(eBone, pchan); + } + + bool culling_test(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) const override + { + const bArmature *arm = static_cast(ob->data); + BLI_assert(arm->drawtype == ARM_B_BONE); + UNUSED_VARS_NDEBUG(arm); + const float ob_scale = mat4_to_size_max_axis(ob->object_to_world); + const Mat4 *bbones_mat = (const Mat4 *)pchan->draw_data->bbone_matrix; + for (int i = pchan->bone->segments; i--; bbones_mat++) { + BoundSphere bsphere; + float size[3]; + mat4_to_size(size, bbones_mat->mat); + mul_v3_m4v3(bsphere.center, ob->object_to_world, bbones_mat->mat[3]); + bsphere.radius = len_v3(size) * ob_scale; + if (DRW_culling_sphere_test(view, &bsphere)) { + return true; + } + } + return false; + } + + void draw_context_setup(ArmatureDrawContext *ctx, + OVERLAY_ArmatureCallBuffersInner *cb, + const bool is_filled, + const bool /*do_envelope_dist*/) const override + { + ctx->outline = cb->box_outline; + ctx->solid = (is_filled) ? cb->box_fill : nullptr; + } + + void draw_bone(ArmatureDrawContext *ctx, + const EditBone *eBone, + const bPoseChannel *pchan, + const bArmature *arm, + const int boneflag, + const short constflag, + const int select_id) const override + { + const float *col_solid = get_bone_solid_with_consts_color( + ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); + + if (select_id != -1) { + DRW_select_load_id(select_id | BONESEL_BONE); + } + + if (pchan) { + Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix; + BLI_assert(bbones_mat != nullptr); + + for (int i = pchan->bone->segments; i--; bbones_mat++) { + drw_shgroup_bone_box(ctx, bbones_mat->mat, col_solid, col_hint, col_wire); + } + } + else if (eBone) { + for (int i = 0; i < eBone->segments; i++) { + drw_shgroup_bone_box(ctx, eBone->disp_bbone_mat[i], col_solid, col_hint, col_wire); + } + } + + if (select_id != -1) { + DRW_select_load_id(-1); + } + + if (eBone) { + draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); + } + } +}; + +/** Bone drawing strategy for ARM_ENVELOPE. */ +class ArmatureBoneDrawStrategyEnvelope : public ArmatureBoneDrawStrategy { + public: + void update_display_matrix(EditBone *eBone, bPoseChannel *pchan) const override + { + draw_bone_update_disp_matrix_default(eBone, pchan); + } + + bool culling_test(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) const override + { + const bArmature *arm = static_cast(ob->data); + BLI_assert(arm->drawtype == ARM_ENVELOPE); + UNUSED_VARS_NDEBUG(arm); + BoundSphere bsphere; + pchan_culling_calc_bsphere(ob, pchan, &bsphere); + bsphere.radius += max_ff(pchan->bone->rad_head, pchan->bone->rad_tail) * + mat4_to_size_max_axis(ob->object_to_world) * + mat4_to_size_max_axis(pchan->disp_mat); + return DRW_culling_sphere_test(view, &bsphere); + } + + void draw_context_setup(ArmatureDrawContext *ctx, + OVERLAY_ArmatureCallBuffersInner *cb, + const bool is_filled, + const bool do_envelope_dist) const override + { + ctx->envelope_outline = cb->envelope_outline; + ctx->envelope_solid = (is_filled) ? cb->envelope_fill : nullptr; + ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : nullptr; + } + + void draw_bone(ArmatureDrawContext *ctx, + const EditBone *eBone, + const bPoseChannel *pchan, + const bArmature *arm, + const int boneflag, + const short constflag, + const int select_id) const override + { + const float *col_solid = get_bone_solid_with_consts_color( + ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); + const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag); + + const float *rad_head, *rad_tail, *distance; + if (eBone) { + rad_tail = &eBone->rad_tail; + distance = &eBone->dist; + rad_head = (eBone->parent && (boneflag & BONE_CONNECTED)) ? &eBone->parent->rad_tail : + &eBone->rad_head; + } + else { + rad_tail = &pchan->bone->rad_tail; + distance = &pchan->bone->dist; + rad_head = (pchan->parent && (boneflag & BONE_CONNECTED)) ? &pchan->parent->bone->rad_tail : + &pchan->bone->rad_head; + } + + if ((select_id == -1) && (boneflag & BONE_NO_DEFORM) == 0 && + ((boneflag & BONE_SELECTED) || (eBone && (boneflag & (BONE_ROOTSEL | BONE_TIPSEL))))) + { + drw_shgroup_bone_envelope_distance( + ctx, BONE_VAR(eBone, pchan, disp_mat), rad_head, rad_tail, distance); + } + + if (select_id != -1) { + DRW_select_load_id(select_id | BONESEL_BONE); + } + + drw_shgroup_bone_envelope( + ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire, rad_head, rad_tail); + + if (select_id != -1) { + DRW_select_load_id(-1); + } + + draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); + } +}; + +/** Bone drawing strategy for ARM_WIRE. */ +class ArmatureBoneDrawStrategyWire : public ArmatureBoneDrawStrategy { + public: + void update_display_matrix(EditBone *eBone, bPoseChannel *pchan) const override + { + draw_bone_update_disp_matrix_bbone(eBone, pchan); + } + + bool culling_test(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) const override + { + BLI_assert(((const bArmature *)ob->data)->drawtype == ARM_WIRE); + return pchan_culling_test_simple(view, ob, pchan); + } + + void draw_context_setup(ArmatureDrawContext *ctx, + OVERLAY_ArmatureCallBuffersInner *cb, + const bool /*is_filled*/, + const bool /*do_envelope_dist*/) const override + { + ctx->wire = cb->wire; + ctx->const_wire = 1.5f; + } + + void draw_bone(ArmatureDrawContext *ctx, + const EditBone *eBone, + const bPoseChannel *pchan, + const bArmature *arm, + const int boneflag, + const short constflag, + const int select_id) const override + { + const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); + + if (select_id != -1) { + DRW_select_load_id(select_id | BONESEL_BONE); + } + + if (pchan) { + Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix; + BLI_assert(bbones_mat != nullptr); + + for (int i = pchan->bone->segments; i--; bbones_mat++) { + drw_shgroup_bone_wire(ctx, bbones_mat->mat, col_wire); + } + } + else if (eBone) { + for (int i = 0; i < eBone->segments; i++) { + drw_shgroup_bone_wire(ctx, eBone->disp_bbone_mat[i], col_wire); + } + } + + if (select_id != -1) { + DRW_select_load_id(-1); + } + + if (eBone) { + draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id); + } + } +}; + +namespace { +/** Armature drawing strategies. + * + * Declared statically here because they cost almost no memory (no fields in any + * of the structs, so just the virtual function table), and this makes it very + * simple to just pass references to them around. + * + * See the functions below. + */ +static ArmatureBoneDrawStrategyOcta strat_octa; +static ArmatureBoneDrawStrategyLine strat_line; +static ArmatureBoneDrawStrategyBBone strat_b_bone; +static ArmatureBoneDrawStrategyEnvelope strat_envelope; +static ArmatureBoneDrawStrategyWire strat_wire; +static ArmatureBoneDrawStrategyEmpty strat_empty; +}; // namespace + +/** + * Return the armature bone drawing strategy for the given draw type. + * + * Note that this does not consider custom bone shapes, as those can be set per bone. + * For those occasions just instance a `ArmatureBoneDrawStrategyCustomShape` and use that. + */ +static ArmatureBoneDrawStrategy &strategy_for_armature_drawtype(const eArmature_Drawtype drawtype) { - /* No type assertion as this is a fallback (files from the future will end up here). */ - /* Account for spheres on the end-points. */ - const float scale = 1.2f; - return pchan_culling_test_with_radius_scale(view, ob, pchan, scale); + switch (drawtype) { + case ARM_OCTA: + return strat_octa; + case ARM_LINE: + return strat_line; + case ARM_B_BONE: + return strat_b_bone; + case ARM_ENVELOPE: + return strat_envelope; + case ARM_WIRE: + return strat_wire; + } + BLI_assert_unreachable(); + return strat_empty; } /** \} */ @@ -2263,6 +2492,10 @@ static void draw_armature_edit(ArmatureDrawContext *ctx) edbo_compute_bbone_child(arm); + /* Determine drawing strategy. */ + const ArmatureBoneDrawStrategy &draw_strat = strategy_for_armature_drawtype( + eArmature_Drawtype(arm->drawtype)); + for (eBone = static_cast(arm->edbo->first), index = ob_orig->runtime.select_id; eBone; eBone = eBone->next, index += 0x10000) @@ -2286,29 +2519,11 @@ static void draw_armature_edit(ArmatureDrawContext *ctx) boneflag &= ~BONE_DRAW_LOCKED_WEIGHT; if (!is_select) { - draw_bone_relations(ctx, eBone, nullptr, arm, boneflag, constflag); + draw_bone_relations(ctx, draw_strat, eBone, nullptr, arm, boneflag, constflag); } - if (arm->drawtype == ARM_ENVELOPE) { - draw_bone_update_disp_matrix_default(eBone, nullptr); - draw_bone_envelope(ctx, eBone, nullptr, arm, boneflag, constflag, select_id); - } - else if (arm->drawtype == ARM_LINE) { - draw_bone_update_disp_matrix_default(eBone, nullptr); - draw_bone_line(ctx, eBone, nullptr, arm, boneflag, constflag, select_id); - } - else if (arm->drawtype == ARM_WIRE) { - draw_bone_update_disp_matrix_bbone(eBone, nullptr); - draw_bone_wire(ctx, eBone, nullptr, arm, boneflag, constflag, select_id); - } - else if (arm->drawtype == ARM_B_BONE) { - draw_bone_update_disp_matrix_bbone(eBone, nullptr); - draw_bone_box(ctx, eBone, nullptr, arm, boneflag, constflag, select_id); - } - else { - draw_bone_update_disp_matrix_default(eBone, nullptr); - draw_bone_octahedral(ctx, eBone, nullptr, arm, boneflag, constflag, select_id); - } + draw_strat.update_display_matrix(eBone, nullptr); + draw_strat.draw_bone(ctx, eBone, nullptr, arm, boneflag, constflag, select_id); if (!is_select) { if (show_text && (arm->flag & ARM_DRAWNAMES)) { @@ -2375,8 +2590,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx) { draw_locked_weights = true; - for (pchan = static_cast(ob->pose->chanbase.first); pchan; pchan = pchan->next) - { + for (bPoseChannel *pchan : ListBaseWrapper(ob->pose->chanbase)) { pchan->bone->flag &= ~BONE_DRAW_LOCKED_WEIGHT; } @@ -2384,18 +2598,25 @@ static void draw_armature_pose(ArmatureDrawContext *ctx) const ListBase *defbase = BKE_object_defgroup_list(obact_orig); for (const bDeformGroup *dg : ConstListBaseWrapper(defbase)) { - if (dg->flag & DG_LOCK_WEIGHT) { - pchan = BKE_pose_channel_find_name(ob->pose, dg->name); - - if (pchan) { - pchan->bone->flag |= BONE_DRAW_LOCKED_WEIGHT; - } + if ((dg->flag & DG_LOCK_WEIGHT) == 0) { + continue; } + + pchan = BKE_pose_channel_find_name(ob->pose, dg->name); + if (!pchan) { + continue; + } + + pchan->bone->flag |= BONE_DRAW_LOCKED_WEIGHT; } } const DRWView *view = is_pose_select ? DRW_view_default_get() : nullptr; + const ArmatureBoneDrawStrategy &draw_strat_normal = strategy_for_armature_drawtype( + eArmature_Drawtype(arm->drawtype)); + const ArmatureBoneDrawStrategyCustomShape draw_strat_custom; + for (pchan = static_cast(ob->pose->chanbase.first); pchan; pchan = pchan->next, index += 0x10000) { @@ -2417,75 +2638,45 @@ static void draw_armature_pose(ArmatureDrawContext *ctx) set_pchan_colorset(ctx, ob, pchan); } - /* catch exception for bone with hidden parent */ int boneflag = bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { + if (bone->parent && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { + /* Avoid drawing connection line to hidden parent. */ boneflag &= ~BONE_CONNECTED; } - - /* set temporary flag for drawing bone as active, but only if selected */ if (bone == arm->act_bone) { + /* Draw bone as active, but only if selected. */ boneflag |= BONE_DRAW_ACTIVE; } - if (!draw_locked_weights) { boneflag &= ~BONE_DRAW_LOCKED_WEIGHT; } + const bool use_custom_shape = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM); + const ArmatureBoneDrawStrategy &draw_strat = use_custom_shape ? draw_strat_custom : + draw_strat_normal; + if (!is_pose_select) { - draw_bone_relations(ctx, nullptr, pchan, arm, boneflag, constflag); + draw_bone_relations(ctx, draw_strat, nullptr, pchan, arm, boneflag, constflag); } - if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { - draw_bone_update_disp_matrix_custom(pchan); - if (!is_pose_select || pchan_culling_test_custom(view, ob, pchan)) { - draw_bone_custom_shape(ctx, nullptr, pchan, arm, boneflag, constflag, select_id); - } - } - else if (arm->drawtype == ARM_ENVELOPE) { - draw_bone_update_disp_matrix_default(nullptr, pchan); - if (!is_pose_select || pchan_culling_test_envelope(view, ob, pchan)) { - draw_bone_envelope(ctx, nullptr, pchan, arm, boneflag, constflag, select_id); - } - } - else if (arm->drawtype == ARM_LINE) { - draw_bone_update_disp_matrix_default(nullptr, pchan); - if (!is_pose_select || pchan_culling_test_line(view, ob, pchan)) { - draw_bone_line(ctx, nullptr, pchan, arm, boneflag, constflag, select_id); - } - } - else if (arm->drawtype == ARM_WIRE) { - draw_bone_update_disp_matrix_bbone(nullptr, pchan); - if (!is_pose_select || pchan_culling_test_wire(view, ob, pchan)) { - draw_bone_wire(ctx, nullptr, pchan, arm, boneflag, constflag, select_id); - } - } - else if (arm->drawtype == ARM_B_BONE) { - draw_bone_update_disp_matrix_bbone(nullptr, pchan); - if (!is_pose_select || pchan_culling_test_bbone(view, ob, pchan)) { - draw_bone_box(ctx, nullptr, pchan, arm, boneflag, constflag, select_id); - } - } - else if (arm->drawtype == ARM_OCTA) { - draw_bone_update_disp_matrix_default(nullptr, pchan); - if (!is_pose_select || pchan_culling_test_octohedral(view, ob, pchan)) { - draw_bone_octahedral(ctx, nullptr, pchan, arm, boneflag, constflag, select_id); - } + draw_strat.update_display_matrix(nullptr, pchan); + if (!is_pose_select || draw_strat.culling_test(view, ob, pchan)) { + draw_strat.draw_bone(ctx, nullptr, pchan, arm, boneflag, constflag, select_id); } - /* These aren't included in the selection. */ - if (!is_pose_select) { - if (draw_dofs) { - draw_bone_degrees_of_freedom(ctx, pchan); - } + /* Below this point nothing is used for selection queries. */ + if (is_pose_select) { + continue; + } - if (show_text && (arm->flag & ARM_DRAWNAMES)) { - draw_bone_name(ctx, nullptr, pchan, arm, boneflag); - } - - if (arm->flag & ARM_DRAWAXES) { - draw_axes(ctx, nullptr, pchan, arm); - } + if (draw_dofs) { + draw_bone_degrees_of_freedom(ctx, pchan); + } + if (show_text && (arm->flag & ARM_DRAWNAMES)) { + draw_bone_name(ctx, nullptr, pchan, arm, boneflag); + } + if (arm->flag & ARM_DRAWAXES) { + draw_axes(ctx, nullptr, pchan, arm); } } } @@ -2514,27 +2705,6 @@ static void armature_context_setup(ArmatureDrawContext *ctx, static const float select_const_color[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - switch (arm->drawtype) { - case ARM_ENVELOPE: - ctx->envelope_outline = cb->envelope_outline; - ctx->envelope_solid = (is_filled) ? cb->envelope_fill : nullptr; - ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : nullptr; - break; - case ARM_LINE: - ctx->stick = cb->stick; - break; - case ARM_WIRE: - ctx->wire = cb->wire; - break; - case ARM_B_BONE: - ctx->outline = cb->box_outline; - ctx->solid = (is_filled) ? cb->box_fill : nullptr; - break; - case ARM_OCTA: - ctx->outline = cb->octa_outline; - ctx->solid = (is_filled) ? cb->octa_fill : nullptr; - break; - } ctx->ob = ob; ctx->extras = &pd->extra_call_buffers[is_xray]; ctx->dof_lines = cb->dof_lines; @@ -2549,10 +2719,16 @@ static void armature_context_setup(ArmatureDrawContext *ctx, ctx->do_relations = !DRW_state_is_select() && pd->armature.show_relations && (is_edit_mode | is_pose_mode); ctx->const_color = DRW_state_is_select() ? select_const_color : const_color; - ctx->const_wire = ((((ob->base_flag & BASE_SELECTED) && (pd->v3d_flag & V3D_SELECT_OUTLINE)) || - (arm->drawtype == ARM_WIRE)) ? + ctx->const_wire = ((ob->base_flag & BASE_SELECTED) && (pd->v3d_flag & V3D_SELECT_OUTLINE) ? 1.5f : ((!is_filled || is_transparent) ? 1.0f : 0.0f)); + ctx->draw_relation_from_head = (arm->flag & ARM_DRAW_RELATION_FROM_HEAD); + + /* Call the draw strategy after setting the generic context properties, so + * that they can be overridden. */ + const eArmature_Drawtype drawtype = eArmature_Drawtype(arm->drawtype); + const ArmatureBoneDrawStrategy &draw_strat = strategy_for_armature_drawtype(drawtype); + draw_strat.draw_context_setup(ctx, cb, is_filled, do_envelope_dist); } void OVERLAY_edit_armature_cache_populate(OVERLAY_Data *vedata, Object *ob) -- 2.30.2