diff options
Diffstat (limited to 'release/scripts')
85 files changed, 6017 insertions, 2808 deletions
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index e212df17f60..a65ff15393a 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -373,11 +373,9 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # 2) Try register collected modules. # Removed register_module, addons need to handle their own registration now. - use_owner = mod.bl_info.get("use_owner", True) - if use_owner: - from _bpy import _bl_owner_id_get, _bl_owner_id_set - owner_id_prev = _bl_owner_id_get() - _bl_owner_id_set(module_name) + from _bpy import _bl_owner_id_get, _bl_owner_id_set + owner_id_prev = _bl_owner_id_get() + _bl_owner_id_set(module_name) # 3) Try run the modules register function. try: @@ -393,8 +391,7 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non _addon_remove(module_name) return None finally: - if use_owner: - _bl_owner_id_set(owner_id_prev) + _bl_owner_id_set(owner_id_prev) # * OK loaded successfully! * mod.__addon_enabled__ = True @@ -499,6 +496,15 @@ def disable_all(): disable(mod_name) +def _blender_manual_url_prefix(): + if _bpy.app.version_cycle in {"rc", "release"}: + manual_version = "%d.%d" % _bpy.app.version[:2] + else: + manual_version = "dev" + + return f"https://docs.blender.org/manual/en/{manual_version}" + + def module_bl_info(mod, info_basis=None): if info_basis is None: info_basis = { @@ -508,12 +514,11 @@ def module_bl_info(mod, info_basis=None): "blender": (), "location": "", "description": "", - "wiki_url": "", + "doc_url": "", "support": 'COMMUNITY', "category": "", "warning": "", "show_expanded": False, - "use_owner": True, } addon_info = getattr(mod, "bl_info", {}) @@ -531,9 +536,30 @@ def module_bl_info(mod, info_basis=None): if not addon_info["name"]: addon_info["name"] = mod.__name__ - # Temporary auto-magic, don't use_owner for import export menus. - if mod.bl_info["category"] == "Import-Export": - mod.bl_info["use_owner"] = False + # Replace 'wiki_url' with 'doc_url'. + doc_url = addon_info.pop("wiki_url", None) + if doc_url is not None: + # Unlikely, but possible that both are set. + if not addon_info["doc_url"]: + addon_info["doc_url"] = doc_url + if _bpy.app.debug: + print( + "Warning: add-on \"{addon_name}\": 'wiki_url' in 'bl_info' " + "is deprecated please use 'doc_url' instead!\n" + " {addon_path}".format( + addon_name=addon_info['name'], + addon_path=getattr(mod, "__file__", None), + ) + ) + + doc_url = addon_info["doc_url"] + if doc_url: + doc_url_prefix = "{BLENDER_MANUAL_URL}" + if doc_url_prefix in doc_url: + addon_info["doc_url"] = doc_url.replace( + doc_url_prefix, + _blender_manual_url_prefix(), + ) addon_info["_init"] = None return addon_info diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py index 2034b2ac55c..cee8f89abd3 100644 --- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py +++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py @@ -166,7 +166,8 @@ def print_info(reports, pot): spell_errors = check_ctxt.get("spell_errors") # XXX Temp, no multi_rnatip nor py_in_rna, see below. - keys = multi_lines | not_capitalized | end_point | undoc_ops | spell_errors.keys() + # Also, multi-lines tooltips are valid now. + keys = not_capitalized | end_point | undoc_ops | spell_errors.keys() if keys: _print("WARNINGS:") for key in keys: @@ -764,7 +765,7 @@ def dump_src_messages(msgs, reports, settings): } data = "" - with open(path) as f: + with open(path, encoding="utf8") as f: data = f.read() for srch in pygettexts: m = srch(data) @@ -797,7 +798,7 @@ def dump_src_messages(msgs, reports, settings): forbidden = set() forced = set() if os.path.isfile(settings.SRC_POTFILES): - with open(settings.SRC_POTFILES) as src: + with open(settings.SRC_POTFILES, encoding="utf8") as src: for l in src: if l[0] == '-': forbidden.add(l[1:].rstrip('\n')) diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index c81558db587..e522ec3fcf9 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -28,6 +28,7 @@ import json import os import sys +import types import bpy @@ -108,7 +109,7 @@ IMPORT_MIN_LEVEL = 0.0 # Languages in /branches we do not want to import in /trunk currently... IMPORT_LANGUAGES_SKIP = { - 'am_ET', 'bg_BG', 'fi_FI', 'el_GR', 'et_EE', 'ne_NP', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic', 'kk_KZ', + 'am_ET', 'bg_BG', 'fi_FI', 'el_GR', 'et_EE', 'ne_NP', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic', 'kk_KZ', 'es_ES', } # Languages that need RTL pre-processing. @@ -288,9 +289,14 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "along %s Y", "along %s Z", "along local Z", + "arccos(A)", + "arcsin(A)", + "arctan(A)", "ascii", "author", # Addons' field. :/ "bItasc", + "cos(A)", + "cosh(A)", "dbl-", # Compacted for 'double', for keymap items. "description", # Addons' field. :/ "dx", @@ -326,10 +332,15 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "re", "res", "rv", + "sin(A)", "sin(x) / x", + "sinh(A)", "sqrt(x*x+y*y+z*z)", "sRGB", + "tan(A)", + "tanh(A)", "utf-8", + "uv_on_emitter() requires a modifier from an evaluated object", "var", "vBVH", "view", @@ -346,6 +357,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "custom matrix", "custom orientation", "edge data", + "exp(A)", "expected a timeline/animation area to be active", "expected a view3d region", "expected a view3d region & editcurve", @@ -357,6 +369,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "image format is read-only", "image path can't be written to", "in memory to enable editing!", + "insufficient content", "jumps over", "left", "local", @@ -386,11 +399,15 @@ WARN_MSGID_END_POINT_ALLOWED = { "Circle|Alt .", "Float Neg. Exp.", "Max Ext.", + "Newer graphics drivers may be available to improve Blender support.", "Numpad .", "Pad.", " RNA Path: bpy.types.", "Temp. Diff.", "Temperature Diff.", + "The program will now close.", + "Your graphics card or driver has limited support. It may work, but with issues.", + "Your graphics card or driver is not supported.", } PARSER_CACHE_HASH = 'sha1' @@ -540,6 +557,10 @@ def _gen_get_set_path(ref, name): return _get, _set +def _check_valid_data(uid, val): + return not uid.startswith("_") and type(val) not in tuple(types.__dict__.values()) + (type,) + + class I18nSettings: """ Class allowing persistence of our settings! @@ -551,20 +572,32 @@ class I18nSettings: # Addon preferences are singleton by definition, so is this class! if not I18nSettings._settings: cls._settings = super(I18nSettings, cls).__new__(cls) - cls._settings.__dict__ = {uid: data for uid, data in globals().items() if not uid.startswith("_")} + cls._settings.__dict__ = {uid: val for uid, val in globals().items() if _check_valid_data(uid, val)} return I18nSettings._settings - def from_json(self, string): - data = dict(json.loads(string)) + def __getstate__(self): + return self.to_dict() + + def __setstate__(self, mapping): + return self.from_dict(mapping) + + def from_dict(self, mapping): # Special case... :/ - if "INTERN_PY_SYS_PATHS" in data: - self.PY_SYS_PATHS = data["INTERN_PY_SYS_PATHS"] - self.__dict__.update(data) + if "INTERN_PY_SYS_PATHS" in mapping: + self.PY_SYS_PATHS = mapping["INTERN_PY_SYS_PATHS"] + self.__dict__.update(mapping) + + def to_dict(self): + glob = globals() + return {uid: val for uid, val in self.__dict__.items() if _check_valid_data(uid, val) and uid in glob} + + def from_json(self, string): + self.from_dict(dict(json.loads(string))) def to_json(self): # Only save the diff from default i18n_settings! glob = globals() - export_dict = {uid: val for uid, val in self.__dict__.items() if glob.get(uid) != val} + export_dict = {uid: val for uid, val in self.__dict__.items() if _check_valid_data(uid, val) and glob.get(uid) != val} return json.dumps(export_dict) def load(self, fname, reset=False): @@ -575,7 +608,7 @@ class I18nSettings: # Assume it is already real JSon string... self.from_json(fname) return - with open(fname) as f: + with open(fname, encoding="utf8") as f: self.from_json(f.read()) # Else assume fname is already a file(like) object! else: @@ -583,7 +616,7 @@ class I18nSettings: def save(self, fname): if isinstance(fname, str): - with open(fname, 'w') as f: + with open(fname, 'w', encoding="utf8") as f: f.write(self.to_json()) # Else assume fname is already a file(like) object! else: diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index 7c22a86d687..61837cc0956 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -21,7 +21,6 @@ # Some misc utilities... import collections -import concurrent.futures import copy import hashlib import os @@ -238,6 +237,12 @@ class I18nMessage: self.is_fuzzy = is_fuzzy self.is_commented = is_commented + # ~ def __getstate__(self): + # ~ return {key: getattr(self, key) for key in self.__slots__} + + # ~ def __getstate__(self): + # ~ return {key: getattr(self, key) for key in self.__slots__} + def _get_msgctxt(self): return "".join(self.msgctxt_lines) @@ -426,6 +431,14 @@ class I18nMessages: self._reverse_cache = None + def __getstate__(self): + return (self.settings, self.uid, self.msgs, self.parsing_errors) + + def __setstate__(self, data): + self.__init__() + self.settings, self.uid, self.msgs, self.parsing_errors = data + self.update_info() + @staticmethod def _new_messages(): return getattr(collections, 'OrderedDict', dict)() @@ -566,24 +579,23 @@ class I18nMessages: # Next process new keys. if use_similar > 0.0: - with concurrent.futures.ProcessPoolExecutor() as exctr: - for key, msgid in exctr.map(get_best_similar, - tuple((nk, use_similar, tuple(similar_pool.keys())) for nk in new_keys)): - if msgid: - # Try to get the same context, else just get one... - skey = (key[0], msgid) - if skey not in similar_pool[msgid]: - skey = tuple(similar_pool[msgid])[0] - # We keep org translation and comments, and mark message as fuzzy. - msg, refmsg = self.msgs[skey].copy(), ref.msgs[key] - msg.msgctxt = refmsg.msgctxt - msg.msgid = refmsg.msgid - msg.sources = refmsg.sources - msg.is_fuzzy = True - msg.is_commented = refmsg.is_commented - msgs[key] = msg - else: - msgs[key] = ref.msgs[key] + for key, msgid in map(get_best_similar, + tuple((nk, use_similar, tuple(similar_pool.keys())) for nk in new_keys)): + if msgid: + # Try to get the same context, else just get one... + skey = (key[0], msgid) + if skey not in similar_pool[msgid]: + skey = tuple(similar_pool[msgid])[0] + # We keep org translation and comments, and mark message as fuzzy. + msg, refmsg = self.msgs[skey].copy(), ref.msgs[key] + msg.msgctxt = refmsg.msgctxt + msg.msgid = refmsg.msgid + msg.sources = refmsg.sources + msg.is_fuzzy = True + msg.is_commented = refmsg.is_commented + msgs[key] = msg + else: + msgs[key] = ref.msgs[key] else: for key in new_keys: msgs[key] = ref.msgs[key] @@ -1075,9 +1087,7 @@ class I18nMessages: "-o", fname, ) - print("Running ", " ".join(cmd)) ret = subprocess.call(cmd) - print("Finished.") return # XXX Code below is currently broken (generates corrupted mo files it seems :( )! # Using http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html notation. @@ -1158,7 +1168,7 @@ class I18n: print("WARNING: skipping file {}, too huge!".format(path)) return None, None, None, False txt = "" - with open(path) as f: + with open(path, encoding="utf8") as f: txt = f.read() _in = 0 _out = len(txt) @@ -1544,7 +1554,7 @@ class I18n: "", self.settings.PARSER_PY_MARKER_END, ] - with open(dst, 'w') as f: + with open(dst, 'w', encoding="utf8") as f: f.write((prev or "") + "\n".join(txt) + (nxt or "")) self.unescape() diff --git a/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py b/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py index 4f499476ad9..7c98faebe9d 100755 --- a/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py +++ b/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py @@ -93,7 +93,7 @@ def gen_menu_file(stats, settings): else: # Non-existing, commented entry! data_lines.append("# {} #{}:{}:{}".format(FLAG_MESSAGES[flag], uid_num, label, uid)) - with open(os.path.join(settings.TRUNK_MO_DIR, settings.LANGUAGES_FILE), 'w') as f: + with open(os.path.join(settings.TRUNK_MO_DIR, settings.LANGUAGES_FILE), 'w', encoding="utf8") as f: f.write("\n".join(data_lines)) - with open(os.path.join(settings.GIT_I18N_ROOT, settings.LANGUAGES_FILE), 'w') as f: + with open(os.path.join(settings.GIT_I18N_ROOT, settings.LANGUAGES_FILE), 'w', encoding="utf8") as f: f.write("\n".join(data_lines)) diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py index 3418b4af769..738554e8f2c 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -32,15 +32,18 @@ class SpellChecker: # These must be all lower case for comparisons uimsgs = { # OK words - "adaptively", + "adaptively", "adaptivity", "aren", # aren't "betweens", # yuck! in-betweens! "boolean", "booleans", + "chamfer", "couldn", # couldn't "decrement", "derivate", "deterministically", "doesn", # doesn't + "duplications", + "effector", "equi", # equi-angular, etc. "fader", "globbing", @@ -61,6 +64,7 @@ class SpellChecker: "pong", # ping pong "scalable", "shadeless", + "shouldn", # shouldn't "smoothen", "spacings", "teleport", "teleporting", @@ -75,6 +79,7 @@ class SpellChecker: "autoexecution", "autogenerated", "autolock", + "automasking", "autoname", "autopack", "autosave", @@ -105,7 +110,7 @@ class SpellChecker: "deadzone", "deconstruct", "defocus", - "denoise", "denoising", + "denoise", "denoised", "denoising", "denoiser", "deselect", "deselecting", "deselection", "despill", "despilling", "dirtree", @@ -211,7 +216,9 @@ class SpellChecker: "todo", "tradeoff", "un", + "unassociate", "unassociated", "unbake", + "unclosed", "uncomment", "unculled", "undeformed", @@ -230,10 +237,11 @@ class SpellChecker: "unreferenced", "unregister", "unselect", "unselected", "unselectable", - "unsubdivided", "unsubdivide", + "unsets", "unshadowed", "unspill", "unstitchable", + "unsubdivided", "unsubdivide", "untrusted", "vectorscope", "whitespace", "whitespaces", @@ -269,6 +277,7 @@ class SpellChecker: "scalings", "selectable", "selectability", "shaper", + "smoothen", "smoothening", "spherize", "spherized", "stitchable", "symmetrize", @@ -285,10 +294,13 @@ class SpellChecker: "aero", "amb", "anim", + "aov", "app", "bbox", "bboxes", + "bksp", # Backspace "bool", "calc", + "cfl", "config", "configs", "const", "coord", "coords", @@ -338,8 +350,12 @@ class SpellChecker: "subdiv", "sys", "tex", + "texcoord", "tmr", # timer "tri", "tris", + "udim", "udims", + "upres", # Upresolution + "usd", "uv", "uvs", "uvw", "uw", "uvmap", "ve", "vec", @@ -413,6 +429,7 @@ class SpellChecker: "vorticity", "waveform", "waveforms", "wildcard", "wildcards", + "wintab", # Some Windows tablet API # General computer graphics terms "anaglyph", @@ -437,6 +454,7 @@ class SpellChecker: "cuda", "deinterlace", "dropoff", + "duotone", "dv", "eigenvectors", "emissive", @@ -452,6 +470,7 @@ class SpellChecker: "linearlight", "lossless", "lossy", "luminance", + "mantaflow", "matcap", "midtones", "mipmap", "mipmaps", "mip", @@ -466,6 +485,7 @@ class SpellChecker: "raycasting", "raytrace", "raytracing", "raytraced", "refractions", + "remesher", "remeshing", "remesh", "renderfarm", "scanfill", "shader", "shaders", @@ -549,8 +569,9 @@ class SpellChecker: "shrinkwrap", "softbody", "stucci", - "sunsky", "subsurf", + "subtype", + "sunsky", "tessface", "tessfaces", "texface", "timeline", "timelines", @@ -574,6 +595,7 @@ class SpellChecker: # Algorithm/library names "ashikhmin", # Ashikhmin-Shirley + "arsloe", # Texel-Marsen-Arsloe "beckmann", "blackman", # Blackman-Harris "blosc", @@ -587,16 +609,21 @@ class SpellChecker: "hosek", "kutta", "lennard", + "marsen", # Texel-Marsen-Arsloe "mikktspace", "minkowski", "minnaert", + "moskowitz", # Pierson-Moskowitz "musgrave", "nayar", "netravali", "ogawa", "oren", + "peucker", # Ramer-Douglas-Peucker + "pierson", # Pierson-Moskowitz "preetham", "prewitt", + "ramer", # Ramer-Douglas-Peucker "runge", "sobol", "verlet", @@ -646,6 +673,7 @@ class SpellChecker: "ies", "ior", "itu", + "jonswap", "lhs", "lmb", "mmb", "rmb", "kb", @@ -667,10 +695,13 @@ class SpellChecker: "ssao", "ssr", "svn", + "tma", "ui", "unix", "vbo", "vbos", + "vr", "wxyz", + "xr", "ycc", "ycca", "yrgb", "yuv", "yuva", @@ -712,7 +743,7 @@ class SpellChecker: "gltf", "gzip", "ico", - "jpg", "jpeg", + "jpg", "jpeg", "jpegs", "json", "matroska", "mdd", @@ -724,7 +755,7 @@ class SpellChecker: "osl", "oso", "piz", - "png", + "png", "pngs", "po", "quicktime", "rle", diff --git a/release/scripts/modules/bl_keymap_utils/io.py b/release/scripts/modules/bl_keymap_utils/io.py index a93e86bc0a1..8cddbd37ea3 100644 --- a/release/scripts/modules/bl_keymap_utils/io.py +++ b/release/scripts/modules/bl_keymap_utils/io.py @@ -136,6 +136,9 @@ def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False): # First add all user_modified keymaps (found in keyconfigs.user.keymaps list), # then add all remaining keymaps from the currently active custom keyconfig. # + # Sort the resulting list according to top context name, + # while this isn't essential, it makes comparing keymaps simpler. + # # This will create a final list of keymaps that can be used as a "diff" against # the default blender keyconfig, recreating the current setup from a fresh blender # without needing to export keymaps which haven't been edited. @@ -152,6 +155,10 @@ def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False): else: export_keymaps = keyconfig_merge(edited_kc, edited_kc) + # Sort the keymap list by top context name before exporting, + # not essential, just convenient to order them predictably. + export_keymaps.sort(key=lambda k: k[0].name) + with open(filepath, "w") as fh: fw = fh.write fw("keyconfig_data = \\\n[") diff --git a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py index da4a47783ad..505223872fe 100644 --- a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py +++ b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py @@ -199,6 +199,9 @@ def generate(context, space_type, use_fallback_keys=True, use_reset=True): 'WEIGHT_PAINT': "weight_tool", 'TEXTURE_PAINT': "image_tool", 'PAINT_GPENCIL': "gpencil_tool", + 'VERTEX_GPENCIL': "gpencil_vertex_tool", + 'SCULPT_GPENCIL': "gpencil_sculpt_tool", + 'WEIGHT_GPENCIL': "gpencil_weight_tool", }.get(mode, None) if attr is not None: setattr(kmi_hack_brush_select_properties, attr, item.data_block) diff --git a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py index a98fa2c1fa8..3b829de405a 100644 --- a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py +++ b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py @@ -95,8 +95,8 @@ _km_hierarchy = [ ('Weight Paint', 'EMPTY', 'WINDOW', [ _km_expand_from_toolsystem('VIEW_3D', 'PAINT_WEIGHT'), ]), - ('Weight Paint Vertex Selection', 'EMPTY', 'WINDOW', []), - ('Face Mask', 'EMPTY', 'WINDOW', []), + ('Paint Vertex Selection (Weight, Vertex)', 'EMPTY', 'WINDOW', []), + ('Paint Face Mask (Weight, Vertex, Texture)', 'EMPTY', 'WINDOW', []), # image and view3d ('Image Paint', 'EMPTY', 'WINDOW', [ _km_expand_from_toolsystem('VIEW_3D', 'PAINT_TEXTURE'), @@ -194,9 +194,26 @@ _km_hierarchy = [ ('Grease Pencil Stroke Paint (Draw brush)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Paint (Fill)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Paint (Erase)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Paint (Tint)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Paint Mode', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Sculpt Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Smooth)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Thickness)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Strength)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Grab)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Push)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Twist)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Pinch)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Randomize)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Clone)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Weight Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Weight (Draw)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Draw)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Blur)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Average)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Smear)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Replace)', 'EMPTY', 'WINDOW', []), ]), ('Mask Editing', 'EMPTY', 'WINDOW', []), ('Frames', 'EMPTY', 'WINDOW', []), # frame navigation (per region) diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py index 8d1a782bc54..b79c0b744d0 100644 --- a/release/scripts/modules/bl_previews_utils/bl_previews_render.py +++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py @@ -31,7 +31,6 @@ from mathutils import ( ) -INTERN_PREVIEW_TYPES = {'MATERIAL', 'LIGHT', 'WORLD', 'TEXTURE', 'IMAGE'} OBJECT_TYPES_RENDER = {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'} @@ -315,7 +314,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern): do_save = True if do_data_intern: - bpy.ops.wm.previews_clear(id_type=INTERN_PREVIEW_TYPES) + bpy.ops.wm.previews_clear(id_type='SHADING') bpy.ops.wm.previews_ensure() render_contexts = {} @@ -440,7 +439,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern): def do_clear_previews(do_objects, do_collections, do_scenes, do_data_intern): if do_data_intern: - bpy.ops.wm.previews_clear(id_type=INTERN_PREVIEW_TYPES) + bpy.ops.wm.previews_clear(id_type='SHADING') if do_objects: for ob in ids_nolib(bpy.data.objects): diff --git a/release/scripts/modules/bl_ui_utils/bug_report_url.py b/release/scripts/modules/bl_ui_utils/bug_report_url.py index 008eafc2c46..2adee70bc86 100644 --- a/release/scripts/modules/bl_ui_utils/bug_report_url.py +++ b/release/scripts/modules/bl_ui_utils/bug_report_url.py @@ -57,7 +57,7 @@ def url_prefill_from_blender(addon_info=None): ) ) fh.write( - "Worked: (optional)\n" + "Worked: (newest version of Blender that worked as expected)\n" ) if addon_info: fh.write( diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index 3d36f3eb510..19450bb38ec 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -830,9 +830,13 @@ def register_tool(tool_cls, *, after=None, separator=False, group=False): context_descr = context_mode.replace("_", " ").title() from bpy import context wm = context.window_manager - kc = wm.keyconfigs.default + keyconfigs = wm.keyconfigs + kc_default = keyconfigs.default + # Note that Blender's default tools use the default key-config for both. + # We need to use the add-ons for 3rd party tools so reloading the key-map doesn't clear them. + kc = keyconfigs.addon if callable(keymap_data[0]): - cls._km_action_simple(kc, context_descr, tool_def.label, keymap_data) + cls._km_action_simple(kc_default, kc, context_descr, tool_def.label, keymap_data) return tool_def tool_converted = tool_from_class(tool_cls) @@ -955,12 +959,13 @@ def unregister_tool(tool_cls): if keymap_data is not None: from bpy import context wm = context.window_manager - kc = wm.keyconfigs.default - km = kc.keymaps.get(keymap_data[0]) - if km is None: - print("Warning keymap {keymap_data[0]!r} not found!") - else: - kc.keymaps.remove(km) + keyconfigs = wm.keyconfigs + for kc in (keyconfigs.default, keyconfigs.addon): + km = kc.keymaps.get(keymap_data[0]) + if km is None: + print(f"Warning keymap {keymap_data[0]!r} not found in {kc.name!r}!") + else: + kc.keymaps.remove(km) # ----------------------------------------------------------------------------- diff --git a/release/scripts/modules/bpy/utils/previews.py b/release/scripts/modules/bpy/utils/previews.py index a3baf8f878c..bfdf28e0db4 100644 --- a/release/scripts/modules/bpy/utils/previews.py +++ b/release/scripts/modules/bpy/utils/previews.py @@ -94,7 +94,7 @@ class ImagePreviewCollection(dict): def load(self, name, path, path_type, force_reload=False): if name in self: - raise KeyError("key {name!r} already exists") + raise KeyError(f"key {name!r} already exists") p = self[name] = _utils_previews.load( self._gen_key(name), path, path_type, force_reload) return p diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py index c67134ac3f6..7de919f489e 100644 --- a/release/scripts/modules/bpy_extras/anim_utils.py +++ b/release/scripts/modules/bpy_extras/anim_utils.py @@ -216,8 +216,6 @@ def bake_action_iter( pose_info = [] obj_info = [] - options = {'INSERTKEY_NEEDED'} - # ------------------------------------------------------------------------- # Collect transformations @@ -281,7 +279,7 @@ def bake_action_iter( for (f, matrix, bbones) in pose_info: pbone.matrix_basis = matrix[name].copy() - pbone.keyframe_insert("location", index=-1, frame=f, group=name, options=options) + pbone.keyframe_insert("location", index=-1, frame=f, group=name) rotation_mode = pbone.rotation_mode if rotation_mode == 'QUATERNION': @@ -293,9 +291,9 @@ def bake_action_iter( del quat else: quat_prev = pbone.rotation_quaternion.copy() - pbone.keyframe_insert("rotation_quaternion", index=-1, frame=f, group=name, options=options) + pbone.keyframe_insert("rotation_quaternion", index=-1, frame=f, group=name) elif rotation_mode == 'AXIS_ANGLE': - pbone.keyframe_insert("rotation_axis_angle", index=-1, frame=f, group=name, options=options) + pbone.keyframe_insert("rotation_axis_angle", index=-1, frame=f, group=name) else: # euler, XYZ, ZXY etc if euler_prev is not None: euler = pbone.rotation_euler.copy() @@ -305,9 +303,9 @@ def bake_action_iter( del euler else: euler_prev = pbone.rotation_euler.copy() - pbone.keyframe_insert("rotation_euler", index=-1, frame=f, group=name, options=options) + pbone.keyframe_insert("rotation_euler", index=-1, frame=f, group=name) - pbone.keyframe_insert("scale", index=-1, frame=f, group=name, options=options) + pbone.keyframe_insert("scale", index=-1, frame=f, group=name) # Bendy Bones if pbone.bone.bbone_segments > 1: @@ -315,7 +313,7 @@ def bake_action_iter( for bb_prop in BBONE_PROPS: # update this property with value from bbone_shape, then key it setattr(pbone, bb_prop, bbone_shape[bb_prop]) - pbone.keyframe_insert(bb_prop, index=-1, frame=f, group=name, options=options) + pbone.keyframe_insert(bb_prop, index=-1, frame=f, group=name) # object. TODO. multiple objects if do_object: @@ -331,7 +329,7 @@ def bake_action_iter( name = "Action Bake" # XXX: placeholder obj.matrix_basis = matrix - obj.keyframe_insert("location", index=-1, frame=f, group=name, options=options) + obj.keyframe_insert("location", index=-1, frame=f, group=name) rotation_mode = obj.rotation_mode if rotation_mode == 'QUATERNION': @@ -344,9 +342,9 @@ def bake_action_iter( print ("quat_prev", quat_prev) else: quat_prev = obj.rotation_quaternion.copy() - obj.keyframe_insert("rotation_quaternion", index=-1, frame=f, group=name, options=options) + obj.keyframe_insert("rotation_quaternion", index=-1, frame=f, group=name) elif rotation_mode == 'AXIS_ANGLE': - obj.keyframe_insert("rotation_axis_angle", index=-1, frame=f, group=name, options=options) + obj.keyframe_insert("rotation_axis_angle", index=-1, frame=f, group=name) else: # euler, XYZ, ZXY etc if euler_prev is not None: euler = obj.rotation_euler.copy() @@ -356,9 +354,9 @@ def bake_action_iter( del euler else: euler_prev = obj.rotation_euler.copy() - obj.keyframe_insert("rotation_euler", index=-1, frame=f, group=name, options=options) + obj.keyframe_insert("rotation_euler", index=-1, frame=f, group=name) - obj.keyframe_insert("scale", index=-1, frame=f, group=name, options=options) + obj.keyframe_insert("scale", index=-1, frame=f, group=name) if do_parents_clear: obj.parent = None diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index 8c009a77d3d..540bc75cece 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -161,7 +161,7 @@ def object_data_add(context, obdata, operator=None, name=None): bpy.ops.object.mode_set(mode='EDIT') else: layer.objects.active = obj_new - if context.preferences.edit.use_enter_edit_mode: + if obdata and context.preferences.edit.use_enter_edit_mode: bpy.ops.object.mode_set(mode='EDIT') return obj_new diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 43ee785438b..a30f9d1dd1d 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -29,6 +29,7 @@ bpy_types.BlendDataLibraries.load = _bpy._library_load bpy_types.BlendDataLibraries.write = _bpy._library_write bpy_types.BlendData.user_map = _bpy._rna_id_collection_user_map bpy_types.BlendData.batch_remove = _bpy._rna_id_collection_batch_remove +bpy_types.BlendData.orphans_purge = _bpy._rna_id_collection_orphans_purge class Context(StructRNA): @@ -783,7 +784,10 @@ class _GenericUI: for func in draw_ls._draw_funcs: # Begin 'owner_id' filter. - if owner_names is not None: + # Exclude Import/Export menus from this filtering (io addons should always show there) + if not getattr(self, "bl_owner_use_filter", True): + pass + elif owner_names is not None: owner_id = getattr(func, "_owner", None) if owner_id is not None: if func._owner not in owner_names: diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py index b8a9aa40a0b..844daded570 100644 --- a/release/scripts/modules/rna_keymap_ui.py +++ b/release/scripts/modules/rna_keymap_ui.py @@ -161,7 +161,12 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level): if (not kmi.is_user_defined) and kmi.is_user_modified: row.operator("preferences.keyitem_restore", text="", icon='BACK').item_id = kmi.id else: - row.operator("preferences.keyitem_remove", text="", icon='X').item_id = kmi.id + row.operator( + "preferences.keyitem_remove", + text="", + # Abusing the tracking icon, but it works pretty well here. + icon=('TRACKING_CLEAR_BACKWARDS' if kmi.is_user_defined else 'X') + ).item_id = kmi.id # Expanded, additional event settings if kmi.show_expanded: @@ -184,6 +189,9 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level): if map_type == 'KEYBOARD': subrow.prop(kmi, "type", text="", event=True) subrow.prop(kmi, "value", text="") + subrow_repeat = subrow.row(align=True) + subrow_repeat.active = kmi.value in {'ANY', 'PRESS'} + subrow_repeat.prop(kmi, "repeat", text="Repeat") elif map_type in {'MOUSE', 'NDOF'}: subrow.prop(kmi, "type", text="") subrow.prop(kmi, "value", text="") @@ -387,7 +395,7 @@ def draw_keymaps(context, layout): # layout.context_pointer_set("keyconfig", wm.keyconfigs.active) # row.operator("preferences.keyconfig_remove", text="", icon='X') - rowsub = row.split(factor=0.3, align=True) + rowsub = row.split(factor=0.4, align=True) # postpone drawing into rowsub, so we can set alert! layout.separator() @@ -402,7 +410,8 @@ def draw_keymaps(context, layout): ok = True # go back and fill in rowsub - rowsub.prop(spref, "filter_type", text="") + rowsubsub = rowsub.row(align=True) + rowsubsub.prop(spref, "filter_type", expand=True) rowsubsub = rowsub.row(align=True) if not ok: rowsubsub.alert = True diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 2e78f18b78e..b76f57c4545 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -9,64 +9,125 @@ else: url_manual_prefix = "https://docs.blender.org/manual/en/" + manual_version + "/" -language = "" -if bpy.context.preferences.view.use_international_fonts: - language = bpy.context.preferences.view.language - if language == 'DEFAULT': - import os - language = os.getenv('LANG', '').split('.')[0] +language = bpy.context.preferences.view.language +if language == 'DEFAULT': + import os + language = os.getenv('LANG', '').split('.')[0] LANG = { - "de_DE": "de", - "ru_RU": "ru", - "uk_UA": "uk", - "es": "es", - "fr_FR": "fr", - "it_IT": "it", - "ja_JP": "ja", - "ko_KR": "ko", - "pt_PT": "pt", - "pt_BR": "pt", - "vi_VN": "vi", - "zh_CN": "zh-hans", - "zh_TW": "zh-hant", +"de_DE": "de", +"ru_RU": "ru", +"uk_UA": "uk", +"es": "es", +"fr_FR": "fr", +"it_IT": "it", +"ja_JP": "ja", +"ko_KR": "ko", +"pt_PT": "pt", +"pt_BR": "pt", +"vi_VN": "vi", +"zh_CN": "zh-hans", +"zh_TW": "zh-hant", }.get(language) if LANG is not None: url_manual_prefix = url_manual_prefix.replace("manual/en", "manual/" + LANG) url_manual_mapping = ( + ("bpy.types.fluiddomainsettings.sndparticle_potential_max_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-trappedair"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_min_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-trappedair"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_max_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-wavecrest"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), + ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), + ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), + ("bpy.types.fluiddomainsettings.sndparticle_bubble_buoyancy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-buoyancy"), + ("bpy.types.fluiddomainsettings.sndparticle_combined_export*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-combined-export"), + ("bpy.types.fluiddomainsettings.use_collision_border_bottom*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-bottom"), + ("bpy.types.fluiddomainsettings.use_collision_border_front*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-front"), + ("bpy.types.fluiddomainsettings.use_collision_border_right*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-right"), ("bpy.types.cyclesobjectsettings.use_adaptive_subdivision*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-use-adaptive-subdivision"), + ("bpy.types.fluiddomainsettings.sndparticle_update_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-update-radius"), + ("bpy.types.fluiddomainsettings.use_collision_border_back*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-back"), + ("bpy.types.fluiddomainsettings.use_collision_border_left*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-left"), ("bpy.types.rendersettings_simplify_gpencil_view_modifier*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-modifier"), ("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"), + ("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"), ("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"), ("bpy.types.rendersettings_simplify_gpencil_remove_lines*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-remove-lines"), ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-pivot-point-align"), + ("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"), ("bpy.types.cyclesrendersettings.offscreen_dicing_scale*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-offscreen-dicing-scale"), + ("bpy.types.fluiddomainsettings.sndparticle_bubble_drag*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-drag"), ("bpy.types.linestylegeometrymodifier_backbonestretcher*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/backbone_stretcher.html#bpy-types-linestylegeometrymodifier-backbonestretcher"), ("bpy.types.linestylegeometrymodifier_sinusdisplacement*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/sinus_displacement.html#bpy-types-linestylegeometrymodifier-sinusdisplacement"), + ("bpy.types.fluiddomainsettings.use_adaptive_timesteps*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-adaptive-timesteps"), + ("bpy.types.fluiddomainsettings.use_dissolve_smoke_log*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-dissolve-smoke-log"), ("bpy.types.linestylegeometrymodifier_polygonalization*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/polygonization.html#bpy-types-linestylegeometrymodifier-polygonalization"), + ("bpy.ops.view3d.edit_mesh_extrude_move_shrink_fatten*", "modeling/meshes/editing/face/extrude_faces_normal.html#bpy-ops-view3d-edit-mesh-extrude-move-shrink-fatten"), ("bpy.types.cyclesrendersettings.distance_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-distance-cull-margin"), + ("bpy.types.fluiddomainsettings.cache_particle_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-particle-format"), + ("bpy.types.fluiddomainsettings.display_interpolation*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-display-interpolation"), ("bpy.types.materialgpencilstyle.use_fill_texture_mix*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-use-fill-texture-mix"), ("bpy.types.rendersettings_simplify_gpencil_shader_fx*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-shader-fx"), ("bpy.types.rendersettings_simplify_gpencil_view_fill*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-fill"), + ("bpy.types.brush.elastic_deform_volume_preservation*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-volume-preservation"), ("bpy.types.brushgpencilsettings.use_jitter_pressure*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-use-jitter-pressure"), ("bpy.types.brushgpencilsettings.use_settings_random*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-use-settings-random"), + ("bpy.types.fluiddomainsettings.mesh_particle_radius*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-particle-radius"), + ("bpy.types.fluiddomainsettings.sndparticle_boundary*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-boundary"), + ("bpy.types.fluiddomainsettings.sndparticle_life_max*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-max"), + ("bpy.types.fluiddomainsettings.sndparticle_life_min*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-min"), + ("bpy.types.fluiddomainsettings.use_bubble_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-bubble-particles"), ("bpy.types.linestylegeometrymodifier_simplification*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/simplification.html#bpy-types-linestylegeometrymodifier-simplification"), ("bpy.types.materialgpencilstyle.use_overlap_strokes*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-use-overlap-strokes"), ("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"), + ("bpy.types.brush.surface_smooth_shape_preservation*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-shape-preservation"), ("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"), + ("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"), + ("bpy.types.fluiddomainsettings.fractions_threshold*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-fractions-threshold"), + ("bpy.types.fluiddomainsettings.particle_band_width*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-band-width"), + ("bpy.types.fluiddomainsettings.particle_randomness*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-randomness"), + ("bpy.types.fluiddomainsettings.use_adaptive_domain*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-use-adaptive-domain"), + ("bpy.types.fluiddomainsettings.use_spray_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-spray-particles"), + ("bpy.types.fluiddomainsettings.vector_display_type*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-display-type"), ("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"), ("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"), - ("bpy.types.smokedomainsettings.use_high_resolution*", "render/cycles/render_settings/simplify.html#bpy-types-smokedomainsettings-use-high-resolution"), + ("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"), ("bpy.types.cyclesrendersettings.use_distance_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-distance-cull"), + ("bpy.types.fluiddomainsettings.delete_in_obstacle*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-delete-in-obstacle"), + ("bpy.types.fluiddomainsettings.mesh_concave_lower*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-concave-lower"), + ("bpy.types.fluiddomainsettings.mesh_concave_upper*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-concave-upper"), + ("bpy.types.fluiddomainsettings.use_dissolve_smoke*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-dissolve-smoke"), + ("bpy.types.fluiddomainsettings.use_flip_particles*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-flip-particles"), + ("bpy.types.fluiddomainsettings.use_foam_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-foam-particles"), + ("bpy.types.fluiddomainsettings.viscosity_exponent*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-viscosity-exponent"), + ("bpy.types.fluideffectorsettings.surface_distance*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-surface-distance"), + ("bpy.types.fluidflowsettings.density_vertex_group*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density-vertex-group"), + ("bpy.types.fluidflowsettings.use_initial_velocity*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-initial-velocity"), ("bpy.types.linestylegeometrymodifier_guidinglines*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/guiding_lines.html#bpy-types-linestylegeometrymodifier-guidinglines"), ("bpy.types.linestylegeometrymodifier_spatialnoise*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/spatial_noise.html#bpy-types-linestylegeometrymodifier-spatialnoise"), ("bpy.types.linestylethicknessmodifier_calligraphy*", "render/freestyle/parameter_editor/line_style/modifiers/thickness/calligraphy.html#bpy-types-linestylethicknessmodifier-calligraphy"), ("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"), + ("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"), ("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"), + ("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"), ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-data-origin"), + ("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/hide_mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"), ("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"), + ("bpy.types.fluiddomainsettings.axis_slice_method*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-axis-slice-method"), + ("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"), + ("bpy.types.fluiddomainsettings.cache_frame_start*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-start"), + ("bpy.types.fluiddomainsettings.cache_mesh_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-mesh-format"), + ("bpy.types.fluiddomainsettings.display_thickness*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-display-thickness"), + ("bpy.types.fluiddomainsettings.flame_smoke_color*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-smoke-color"), + ("bpy.types.fluiddomainsettings.mesh_smoothen_neg*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-smoothen-neg"), + ("bpy.types.fluiddomainsettings.mesh_smoothen_pos*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-smoothen-pos"), + ("bpy.types.fluiddomainsettings.simulation_method*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-simulation-method"), + ("bpy.types.fluiddomainsettings.use_speed_vectors*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-speed-vectors"), + ("bpy.types.fluideffectorsettings.velocity_factor*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-velocity-factor"), ("bpy.types.linestyle*modifier_distancefromcamera*", "render/freestyle/parameter_editor/line_style/modifiers/color/distance_from_camera.html#bpy-types-linestyle-modifier-distancefromcamera"), ("bpy.types.linestyle*modifier_distancefromobject*", "render/freestyle/parameter_editor/line_style/modifiers/color/distance_from_object.html#bpy-types-linestyle-modifier-distancefromobject"), ("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"), @@ -74,31 +135,100 @@ url_manual_mapping = ( ("bpy.types.rendersettings_simplify_gpencil_blend*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-blend"), ("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"), ("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"), + ("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"), + ("bpy.types.fluideffectorsettings.use_plane_init*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-use-plane-init"), ("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"), ("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"), ("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"), + ("bpy.types.brush.surface_smooth_current_vertex*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-current-vertex"), + ("bpy.types.brush.use_multiplane_scrape_dynamic*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-use-multiplane-scrape-dynamic"), + ("bpy.types.clothsettings.vertex_group_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-pressure"), ("bpy.types.cyclesmaterialsettings.displacement*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-displacement"), + ("bpy.types.fluiddomainsettings.adapt_threshold*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-threshold"), + ("bpy.types.fluiddomainsettings.cache_directory*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-directory"), + ("bpy.types.fluiddomainsettings.cache_frame_end*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-end"), + ("bpy.types.fluiddomainsettings.flame_vorticity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-vorticity"), + ("bpy.types.fluiddomainsettings.noise_pos_scale*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-pos-scale"), + ("bpy.types.fluiddomainsettings.noise_time_anim*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-time-anim"), + ("bpy.types.fluiddomainsettings.particle_number*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-number"), + ("bpy.types.fluiddomainsettings.particle_radius*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-radius"), + ("bpy.types.fluiddomainsettings.slice_per_voxel*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-per-voxel"), + ("bpy.types.fluiddomainsettings.surface_tension*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-surface-tension"), + ("bpy.types.fluideffectorsettings.effector_type*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-effector-type"), + ("bpy.types.fluidflowsettings.use_particle_size*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-particle-size"), ("bpy.types.linestylegeometrymodifier_blueprint*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/blueprint.html#bpy-types-linestylegeometrymodifier-blueprint"), ("bpy.types.materialgpencilstyle.alignment_mode*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-alignment-mode"), ("bpy.types.rendersettings.simplify_subdivision*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-subdivision"), + ("bpy.types.spacesequenceeditor.show_region_hud*", "video_editing/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-region-hud"), ("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.view3d.edit_mesh_extrude_move_normal*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-move-normal"), + ("bpy.types.clothsettings.internal_compression*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression"), ("bpy.types.cyclesrendersettings.dicing_camera*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-camera"), ("bpy.types.cyclesrendersettings.texture_limit*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-texture-limit"), + ("bpy.types.fluiddomainsettings.additional_res*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-additional-res"), + ("bpy.types.fluiddomainsettings.dissolve_speed*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-dissolve-speed"), + ("bpy.types.fluiddomainsettings.effector_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-effector-group"), + ("bpy.types.fluiddomainsettings.flame_ignition*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-ignition"), + ("bpy.types.fluiddomainsettings.flame_max_temp*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-max-temp"), + ("bpy.types.fluiddomainsettings.mesh_generator*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-generator"), + ("bpy.types.fluiddomainsettings.noise_strength*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-strength"), + ("bpy.types.fluiddomainsettings.particle_scale*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-particle-scale"), + ("bpy.types.fluiddomainsettings.resolution_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-resolution-max"), + ("bpy.types.fluiddomainsettings.use_color_ramp*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-use-color-ramp"), + ("bpy.types.fluiddomainsettings.viscosity_base*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-viscosity-base"), + ("bpy.types.fluideffectorsettings.use_effector*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-use-effector"), + ("bpy.types.fluidflowsettings.surface_distance*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-surface-distance"), + ("bpy.types.fluidflowsettings.texture_map_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-map-type"), ("bpy.types.gpencilsculptguide.reference_point*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-reference-point"), ("bpy.types.linestylegeometrymodifier_2doffset*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/2d_offset.html#bpy-types-linestylegeometrymodifier-2doffset"), ("bpy.types.linestylegeometrymodifier_sampling*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/sampling.html#bpy-types-linestylegeometrymodifier-sampling"), + ("bpy.types.clothsettings.use_pressure_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure-volume"), + ("bpy.types.clothsettings.vertex_group_intern*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-intern"), ("bpy.types.cyclesrendersettings.*dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-rate"), + ("bpy.types.fluiddomainsettings.cfl_condition*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-cfl-condition"), + ("bpy.types.fluiddomainsettings.show_velocity*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-show-velocity"), + ("bpy.types.fluiddomainsettings.timesteps_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-timesteps-max"), + ("bpy.types.fluiddomainsettings.timesteps_min*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-timesteps-min"), + ("bpy.types.fluiddomainsettings.use_diffusion*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-use-diffusion"), + ("bpy.types.fluiddomainsettings.use_fractions*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-fractions"), + ("bpy.types.fluidflowsettings.particle_system*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-particle-system"), + ("bpy.types.fluidflowsettings.velocity_factor*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-factor"), + ("bpy.types.fluidflowsettings.velocity_normal*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-normal"), ("bpy.types.materialgpencilstyle.stroke_style*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-stroke-style"), ("bpy.types.rendersettings.use_file_extension*", "render/output/settings.html#bpy-types-rendersettings-use-file-extension"), - ("bpy.types.spaceview3d.transform_orientation*", "scene_layout/object/editing/transform/control/orientations.html#bpy-types-spaceview3d-transform-orientation"), + ("bpy.types.spaceview3d.transform_orientation*", "editors/3dview/controls/orientation.html#bpy-types-spaceview3d-transform-orientation"), + ("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/properties/sidebar.html#bpy-types-spaceview3d-use-local-collections"), ("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"), ("bpy.ops.object.vertex_group_copy_to_linked*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-linked"), ("bpy.types.cyclesobjectsettings.dicing_rate*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-dicing-rate"), + ("bpy.types.fluiddomainsettings.adapt_margin*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-margin"), + ("bpy.types.fluiddomainsettings.burning_rate*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-burning-rate"), + ("bpy.types.fluiddomainsettings.guide_parent*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-parent"), + ("bpy.types.fluiddomainsettings.guide_source*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-source"), + ("bpy.types.fluiddomainsettings.particle_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-max"), + ("bpy.types.fluiddomainsettings.particle_min*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-min"), + ("bpy.types.fluiddomainsettings.slice_method*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-method"), + ("bpy.types.fluiddomainsettings.vector_scale*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-scale"), + ("bpy.types.fluideffectorsettings.guide_mode*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-guide-mode"), + ("bpy.types.fluidflowsettings.texture_offset*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-offset"), + ("bpy.types.fluidflowsettings.use_plane_init*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-plane-init"), + ("bpy.types.fluidflowsettings.velocity_coord*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-coord"), + ("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"), ("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-show-stroke"), ("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"), ("bpy.ops.constraint.disable_keep_transform*", "animation/constraints/interface/common.html#bpy-ops-constraint-disable-keep-transform"), ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), + ("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"), ("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-pen-jitter"), + ("bpy.types.fluiddomainsettings.domain_type*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-domain-type"), + ("bpy.types.fluiddomainsettings.flame_smoke*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-smoke"), + ("bpy.types.fluiddomainsettings.fluid_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-fluid-group"), + ("bpy.types.fluiddomainsettings.guide_alpha*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-alpha"), + ("bpy.types.fluiddomainsettings.noise_scale*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-scale"), + ("bpy.types.fluiddomainsettings.slice_depth*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-depth"), + ("bpy.types.fluideffectorsettings.subframes*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-subframes"), + ("bpy.types.fluidflowsettings.flow_behavior*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-behavior"), + ("bpy.types.fluidflowsettings.noise_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-noise-texture"), ("bpy.types.gpencillayer.use_onion_skinning*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-onion-skinning"), ("bpy.types.gpencilsculptguide.use_snapping*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-use-snapping"), ("bpy.types.gpencilsculptsettings.lock_axis*", "grease_pencil/modes/draw/drawing_planes.html#bpy-types-gpencilsculptsettings-lock-axis"), @@ -111,12 +241,24 @@ url_manual_mapping = ( ("bpy.types.rendersettings_simplify_gpencil*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil"), ("bpy.types.sceneeevee.use_taa_reprojection*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-use-taa-reprojection"), ("bpy.types.sequenceeditor.use_overlay_lock*", "video_editing/preview/properties.html#bpy-types-sequenceeditor-use-overlay-lock"), + ("bpy.types.spaceuveditor.show_pixel_coords*", "editors/uv/display_panel.html#bpy-types-spaceuveditor-show-pixel-coords"), ("bpy.types.toolsettings.gpencil_selectmode*", "grease_pencil/selecting.html#bpy-types-toolsettings-gpencil-selectmode"), ("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"), ("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"), - ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/transform/clear_apply.html#bpy-ops-object-anim-transforms-to-deltas"), + ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-uv-random"), + ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), + ("bpy.types.fluiddomainsettings.cache_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-type"), + ("bpy.types.fluiddomainsettings.coba_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-coba-field"), + ("bpy.types.fluiddomainsettings.flip_ratio*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flip-ratio"), + ("bpy.types.fluiddomainsettings.guide_beta*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-beta"), + ("bpy.types.fluiddomainsettings.mesh_scale*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-scale"), + ("bpy.types.fluiddomainsettings.noise_type*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-type"), + ("bpy.types.fluiddomainsettings.slice_axis*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-axis"), + ("bpy.types.fluiddomainsettings.time_scale*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-time-scale"), + ("bpy.types.fluidflowsettings.texture_size*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-size"), + ("bpy.types.fluidflowsettings.use_absolute*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-absolute"), ("bpy.types.linestyle*modifier_alongstroke*", "render/freestyle/parameter_editor/line_style/modifiers/color/along_stroke.html#bpy-types-linestyle-modifier-alongstroke"), ("bpy.types.linestyle*modifier_creaseangle*", "render/freestyle/parameter_editor/line_style/modifiers/color/crease_angle.html#bpy-types-linestyle-modifier-creaseangle"), ("bpy.types.linestylecolormodifier_tangent*", "render/freestyle/parameter_editor/line_style/modifiers/color/tangent.html#bpy-types-linestylecolormodifier-tangent"), @@ -124,56 +266,88 @@ url_manual_mapping = ( ("bpy.types.materialgpencilstyle.show_fill*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-show-fill"), ("bpy.types.rendersettings.use_placeholder*", "render/output/settings.html#bpy-types-rendersettings-use-placeholder"), ("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"), + ("bpy.types.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"), + ("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"), ("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"), ("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"), + ("bpy.types.animdata.action_extrapolation*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-extrapolation"), + ("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"), + ("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"), + ("bpy.types.clothsettings.pressure_factor*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-pressure-factor"), ("bpy.types.compositornodecolorcorrection*", "compositing/types/color/color_correction.html#bpy-types-compositornodecolorcorrection"), ("bpy.types.compositornodemoviedistortion*", "compositing/types/distort/movie_distortion.html#bpy-types-compositornodemoviedistortion"), ("bpy.types.ffmpegsettings.audio_channels*", "scene_layout/scene/properties.html#bpy-types-ffmpegsettings-audio-channels"), + ("bpy.types.fluiddomainsettings.use_guide*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-use-guide"), + ("bpy.types.fluiddomainsettings.use_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-use-noise"), + ("bpy.types.fluiddomainsettings.vorticity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-vorticity"), + ("bpy.types.fluidflowsettings.flow_source*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-source"), + ("bpy.types.fluidflowsettings.fuel_amount*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-fuel-amount"), + ("bpy.types.fluidflowsettings.smoke_color*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-smoke-color"), + ("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"), + ("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"), ("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"), ("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"), ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), - ("bpy.types.spaceuveditor.pixel_snap_mode*", "modeling/meshes/editing/uv/layout.html#bpy-types-spaceuveditor-pixel-snap-mode"), - ("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/editing/uv/layout.html#bpy-types-spaceuveditor-use-live-unwrap"), + ("bpy.types.spaceuveditor.pixel_snap_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-snap-mode"), + ("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"), ("bpy.types.vertexweightproximitymodifier*", "modeling/modifiers/modify/weight_proximity.html#bpy-types-vertexweightproximitymodifier"), + ("bpy.ops.mesh.vertices_smooth_laplacian*", "modeling/meshes/editing/vertex/laplacian_smooth.html#bpy-ops-mesh-vertices-smooth-laplacian"), + ("bpy.types.brush.pose_smooth_iterations*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-smooth-iterations"), + ("bpy.types.brush.use_grab_active_vertex*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-active-vertex"), ("bpy.types.compositornodebrightcontrast*", "compositing/types/color/bright_contrast.html#bpy-types-compositornodebrightcontrast"), ("bpy.types.compositornodedoubleedgemask*", "compositing/types/matte/double_edge_mask.html#bpy-types-compositornodedoubleedgemask"), ("bpy.types.ffmpegsettings.audio_mixrate*", "scene_layout/scene/properties.html#bpy-types-ffmpegsettings-audio-mixrate"), + ("bpy.types.fluiddomainsettings.clipping*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-clipping"), + ("bpy.types.fluiddomainsettings.use_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-mesh"), ("bpy.types.material.preview_render_type*", "render/materials/preview.html#bpy-types-material-preview-render-type"), ("bpy.types.materialgpencilstyle.pattern*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-pattern"), ("bpy.types.materialgpencilstyle.texture*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-texture"), + ("bpy.types.object.use_empty_image_alpha*", "modeling/empties.html#bpy-types-object-use-empty-image-alpha"), ("bpy.types.rendersettings.use_overwrite*", "render/output/settings.html#bpy-types-rendersettings-use-overwrite"), ("bpy.types.sceneeevee.volumetric_shadow*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-shadow"), ("bpy.types.shadernodebsdfhairprincipled*", "render/shader_nodes/shader/hair_principled.html#bpy-types-shadernodebsdfhairprincipled"), ("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"), - ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/fcurves/properties.html#bpy-types-spacegrapheditor-show-cursor"), + ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"), ("bpy.types.spaceimageeditor.show_repeat*", "editors/image/view_tab.html#bpy-types-spaceimageeditor-show-repeat"), + ("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"), ("bpy.ops.curve.normals_make_consistent*", "modeling/curves/editing/control_points.html#bpy-ops-curve-normals-make-consistent"), ("bpy.ops.gpencil.stroke_simplify_fixed*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-simplify-fixed"), ("bpy.ops.object.gpencil_modifier_apply*", "grease_pencil/modifiers/introduction.html#bpy-ops-object-gpencil-modifier-apply"), ("bpy.ops.object.vertex_group_normalize*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize"), - ("bpy.ops.object.visual_transform_apply*", "scene_layout/object/editing/transform/clear_apply.html#bpy-ops-object-visual-transform-apply"), - ("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/display.html#bpy-types-brush-texture-overlay-alpha"), + ("bpy.ops.object.visual_transform_apply*", "scene_layout/object/editing/apply.html#bpy-ops-object-visual-transform-apply"), + ("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-texture-overlay-alpha"), ("bpy.types.brushgpencilsettings.random*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-random"), + ("bpy.types.clothsettings.target_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-target-volume"), ("bpy.types.compositornodebilateralblur*", "compositing/types/filter/bilateral_blur.html#bpy-types-compositornodebilateralblur"), ("bpy.types.compositornodedistancematte*", "compositing/types/matte/distance_key.html#bpy-types-compositornodedistancematte"), + ("bpy.types.fluiddomainsettings.gravity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-gravity"), + ("bpy.types.fluidflowsettings.flow_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-type"), + ("bpy.types.fluidflowsettings.subframes*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-subframes"), ("bpy.types.imagepaint.screen_grab_size*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-screen-grab-size"), ("bpy.types.linestyle*modifier_material*", "render/freestyle/parameter_editor/line_style/modifiers/color/material.html#bpy-types-linestyle-modifier-material"), ("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"), ("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"), ("bpy.types.sceneeevee.volumetric_light*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-light"), + ("bpy.types.sculpt.symmetrize_direction*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-symmetrize-direction"), ("bpy.types.sequenceeditor.show_overlay*", "video_editing/preview/properties.html#bpy-types-sequenceeditor-show-overlay"), ("bpy.types.spline.radius_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-radius-interpolation"), + ("bpy.types.viewlayer.material_override*", "render/layers/layers.html#bpy-types-viewlayer-material-override"), ("bpy.ops.gpencil.interpolate_sequence*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-interpolate-sequence"), - ("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-normals-make-consistent"), - ("bpy.ops.object.duplicate_move_linked*", "scene_layout/object/editing/duplication.html#bpy-ops-object-duplicate-move-linked"), + ("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-make-consistent"), + ("bpy.ops.object.duplicate_move_linked*", "scene_layout/object/editing/duplicate_linked.html#bpy-ops-object-duplicate-move-linked"), ("bpy.ops.object.vertex_group_quantize*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-quantize"), ("bpy.ops.view3d.localview_remove_from*", "editors/3dview/navigate/views.html#bpy-ops-view3d-localview-remove-from"), - ("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/display.html#bpy-types-brush-cursor-overlay-alpha"), + ("bpy.types.animdata.action_blend_type*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-blend-type"), + ("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-overlay-alpha"), + ("bpy.types.brush.normal_radius_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-normal-radius-factor"), ("bpy.types.brush.topology_rake_factor*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-brush-topology-rake-factor"), + ("bpy.types.brush.use_pose_ik_anchored*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-ik-anchored"), + ("bpy.types.clothsettings.use_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure"), ("bpy.types.compositornodechannelmatte*", "compositing/types/matte/channel_key.html#bpy-types-compositornodechannelmatte"), ("bpy.types.compositornodecolorbalance*", "compositing/types/color/color_balance.html#bpy-types-compositornodecolorbalance"), ("bpy.types.compositornodekeyingscreen*", "compositing/types/matte/keying_screen.html#bpy-types-compositornodekeyingscreen"), ("bpy.types.dynamicpaintcanvassettings*", "physics/dynamic_paint/canvas.html#bpy-types-dynamicpaintcanvassettings"), + ("bpy.types.fluidflowsettings.use_flow*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-flow"), ("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierfunctiongenerator"), ("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"), @@ -183,45 +357,63 @@ url_manual_mapping = ( ("bpy.types.shadernodeambientocclusion*", "render/shader_nodes/input/ao.html#bpy-types-shadernodeambientocclusion"), ("bpy.types.shadernodevolumeabsorption*", "render/shader_nodes/shader/volume_absorption.html#bpy-types-shadernodevolumeabsorption"), ("bpy.types.shadernodevolumeprincipled*", "render/shader_nodes/shader/volume_principled.html#bpy-types-shadernodevolumeprincipled"), - ("bpy.types.toolsettings.use_uv_sculpt*", "modeling/meshes/editing/uv/uv_sculpt.html#bpy-types-toolsettings-use-uv-sculpt"), + ("bpy.types.toolsettings.use_uv_sculpt*", "modeling/meshes/uv/uv_sculpt.html#bpy-types-toolsettings-use-uv-sculpt"), ("bpy.ops.gpencil.interpolate_reverse*", "grease_pencil/animation/interpolation.html#bpy-ops-gpencil-interpolate-reverse"), + ("bpy.ops.gpencil.select_vertex_color*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-vertex-color"), ("bpy.ops.gpencil.set_active_material*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-set-active-material"), ("bpy.ops.gpencil.stroke_change_color*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-change-color"), ("bpy.ops.gpencil.stroke_cyclical_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-cyclical-set"), - ("bpy.ops.mesh.set_normals_from_faces*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-set-normals-from-faces"), - ("bpy.ops.object.duplicates_make_real*", "scene_layout/object/editing/transform/clear_apply.html#bpy-ops-object-duplicates-make-real"), - ("bpy.ops.object.transforms_to_deltas*", "scene_layout/object/editing/transform/clear_apply.html#bpy-ops-object-transforms-to-deltas"), + ("bpy.ops.mesh.set_normals_from_faces*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-set-normals-from-faces"), + ("bpy.ops.mesh.shape_propagate_to_all*", "modeling/meshes/editing/vertex/propagate_shapes.html#bpy-ops-mesh-shape-propagate-to-all"), + ("bpy.ops.mesh.vert_connect_nonplanar*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-nonplanar"), + ("bpy.ops.object.duplicates_make_real*", "scene_layout/object/editing/apply.html#bpy-ops-object-duplicates-make-real"), + ("bpy.ops.object.transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-transforms-to-deltas"), ("bpy.ops.sequencer.view_ghost_border*", "video_editing/preview/properties.html#bpy-ops-sequencer-view-ghost-border"), - ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/display.html#bpy-types-brush-use-primary-overlay"), + ("bpy.types.animdata.action_influence*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-influence"), + ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"), + ("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"), + ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"), ("bpy.types.compositornodechromamatte*", "compositing/types/matte/chroma_key.html#bpy-types-compositornodechromamatte"), ("bpy.types.compositornodedilateerode*", "compositing/types/filter/dilate_erode.html#bpy-types-compositornodedilateerode"), ("bpy.types.compositornodeellipsemask*", "compositing/types/matte/ellipse_mask.html#bpy-types-compositornodeellipsemask"), ("bpy.types.compositornodesplitviewer*", "compositing/types/output/split_viewer.html#bpy-types-compositornodesplitviewer"), ("bpy.types.dynamicpaintbrushsettings*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings"), + ("bpy.types.fluiddomainsettings.alpha*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-alpha"), + ("bpy.types.fluidflowsettings.density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density"), + ("bpy.types.light.use_custom_distance*", "render/eevee/lighting.html#bpy-types-light-use-custom-distance"), ("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-flip"), ("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-mode"), + ("bpy.types.object.empty_display_size*", "modeling/empties.html#bpy-types-object-empty-display-size"), + ("bpy.types.object.empty_display_type*", "modeling/empties.html#bpy-types-object-empty-display-type"), ("bpy.types.rendersettings.use_border*", "render/output/settings.html#bpy-types-rendersettings-use-border"), ("bpy.types.sceneeevee.bokeh_max_size*", "render/eevee/render_settings/depth_of_field.html#bpy-types-sceneeevee-bokeh-max-size"), ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/anisotropic.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.shadernodevectortransform*", "render/shader_nodes/vector/transform.html#bpy-types-shadernodevectortransform"), - ("bpy.types.spaceuveditor.lock_bounds*", "modeling/meshes/editing/uv/layout.html#bpy-types-spaceuveditor-lock-bounds"), + ("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.ops.mesh.quads_convert_to_tris*", "modeling/meshes/editing/faces.html#bpy-ops-mesh-quads-convert-to-tris"), + ("bpy.ops.mesh.customdata_mask_clear*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-mesh-customdata-mask-clear"), + ("bpy.ops.mesh.extrude_vertices_move*", "modeling/meshes/editing/vertex/extrude_vertices.html#bpy-ops-mesh-extrude-vertices-move"), + ("bpy.ops.mesh.mod_weighted_strength*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-mod-weighted-strength"), + ("bpy.ops.mesh.quads_convert_to_tris*", "modeling/meshes/editing/face/triangulate_faces.html#bpy-ops-mesh-quads-convert-to-tris"), + ("bpy.ops.mesh.tris_convert_to_quads*", "modeling/meshes/editing/face/triangles_quads.html#bpy-ops-mesh-tris-convert-to-quads"), ("bpy.ops.node.read_fullsamplelayers*", "interface/controls/nodes/editing.html#bpy-ops-node-read-fullsamplelayers"), - ("bpy.ops.object.datalayout_transfer*", "modeling/meshes/editing/data_transfer.html#bpy-ops-object-datalayout-transfer"), - ("bpy.ops.object.randomize_transform*", "scene_layout/object/editing/transform/tools.html#bpy-ops-object-randomize-transform"), + ("bpy.ops.object.datalayout_transfer*", "scene_layout/object/editing/relations.html#bpy-ops-object-datalayout-transfer"), + ("bpy.ops.object.randomize_transform*", "scene_layout/object/editing/transform/randomize.html#bpy-ops-object-randomize-transform"), ("bpy.ops.object.vertex_group_invert*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-invert"), ("bpy.ops.object.vertex_group_levels*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-levels"), ("bpy.ops.object.vertex_group_mirror*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-mirror"), ("bpy.ops.object.vertex_group_remove*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove"), ("bpy.ops.object.vertex_group_smooth*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-smooth"), + ("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/sequencer/strips/transitions/cross.html#bpy-ops-sequencer-crossfade-sounds"), ("bpy.ops.sequencer.export_subtitles*", "video_editing/preview/introduction.html#bpy-ops-sequencer-export-subtitles"), - ("bpy.ops.transform.edge_bevelweight*", "modeling/meshes/editing/edges.html#bpy-ops-transform-edge-bevelweight"), + ("bpy.ops.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"), ("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"), - ("bpy.types.brush.use_cursor_overlay*", "sculpt_paint/brush/display.html#bpy-types-brush-use-cursor-overlay"), + ("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-auto-smooth-factor"), + ("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"), + ("bpy.types.brush.use_cursor_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-cursor-overlay"), ("bpy.types.compositornodebokehimage*", "compositing/types/input/bokeh_image.html#bpy-types-compositornodebokehimage"), ("bpy.types.compositornodecolormatte*", "compositing/types/matte/color_key.html#bpy-types-compositornodecolormatte"), ("bpy.types.compositornodecolorspill*", "compositing/types/matte/color_spill.html#bpy-types-compositornodecolorspill"), @@ -231,10 +423,13 @@ url_manual_mapping = ( ("bpy.types.copytransformsconstraint*", "animation/constraints/transform/copy_transforms.html#bpy-types-copytransformsconstraint"), ("bpy.types.correctivesmoothmodifier*", "modeling/modifiers/deform/corrective_smooth.html#bpy-types-correctivesmoothmodifier"), ("bpy.types.cyclesvisibilitysettings*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesvisibilitysettings"), + ("bpy.types.fluiddomainsettings.beta*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-beta"), + ("bpy.types.fluidmodifier.fluid_type*", "physics/fluid/type/index.html#bpy-types-fluidmodifier-fluid-type"), + ("bpy.types.image.use_half_precision*", "editors/image/image_settings.html#bpy-types-image-use-half-precision"), ("bpy.types.imagepaint.interpolation*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-interpolation"), ("bpy.types.linestyle*modifier_noise*", "render/freestyle/parameter_editor/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.mesh.use_mirror_topology*", "modeling/meshes/editing/mesh_options.html#bpy-types-mesh-use-mirror-topology"), + ("bpy.types.mesh.use_mirror_topology*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-topology"), ("bpy.types.particleinstancemodifier*", "modeling/modifiers/simulate/particle_instance.html#bpy-types-particleinstancemodifier"), ("bpy.types.shadernodebrightcontrast*", "render/shader_nodes/color/bright_contrast.html#bpy-types-shadernodebrightcontrast"), ("bpy.types.shadernodebsdfprincipled*", "render/shader_nodes/shader/principled.html#bpy-types-shadernodebsdfprincipled"), @@ -244,13 +439,15 @@ url_manual_mapping = ( ("bpy.types.subdividegpencilmodifier*", "grease_pencil/modifiers/generate/subdivide.html#bpy-types-subdividegpencilmodifier"), ("bpy.types.thicknessgpencilmodifier*", "grease_pencil/modifiers/deform/thickness.html#bpy-types-thicknessgpencilmodifier"), ("bpy.types.transformcacheconstraint*", "animation/constraints/transform/transform_cache.html#bpy-types-transformcacheconstraint"), - ("bpy.types.userpreferencesfilepaths*", "editors/preferences/file_paths.html#bpy-types-userpreferencesfilepaths"), ("bpy.types.vertexweighteditmodifier*", "modeling/modifiers/modify/weight_edit.html#bpy-types-vertexweighteditmodifier"), - ("bpy.ops.curve.match_texture_space*", "editors/uv/generated_uvs.html#bpy-ops-curve-match-texture-space"), - ("bpy.ops.font.text_paste_from_file*", "modeling/texts/selecting_editing.html#bpy-ops-font-text-paste-from-file"), + ("bpy.ops.anim.channels_clean_empty*", "editors/nla/editing.html#bpy-ops-anim-channels-clean-empty"), + ("bpy.ops.curve.match_texture_space*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-ops-curve-match-texture-space"), + ("bpy.ops.font.text_paste_from_file*", "modeling/texts/editing.html#bpy-ops-font-text-paste-from-file"), ("bpy.ops.gpencil.frame_clean_loose*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-loose"), + ("bpy.ops.mesh.vert_connect_concave*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-concave"), ("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"), ("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.html#bpy-ops-sculpt-set-pivot-position"), ("bpy.types.armaturegpencilmodifier*", "grease_pencil/modifiers/deform/armature.html#bpy-types-armaturegpencilmodifier"), ("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"), ("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"), @@ -265,7 +462,6 @@ url_manual_mapping = ( ("bpy.types.compositornodestabilize*", "compositing/types/distort/stabilize_2d.html#bpy-types-compositornodestabilize"), ("bpy.types.compositornodetransform*", "compositing/types/distort/transform.html#bpy-types-compositornodetransform"), ("bpy.types.compositornodetranslate*", "compositing/types/distort/translate.html#bpy-types-compositornodetranslate"), - ("bpy.types.fluidsimulationmodifier*", "physics/fluid/index.html#bpy-types-fluidsimulationmodifier"), ("bpy.types.freestylemodulesettings*", "render/freestyle/python.html#bpy-types-freestylemodulesettings"), ("bpy.types.gpencillayer.blend_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-blend-mode"), ("bpy.types.gpencillayer.mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-mask-layer"), @@ -275,25 +471,38 @@ url_manual_mapping = ( ("bpy.types.limitdistanceconstraint*", "animation/constraints/transform/limit_distance.html#bpy-types-limitdistanceconstraint"), ("bpy.types.limitlocationconstraint*", "animation/constraints/transform/limit_location.html#bpy-types-limitlocationconstraint"), ("bpy.types.limitrotationconstraint*", "animation/constraints/transform/limit_rotation.html#bpy-types-limitrotationconstraint"), + ("bpy.types.multiplygpencilmodifier*", "grease_pencil/modifiers/generate/multiple_strokes.html#bpy-types-multiplygpencilmodifier"), ("bpy.types.rendersettings.filepath*", "render/output/settings.html#bpy-types-rendersettings-filepath"), ("bpy.types.sceneeevee.use_overscan*", "render/eevee/render_settings/film.html#bpy-types-sceneeevee-use-overscan"), ("bpy.types.shadernodeeeveespecular*", "render/shader_nodes/shader/specular_bsdf.html#bpy-types-shadernodeeeveespecular"), ("bpy.types.shadernodehuesaturation*", "render/shader_nodes/color/hue_saturation.html#bpy-types-shadernodehuesaturation"), + ("bpy.types.shadernodetexwhitenoise*", "render/shader_nodes/textures/white_noise.html#bpy-types-shadernodetexwhitenoise"), ("bpy.types.shadernodevolumescatter*", "render/shader_nodes/shader/volume_scatter.html#bpy-types-shadernodevolumescatter"), ("bpy.types.simplifygpencilmodifier*", "grease_pencil/modifiers/generate/simplify.html#bpy-types-simplifygpencilmodifier"), ("bpy.types.spacegrapheditor.cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-cursor"), ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), + ("bpy.types.viewlayer.use_freestyle*", "render/layers/layers.html#bpy-types-viewlayer-use-freestyle"), ("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"), ("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"), + ("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"), + ("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"), + ("bpy.ops.mesh.intersect_boolean()*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"), + ("bpy.ops.mesh.mark_freestyle_face*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-mark-freestyle-face"), ("bpy.ops.object.constraints_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-clear"), + ("bpy.ops.object.quadriflow_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-quadriflow-remesh"), ("bpy.ops.object.vertex_group_copy*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy"), - ("bpy.ops.object.vertex_group_lock*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-lock"), + ("bpy.ops.object.vertex_group_lock*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-lock"), ("bpy.ops.object.vertex_group_move*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-move"), ("bpy.ops.object.vertex_group_sort*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-sort"), - ("bpy.ops.uv.average_islands_scale*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-average-islands-scale"), - ("bpy.ops.view3d.edit_mesh_extrude*", "modeling/meshes/editing/duplicating/extrude.html#bpy-ops-view3d-edit-mesh-extrude"), + ("bpy.ops.object.vertex_parent_set*", "modeling/meshes/editing/vertex/make_vertex_parent.html#bpy-ops-object-vertex-parent-set"), + ("bpy.ops.paint.mask_lasso_gesture*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-paint-mask-lasso-gesture"), + ("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"), + ("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), ("bpy.types.brightcontrastmodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-brightcontrastmodifier"), - ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/display.html#bpy-types-brush-cursor-color-add"), + ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), + ("bpy.types.brush.pose_ik_segments*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-ik-segments"), + ("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"), ("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"), ("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"), ("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"), @@ -310,6 +519,7 @@ url_manual_mapping = ( ("bpy.types.copylocationconstraint*", "animation/constraints/transform/copy_location.html#bpy-types-copylocationconstraint"), ("bpy.types.copyrotationconstraint*", "animation/constraints/transform/copy_rotation.html#bpy-types-copyrotationconstraint"), ("bpy.types.cyclesmaterialsettings*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings"), + ("bpy.types.dopesheet.show_summary*", "editors/dope_sheet/introduction.html#bpy-types-dopesheet-show-summary"), ("bpy.types.imagepaint.use_occlude*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-occlude"), ("bpy.types.latticegpencilmodifier*", "grease_pencil/modifiers/deform/lattice.html#bpy-types-latticegpencilmodifier"), ("bpy.types.mesh.auto_smooth_angle*", "modeling/meshes/structure.html#bpy-types-mesh-auto-smooth-angle"), @@ -322,6 +532,8 @@ url_manual_mapping = ( ("bpy.types.shadernodedisplacement*", "render/shader_nodes/vector/displacement.html#bpy-types-shadernodedisplacement"), ("bpy.types.shadernodelightfalloff*", "render/shader_nodes/color/light_falloff.html#bpy-types-shadernodelightfalloff"), ("bpy.types.shadernodeparticleinfo*", "render/shader_nodes/input/particle_info.html#bpy-types-shadernodeparticleinfo"), + ("bpy.types.shadernodevectorrotate*", "render/shader_nodes/vector/vector_rotate.html#bpy-types-shadernodevectorrotate"), + ("bpy.types.volumerender.step_size*", "modeling/volumes/properties.html#bpy-types-volumerender-step-size"), ("bpy.types.weightednormalmodifier*", "modeling/modifiers/modify/weighted_normal.html#bpy-types-weightednormalmodifier"), ("bpy.ops.curve.spline_weight_set*", "modeling/curves/editing/other.html#bpy-ops-curve-spline-weight-set"), ("bpy.ops.gpencil.blank_frame_add*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-blank-frame-add"), @@ -329,22 +541,31 @@ url_manual_mapping = ( ("bpy.ops.gpencil.stroke_caps_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-caps-set"), ("bpy.ops.gpencil.stroke_separate*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-separate"), ("bpy.ops.gpencil.stroke_simplify*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-simplify"), + ("bpy.ops.mesh.extrude_edges_move*", "modeling/meshes/editing/edge/extrude_edges.html#bpy-ops-mesh-extrude-edges-move"), + ("bpy.ops.mesh.extrude_faces_move*", "modeling/meshes/editing/face/extrude_individual_faces.html#bpy-ops-mesh-extrude-faces-move"), + ("bpy.ops.mesh.subdivide_edgering*", "modeling/meshes/editing/edge/subdivide_edge_ring.html#bpy-ops-mesh-subdivide-edgering"), ("bpy.ops.object.constraints_copy*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-copy"), ("bpy.ops.object.gpencil_modifier*", "grease_pencil/modifiers/index.html#bpy-ops-object-gpencil-modifier"), - ("bpy.ops.object.make_single_user*", "scene_layout/object/editing/duplication.html#bpy-ops-object-make-single-user"), + ("bpy.ops.object.make_single_user*", "scene_layout/object/editing/relations.html#bpy-ops-object-make-single-user"), ("bpy.ops.object.select_hierarchy*", "scene_layout/object/selecting.html#bpy-ops-object-select-hierarchy"), ("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.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"), ("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"), + ("bpy.ops.scene.view_layer_remove*", "render/layers/layers.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.transform.rotate_normal*", "modeling/meshes/editing/normals.html#bpy-ops-transform-rotate-normal"), - ("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"), - ("bpy.ops.wm.dependency_relations*", "advanced/operators.html#bpy-ops-wm-dependency-relations"), + ("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"), + ("bpy.ops.transform.vertex_random*", "modeling/meshes/editing/mesh/transform/randomize.html#bpy-ops-transform-vertex-random"), + ("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"), ("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"), - ("bpy.types.brush.use_custom_icon*", "sculpt_paint/brush/display.html#bpy-types-brush-use-custom-icon"), + ("bpy.types.armature.use_mirror_x*", "animation/armatures/bones/tools/tool_settings.html#bpy-types-armature-use-mirror-x"), + ("bpy.types.brush.use_custom_icon*", "sculpt_paint/brush/brush.html#bpy-types-brush-use-custom-icon"), + ("bpy.types.brushtextureslot.mask*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-mask"), ("bpy.types.camerabackgroundimage*", "render/cameras.html#bpy-types-camerabackgroundimage"), ("bpy.types.compositornodeboxmask*", "compositing/types/matte/box_mask.html#bpy-types-compositornodeboxmask"), ("bpy.types.compositornodedefocus*", "compositing/types/filter/defocus.html#bpy-types-compositornodedefocus"), + ("bpy.types.compositornodedenoise*", "compositing/types/filter/denoise.html#bpy-types-compositornodedenoise"), ("bpy.types.compositornodeinpaint*", "compositing/types/filter/inpaint.html#bpy-types-compositornodeinpaint"), ("bpy.types.compositornodergbtobw*", "compositing/types/converter/rgb_to_bw.html#bpy-types-compositornodergbtobw"), ("bpy.types.compositornoderlayers*", "compositing/types/input/render_layers.html#bpy-types-compositornoderlayers"), @@ -353,14 +574,16 @@ url_manual_mapping = ( ("bpy.types.compositornodevecblur*", "compositing/types/filter/vector_blur.html#bpy-types-compositornodevecblur"), ("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.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"), ("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"), ("bpy.types.gpencilsculptsettings*", "grease_pencil/properties/index.html#bpy-types-gpencilsculptsettings"), + ("bpy.types.light.cutoff_distance*", "render/eevee/lighting.html#bpy-types-light-cutoff-distance"), ("bpy.types.lockedtrackconstraint*", "animation/constraints/tracking/locked_track.html#bpy-types-lockedtrackconstraint"), ("bpy.types.material.blend_method*", "render/eevee/materials/settings.html#bpy-types-material-blend-method"), ("bpy.types.mirrorgpencilmodifier*", "grease_pencil/modifiers/generate/mirror.html#bpy-types-mirrorgpencilmodifier"), - ("bpy.types.obstaclefluidsettings*", "physics/fluid/types/obstacle.html#bpy-types-obstaclefluidsettings"), ("bpy.types.offsetgpencilmodifier*", "grease_pencil/modifiers/deform/offset.html#bpy-types-offsetgpencilmodifier"), ("bpy.types.particlefluidsettings*", "physics/particles/emitter/physics/fluid.html#bpy-types-particlefluidsettings"), + ("bpy.types.posebone.custom_shape*", "animation/armatures/bones/properties/display.html#bpy-types-posebone-custom-shape"), ("bpy.types.sceneeevee.volumetric*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric"), ("bpy.types.shadernodebsdfdiffuse*", "render/shader_nodes/shader/diffuse.html#bpy-types-shadernodebsdfdiffuse"), ("bpy.types.shadernodelayerweight*", "render/shader_nodes/input/layer_weight.html#bpy-types-shadernodelayerweight"), @@ -369,19 +592,28 @@ url_manual_mapping = ( ("bpy.types.shadernodetexgradient*", "render/shader_nodes/textures/gradient.html#bpy-types-shadernodetexgradient"), ("bpy.types.shadernodetexmusgrave*", "render/shader_nodes/textures/musgrave.html#bpy-types-shadernodetexmusgrave"), ("bpy.types.shadernodevectorcurve*", "render/shader_nodes/vector/curves.html#bpy-types-shadernodevectorcurve"), + ("bpy.types.shadernodevertexcolor*", "render/shader_nodes/input/vertex_color.html#bpy-types-shadernodevertexcolor"), ("bpy.types.smoothgpencilmodifier*", "grease_pencil/modifiers/deform/smooth.html#bpy-types-smoothgpencilmodifier"), ("bpy.types.spline.use_endpoint_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-endpoint-u"), - ("bpy.types.userpreferencessystem*", "editors/preferences/system.html#bpy-types-userpreferencessystem"), + ("bpy.types.surfacedeformmodifier*", "modeling/modifiers/deform/surface_deform.html#bpy-types-surfacedeformmodifier"), + ("bpy.types.viewlayer.use_volumes*", "render/layers/layers.html#bpy-types-viewlayer-use-volumes"), + ("bpy.types.volume.frame_duration*", "modeling/volumes/properties.html#bpy-types-volume-frame-duration"), + ("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.ops.curve.switch_direction*", "modeling/curves/editing/segments.html#bpy-ops-curve-switch-direction"), ("bpy.ops.gpencil.duplicate_move*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-duplicate-move"), ("bpy.ops.gpencil.stroke_arrange*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-arrange"), - ("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edges.html#bpy-ops-mesh-bridge-edge-loops"), + ("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"), + ("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"), + ("bpy.ops.nla.action_sync_length*", "editors/nla/editing.html#bpy-ops-nla-action-sync-length"), ("bpy.ops.object.paths_calculate*", "animation/motion_paths.html#bpy-ops-object-paths-calculate"), - ("bpy.ops.object.transform_apply*", "scene_layout/object/editing/transform/clear_apply.html#bpy-ops-object-transform-apply"), - ("bpy.ops.outliner.lib_operation*", "files/linked_libraries.html#bpy-ops-outliner-lib-operation"), + ("bpy.ops.object.transform_apply*", "scene_layout/object/editing/apply.html#bpy-ops-object-transform-apply"), + ("bpy.ops.outliner.lib_operation*", "files/linked_libraries/introduction.html#bpy-ops-outliner-lib-operation"), + ("bpy.ops.outliner.orphans_purge*", "editors/outliner.html#bpy-ops-outliner-orphans-purge"), ("bpy.ops.screen.region_quadview*", "editors/3dview/navigate/views.html#bpy-ops-screen-region-quadview"), - ("bpy.ops.uv.follow_active_quads*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-follow-active-quads"), + ("bpy.ops.uv.follow_active_quads*", "modeling/meshes/editing/uv.html#bpy-ops-uv-follow-active-quads"), ("bpy.types.arraygpencilmodifier*", "grease_pencil/modifiers/generate/array.html#bpy-types-arraygpencilmodifier"), + ("bpy.types.brush.use_persistent*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-use-persistent"), ("bpy.types.buildgpencilmodifier*", "grease_pencil/modifiers/generate/build.html#bpy-types-buildgpencilmodifier"), ("bpy.types.colorbalancemodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-colorbalancemodifier"), ("bpy.types.colorgpencilmodifier*", "grease_pencil/modifiers/color/hue_saturation.html#bpy-types-colorgpencilmodifier"), @@ -396,7 +628,6 @@ url_manual_mapping = ( ("bpy.types.compositornoderotate*", "compositing/types/distort/rotate.html#bpy-types-compositornoderotate"), ("bpy.types.compositornodeviewer*", "compositing/types/output/viewer.html#bpy-types-compositornodeviewer"), ("bpy.types.constraint.influence*", "animation/constraints/interface/common.html#bpy-types-constraint-influence"), - ("bpy.types.controlfluidsettings*", "physics/fluid/types/control.html#bpy-types-controlfluidsettings"), ("bpy.types.datatransfermodifier*", "modeling/modifiers/modify/data_transfer.html#bpy-types-datatransfermodifier"), ("bpy.types.dynamicpaintmodifier*", "physics/dynamic_paint/index.html#bpy-types-dynamicpaintmodifier"), ("bpy.types.ffmpegsettings.audio*", "render/output/file_formats.html#bpy-types-ffmpegsettings-audio"), @@ -407,7 +638,7 @@ url_manual_mapping = ( ("bpy.types.limitscaleconstraint*", "animation/constraints/transform/limit_scale.html#bpy-types-limitscaleconstraint"), ("bpy.types.materialgpencilstyle*", "grease_pencil/materials/index.html#bpy-types-materialgpencilstyle"), ("bpy.types.mesh.use_auto_smooth*", "modeling/meshes/structure.html#bpy-types-mesh-use-auto-smooth"), - ("bpy.types.outflowfluidsettings*", "physics/fluid/types/flow.html#bpy-types-outflowfluidsettings"), + ("bpy.types.preferencesfilepaths*", "editors/preferences/file_paths.html#bpy-types-preferencesfilepaths"), ("bpy.types.scene.background_set*", "scene_layout/scene/properties.html#bpy-types-scene-background-set"), ("bpy.types.shadernodebackground*", "render/shader_nodes/shader/background.html#bpy-types-shadernodebackground"), ("bpy.types.shadernodebsdfglossy*", "render/shader_nodes/shader/glossy.html#bpy-types-shadernodebsdfglossy"), @@ -417,35 +648,43 @@ url_manual_mapping = ( ("bpy.types.shadernodetexchecker*", "render/shader_nodes/textures/checker.html#bpy-types-shadernodetexchecker"), ("bpy.types.shadernodetexvoronoi*", "render/shader_nodes/textures/voronoi.html#bpy-types-shadernodetexvoronoi"), ("bpy.types.shadernodevectormath*", "render/shader_nodes/converter/vector_math.html#bpy-types-shadernodevectormath"), + ("bpy.types.shadernodevolumeinfo*", "render/shader_nodes/input/volume_info.html#bpy-types-shadernodevolumeinfo"), ("bpy.types.shadernodewavelength*", "render/shader_nodes/converter/wavelength.html#bpy-types-shadernodewavelength"), ("bpy.types.shrinkwrapconstraint*", "animation/constraints/relationship/shrinkwrap.html#bpy-types-shrinkwrapconstraint"), ("bpy.types.simpledeformmodifier*", "modeling/modifiers/deform/simple_deform.html#bpy-types-simpledeformmodifier"), ("bpy.types.spacedopesheeteditor*", "editors/dope_sheet/index.html#bpy-types-spacedopesheeteditor"), - ("bpy.types.spaceuserpreferences*", "editors/preferences/index.html#bpy-types-spaceuserpreferences"), ("bpy.types.speedcontrolsequence*", "video_editing/sequencer/strips/effects/speed_control.html#bpy-types-speedcontrolsequence"), ("bpy.types.texturenodecurvetime*", "editors/texture_node/types/input/time.html#bpy-types-texturenodecurvetime"), - ("bpy.types.transformorientation*", "scene_layout/object/editing/transform/control/orientations.html#bpy-types-transformorientation"), - ("bpy.types.unifiedpaintsettings*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-unifiedpaintsettings"), - ("bpy.types.userpreferencesinput*", "editors/preferences/input.html#bpy-types-userpreferencesinput"), + ("bpy.types.transformorientation*", "editors/3dview/controls/orientation.html#bpy-types-transformorientation"), + ("bpy.types.unifiedpaintsettings*", "sculpt_paint/brush/brush.html#bpy-types-unifiedpaintsettings"), + ("bpy.types.viewlayer.use_strand*", "render/layers/layers.html#bpy-types-viewlayer-use-strand"), + ("bpy.types.volume.sequence_mode*", "modeling/volumes/properties.html#bpy-types-volume-sequence-mode"), ("bpy.types.whitebalancemodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-whitebalancemodifier"), ("bpy.ops.curve.handle_type_set*", "modeling/curves/editing/control_points.html#bpy-ops-curve-handle-type-set"), ("bpy.ops.curve.spline_type_set*", "modeling/curves/editing/curve.html#bpy-ops-curve-spline-type-set"), ("bpy.ops.gpencil.move_to_layer*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-move-to-layer"), ("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.mesh.smoothen_normals*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-smoothen-normals"), - ("bpy.ops.object.duplicate_move*", "scene_layout/object/editing/duplication.html#bpy-ops-object-duplicate-move"), - ("bpy.ops.object.hook_add_selob*", "modeling/meshes/editing/vertices.html#bpy-ops-object-hook-add-selob"), + ("bpy.ops.graph.keyframe_insert*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-keyframe-insert"), + ("bpy.ops.mesh.blend_from_shape*", "modeling/meshes/editing/vertex/blend_shape.html#bpy-ops-mesh-blend-from-shape"), + ("bpy.ops.mesh.dissolve_limited*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-limited"), + ("bpy.ops.mesh.face_make_planar*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-face-make-planar"), + ("bpy.ops.mesh.paint_mask_slice*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-mesh-paint-mask-slice"), + ("bpy.ops.object.duplicate_move*", "scene_layout/object/editing/duplicate.html#bpy-ops-object-duplicate-move"), + ("bpy.ops.object.hook_add_selob*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook-add-selob"), ("bpy.ops.object.select_by_type*", "scene_layout/object/selecting.html#bpy-ops-object-select-by-type"), ("bpy.ops.object.select_grouped*", "scene_layout/object/selecting.html#bpy-ops-object-select-grouped"), ("bpy.ops.object.select_pattern*", "scene_layout/object/selecting.html#bpy-ops-object-select-pattern"), + ("bpy.ops.paint.mask_flood_fill*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-paint-mask-flood-fill"), ("bpy.ops.screen.repeat_history*", "interface/undo_redo.html#bpy-ops-screen-repeat-history"), ("bpy.ops.sequencer.refresh_all*", "video_editing/sequencer/navigating.html#bpy-ops-sequencer-refresh-all"), ("bpy.ops.surface.primitive*add*", "modeling/surfaces/primitives.html#bpy-ops-surface-primitive-add"), - ("bpy.ops.transform.edge_crease*", "modeling/meshes/editing/edges.html#bpy-ops-transform-edge-crease"), - ("bpy.ops.uv.seams_from_islands*", "modeling/meshes/editing/uv/unwrapping/seams.html#bpy-ops-uv-seams-from-islands"), - ("bpy.types.brush.icon_filepath*", "sculpt_paint/brush/display.html#bpy-types-brush-icon-filepath"), + ("bpy.ops.transform.edge_crease*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-crease"), + ("bpy.ops.transform.skin_resize*", "modeling/meshes/editing/mesh/transform/skin_resize.html#bpy-ops-transform-skin-resize"), + ("bpy.ops.uv.seams_from_islands*", "modeling/meshes/uv/unwrapping/seams.html#bpy-ops-uv-seams-from-islands"), + ("bpy.types.brush.icon_filepath*", "sculpt_paint/brush/brush.html#bpy-types-brush-icon-filepath"), ("bpy.types.brush.smooth_stroke*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brush-smooth-stroke"), + ("bpy.types.brush.tip_roundness*", "sculpt_paint/sculpting/tools/clay_strips.html#bpy-types-brush-tip-roundness"), ("bpy.types.camera.display_size*", "render/cameras.html#bpy-types-camera-display-size"), ("bpy.types.compositornodedblur*", "compositing/types/filter/directional_blur.html#bpy-types-compositornodedblur"), ("bpy.types.compositornodegamma*", "compositing/types/color/gamma.html#bpy-types-compositornodegamma"), @@ -457,13 +696,12 @@ url_manual_mapping = ( ("bpy.types.compositornodevalue*", "compositing/types/input/value.html#bpy-types-compositornodevalue"), ("bpy.types.copyscaleconstraint*", "animation/constraints/transform/copy_scale.html#bpy-types-copyscaleconstraint"), ("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"), - ("bpy.types.domainfluidsettings*", "physics/fluid/types/domain.html#bpy-types-domainfluidsettings"), + ("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"), ("bpy.types.hookgpencilmodifier*", "grease_pencil/modifiers/deform/hook.html#bpy-types-hookgpencilmodifier"), ("bpy.types.imageformatsettings*", "files/media/image_formats.html#bpy-types-imageformatsettings"), - ("bpy.types.inflowfluidsettings*", "physics/fluid/types/flow.html#bpy-types-inflowfluidsettings"), ("bpy.types.kinematicconstraint*", "animation/constraints/tracking/ik_solver.html#bpy-types-kinematicconstraint"), ("bpy.types.mesh.use_paint_mask*", "sculpt_paint/brush/introduction.html#bpy-types-mesh-use-paint-mask"), - ("bpy.types.movietrackingcamera*", "movie_clip/tracking/clip/properties/camera_data.html#bpy-types-movietrackingcamera"), + ("bpy.types.movietrackingcamera*", "movie_clip/tracking/clip/properties/track/camera.html#bpy-types-movietrackingcamera"), ("bpy.types.noisepencilmodifier*", "grease_pencil/modifiers/deform/noise.html#bpy-types-noisepencilmodifier"), ("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"), ("bpy.types.particledupliweight*", "physics/particles/emitter/vertex_groups.html#bpy-types-particledupliweight"), @@ -477,7 +715,6 @@ url_manual_mapping = ( ("bpy.types.shadernodemixshader*", "render/shader_nodes/shader/mix.html#bpy-types-shadernodemixshader"), ("bpy.types.shadernodenormalmap*", "render/shader_nodes/vector/normal_map.html#bpy-types-shadernodenormalmap"), ("bpy.types.shadernodewireframe*", "render/shader_nodes/input/wireframe.html#bpy-types-shadernodewireframe"), - ("bpy.types.smokedomainsettings*", "physics/smoke/types/domain.html#bpy-types-smokedomainsettings"), ("bpy.types.spacesequenceeditor*", "video_editing/index.html#bpy-types-spacesequenceeditor"), ("bpy.types.spline.resolution_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-resolution-u"), ("bpy.types.spline.use_bezier_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-bezier-u"), @@ -489,29 +726,36 @@ url_manual_mapping = ( ("bpy.types.tintgpencilmodifier*", "grease_pencil/modifiers/color/tint.html#bpy-types-tintgpencilmodifier"), ("bpy.types.transformconstraint*", "animation/constraints/transform/transformation.html#bpy-types-transformconstraint"), ("bpy.types.triangulatemodifier*", "modeling/modifiers/generate/triangulate.html#bpy-types-triangulatemodifier"), - ("bpy.types.userpreferencesedit*", "editors/preferences/editing.html#bpy-types-userpreferencesedit"), - ("bpy.types.userpreferencesview*", "editors/preferences/interface.html#bpy-types-userpreferencesview"), + ("bpy.types.viewlayer.use_solid*", "render/layers/layers.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.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.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"), ("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"), ("bpy.ops.curve.duplicate_move*", "modeling/curves/editing/curve.html#bpy-ops-curve-duplicate-move"), + ("bpy.ops.fluid.bake_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-bake-particles"), + ("bpy.ops.fluid.free_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-free-particles"), ("bpy.ops.gpencil.extrude_move*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-extrude-move"), ("bpy.ops.gpencil.stroke_merge*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-stroke-merge"), ("bpy.ops.gpencil.stroke_split*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-split"), - ("bpy.ops.mesh.average_normals*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-average-normals"), - ("bpy.ops.mesh.vertices_smooth*", "modeling/meshes/editing/transform/smooth.html#bpy-ops-mesh-vertices-smooth"), + ("bpy.ops.graph.duplicate_move*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-duplicate-move"), + ("bpy.ops.mesh.average_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-average-normals"), + ("bpy.ops.mesh.delete_edgeloop*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-delete-edgeloop"), + ("bpy.ops.mesh.vertices_smooth*", "modeling/meshes/editing/vertex/smooth_vertices.html#bpy-ops-mesh-vertices-smooth"), + ("bpy.ops.nla.make_single_user*", "editors/nla/editing.html#bpy-ops-nla-make-single-user"), ("bpy.ops.node.read_viewlayers*", "interface/controls/nodes/editing.html#bpy-ops-node-read-viewlayers"), - ("bpy.ops.object.data_transfer*", "modeling/meshes/editing/data_transfer.html#bpy-ops-object-data-transfer"), + ("bpy.ops.object.data_transfer*", "scene_layout/object/editing/relations.html#bpy-ops-object-data-transfer"), ("bpy.ops.object.select_camera*", "scene_layout/object/selecting.html#bpy-ops-object-select-camera"), ("bpy.ops.object.select_linked*", "scene_layout/object/selecting.html#bpy-ops-object-select-linked"), ("bpy.ops.object.select_mirror*", "scene_layout/object/selecting.html#bpy-ops-object-select-mirror"), ("bpy.ops.object.select_random*", "scene_layout/object/selecting.html#bpy-ops-object-select-random"), + ("bpy.ops.paint.add_simple_uvs*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-ops-paint-add-simple-uvs"), + ("bpy.ops.scene.view_layer_add*", "render/layers/layers.html#bpy-ops-scene-view-layer-add"), ("bpy.ops.sound.bake_animation*", "scene_layout/scene/properties.html#bpy-ops-sound-bake-animation"), - ("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edges.html#bpy-ops-transform-edge-slide"), - ("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertices.html#bpy-ops-transform-vert-slide"), - ("bpy.ops.uv.project_from_view*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-project-from-view"), + ("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edge/edge_slide.html#bpy-ops-transform-edge-slide"), + ("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertex/slide_vertices.html#bpy-ops-transform-vert-slide"), + ("bpy.ops.uv.project_from_view*", "modeling/meshes/editing/uv.html#bpy-ops-uv-project-from-view"), ("bpy.ops.wm.memory_statistics*", "advanced/operators.html#bpy-ops-wm-memory-statistics"), ("bpy.types.adjustmentsequence*", "video_editing/sequencer/strips/adjustment.html#bpy-types-adjustmentsequence"), ("bpy.types.alphaundersequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaundersequence"), @@ -526,7 +770,6 @@ url_manual_mapping = ( ("bpy.types.curve.resolution_u*", "modeling/curves/properties/shape.html#bpy-types-curve-resolution-u"), ("bpy.types.curve.resolution_v*", "modeling/surfaces/properties/shape.html#bpy-types-curve-resolution-v"), ("bpy.types.curvepaintsettings*", "modeling/curves/editing/other.html#bpy-types-curvepaintsettings"), - ("bpy.types.fluidfluidsettings*", "physics/fluid/types/fluid_object.html#bpy-types-fluidfluidsettings"), ("bpy.types.fmodifiergenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiergenerator"), ("bpy.types.freestylelinestyle*", "render/freestyle/parameter_editor/line_style/index.html#bpy-types-freestylelinestyle"), ("bpy.types.gammacrosssequence*", "video_editing/sequencer/strips/transitions/cross.html#bpy-types-gammacrosssequence"), @@ -534,9 +777,10 @@ url_manual_mapping = ( ("bpy.types.huecorrectmodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-huecorrectmodifier"), ("bpy.types.imagepaint.stencil*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-imagepaint-stencil"), ("bpy.types.meshdeformmodifier*", "modeling/modifiers/deform/mesh_deform.html#bpy-types-meshdeformmodifier"), - ("bpy.types.movietrackingtrack*", "movie_clip/tracking/clip/properties/introduction.html#bpy-types-movietrackingtrack"), + ("bpy.types.movietrackingtrack*", "movie_clip/tracking/clip/properties/track/index.html#bpy-types-movietrackingtrack"), ("bpy.types.nodeoutputfileslot*", "compositing/types/output/file.html#bpy-types-nodeoutputfileslot"), ("bpy.types.normaleditmodifier*", "modeling/modifiers/modify/normal_edit.html#bpy-types-normaleditmodifier"), + ("bpy.types.object.empty_image*", "modeling/empties.html#bpy-types-object-empty-image"), ("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"), ("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"), ("bpy.types.shadernodebsdfhair*", "render/shader_nodes/shader/hair.html#bpy-types-shadernodebsdfhair"), @@ -555,27 +799,42 @@ url_manual_mapping = ( ("bpy.types.shrinkwrapmodifier*", "modeling/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapmodifier"), ("bpy.types.splineikconstraint*", "animation/constraints/tracking/spline_ik.html#bpy-types-splineikconstraint"), ("bpy.types.texturenodetexture*", "editors/texture_node/types/input/texture.html#bpy-types-texturenodetexture"), + ("bpy.types.view3dshading.type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-type"), + ("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.keyframe_clear*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-clear"), ("bpy.ops.curve.cyclic_toggle*", "modeling/curves/editing/curve.html#bpy-ops-curve-cyclic-toggle"), ("bpy.ops.curve.primitive*add*", "modeling/curves/primitives.html#bpy-ops-curve-primitive-add"), ("bpy.ops.curve.smooth_radius*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-radius"), ("bpy.ops.curve.smooth_weight*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-weight"), + ("bpy.ops.font.change_spacing*", "modeling/texts/editing.html#bpy-ops-font-change-spacing"), ("bpy.ops.gpencil.interpolate*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-interpolate"), ("bpy.ops.gpencil.stroke_flip*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-flip"), ("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.mesh.duplicate_move*", "modeling/meshes/editing/duplicating/duplicate.html#bpy-ops-mesh-duplicate-move"), - ("bpy.ops.mesh.extrude_region*", "modeling/meshes/editing/duplicating/extrude.html#bpy-ops-mesh-extrude-region"), - ("bpy.ops.object.parent_clear*", "scene_layout/object/properties/relations/parents.html#bpy-ops-object-parent-clear"), - ("bpy.ops.object.shade_smooth*", "modeling/meshes/editing/normals.html#bpy-ops-object-shade-smooth"), - ("bpy.ops.transform.push_pull*", "modeling/meshes/editing/transform/push_pull.html#bpy-ops-transform-push-pull"), + ("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"), + ("bpy.ops.mesh.dissolve_faces*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-faces"), + ("bpy.ops.mesh.dissolve_verts*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-verts"), + ("bpy.ops.mesh.duplicate_move*", "modeling/meshes/editing/mesh/duplicate.html#bpy-ops-mesh-duplicate-move"), + ("bpy.ops.mesh.extrude_repeat*", "modeling/meshes/editing/mesh/extrude.html#bpy-ops-mesh-extrude-repeat"), + ("bpy.ops.mesh.remove_doubles*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-remove-doubles"), + ("bpy.ops.mesh.smooth_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-smooth-normals"), + ("bpy.ops.nla.tweakmode_enter*", "editors/nla/editing.html#bpy-ops-nla-tweakmode-enter"), + ("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"), + ("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"), + ("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"), + ("bpy.ops.transform.push_pull*", "modeling/meshes/editing/mesh/transform/push_pull.html#bpy-ops-transform-push-pull"), ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-trackball"), - ("bpy.ops.transform.transform*", "scene_layout/object/editing/transform/control/orientations.html#bpy-ops-transform-transform"), + ("bpy.ops.transform.transform*", "scene_layout/object/editing/transform/align_transform_orientation.html#bpy-ops-transform-transform"), ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-translate"), - ("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-cylinder-project"), - ("bpy.ops.uv.minimize_stretch*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-minimize-stretch"), + ("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.types.alphaoversequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"), ("bpy.types.armatureeditbones*", "animation/armatures/bones/editing/index.html#bpy-types-armatureeditbones"), + ("bpy.types.brush.pose_offset*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-offset"), + ("bpy.types.brush.rake_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-rake-factor"), ("bpy.types.cameradofsettings*", "render/cameras.html#bpy-types-cameradofsettings"), ("bpy.types.childofconstraint*", "animation/constraints/relationship/child_of.html#bpy-types-childofconstraint"), ("bpy.types.clamptoconstraint*", "animation/constraints/tracking/clamp_to.html#bpy-types-clamptoconstraint"), @@ -584,17 +843,22 @@ url_manual_mapping = ( ("bpy.types.compositornodergb*", "compositing/types/input/rgb.html#bpy-types-compositornodergb"), ("bpy.types.compositornodesep*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodesep"), ("bpy.types.edgesplitmodifier*", "modeling/modifiers/generate/edge_split.html#bpy-types-edgesplitmodifier"), + ("bpy.types.fluidflowsettings*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings"), ("bpy.types.fmodifierenvelope*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelope"), ("bpy.types.freestylesettings*", "render/freestyle/view_layer.html#bpy-types-freestylesettings"), ("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.imagepaint.dither*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-dither"), - ("bpy.types.mesh.texture_mesh*", "editors/uv/generated_uvs.html#bpy-types-mesh-texture-mesh"), - ("bpy.types.mesh.use_mirror_x*", "modeling/meshes/editing/mesh_options.html#bpy-types-mesh-use-mirror-x"), + ("bpy.types.mesh.texture_mesh*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-mesh-texture-mesh"), + ("bpy.types.mesh.use_mirror_x*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-x"), + ("bpy.types.mesh.use_mirror_y*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-y"), + ("bpy.types.mesh.use_mirror_z*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-z"), ("bpy.types.meshcachemodifier*", "modeling/modifiers/modify/mesh_cache.html#bpy-types-meshcachemodifier"), ("bpy.types.movieclipsequence*", "video_editing/sequencer/strips/clip_mask.html#bpy-types-movieclipsequence"), ("bpy.types.object.dimensions*", "scene_layout/object/properties/transforms.html#bpy-types-object-dimensions"), - ("bpy.types.object.track_axis*", "scene_layout/object/properties/relations/extras.html#bpy-types-object-track-axis"), + ("bpy.types.object.track_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-track-axis"), + ("bpy.types.pose.use_mirror_x*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-mirror-x"), + ("bpy.types.preferencessystem*", "editors/preferences/system.html#bpy-types-preferencessystem"), ("bpy.types.scene.active_clip*", "scene_layout/scene/properties.html#bpy-types-scene-active-clip"), ("bpy.types.sceneeevee.shadow*", "render/eevee/render_settings/shadows.html#bpy-types-sceneeevee-shadow"), ("bpy.types.shadernodecombine*", "render/shader_nodes/converter/combine_separate.html#bpy-types-shadernodecombine"), @@ -604,8 +868,6 @@ url_manual_mapping = ( ("bpy.types.shadernodergbtobw*", "render/shader_nodes/converter/rgb_to_bw.html#bpy-types-shadernodergbtobw"), ("bpy.types.shadernodetangent*", "render/shader_nodes/input/tangent.html#bpy-types-shadernodetangent"), ("bpy.types.shadernodetexwave*", "render/shader_nodes/textures/wave.html#bpy-types-shadernodetexwave"), - ("bpy.types.smokecollsettings*", "physics/smoke/types/collision.html#bpy-types-smokecollsettings"), - ("bpy.types.smokeflowsettings*", "physics/smoke/types/flow_object.html#bpy-types-smokeflowsettings"), ("bpy.types.spline.use_smooth*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-smooth"), ("bpy.types.texturenodebricks*", "editors/texture_node/types/patterns/bricks.html#bpy-types-texturenodebricks"), ("bpy.types.texturenodemixrgb*", "editors/texture_node/types/color/mix_rgb.html#bpy-types-texturenodemixrgb"), @@ -613,22 +875,36 @@ url_manual_mapping = ( ("bpy.types.tracktoconstraint*", "animation/constraints/tracking/track_to.html#bpy-types-tracktoconstraint"), ("bpy.types.transformsequence*", "video_editing/sequencer/strips/effects/transform.html#bpy-types-transformsequence"), ("bpy.types.uvprojectmodifier*", "modeling/modifiers/modify/uv_project.html#bpy-types-uvprojectmodifier"), + ("bpy.types.viewlayer.samples*", "render/layers/layers.html#bpy-types-viewlayer-samples"), + ("bpy.types.viewlayer.use_sky*", "render/layers/layers.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/nla/editing.html#bpy-ops-anim-channels-move"), ("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.mesh.loopcut_slide*", "modeling/meshes/editing/subdividing/loop.html#bpy-ops-mesh-loopcut-slide"), - ("bpy.ops.mesh.merge_normals*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-merge-normals"), - ("bpy.ops.mesh.normals_tools*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-normals-tools"), - ("bpy.ops.mesh.point_normals*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-point-normals"), + ("bpy.ops.graph.euler_filter*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-euler-filter"), + ("bpy.ops.mesh.beautify_fill*", "modeling/meshes/editing/face/beautify_faces.html#bpy-ops-mesh-beautify-fill"), + ("bpy.ops.mesh.colors_rotate*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-rotate"), + ("bpy.ops.mesh.edge_collapse*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-edge-collapse"), + ("bpy.ops.mesh.edge_face_add*", "modeling/meshes/editing/vertex/make_face_edge.html#bpy-ops-mesh-edge-face-add"), + ("bpy.ops.mesh.knife_project*", "modeling/meshes/editing/mesh/knife_project.html#bpy-ops-mesh-knife-project"), + ("bpy.ops.mesh.loopcut_slide*", "modeling/meshes/tools/loop.html#bpy-ops-mesh-loopcut-slide"), + ("bpy.ops.mesh.merge_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-merge-normals"), + ("bpy.ops.mesh.normals_tools*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-tools"), + ("bpy.ops.mesh.point_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-point-normals"), ("bpy.ops.mesh.primitive*add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-add"), - ("bpy.ops.mesh.split_normals*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-split-normals"), + ("bpy.ops.mesh.rip_edge_move*", "modeling/meshes/editing/vertex/rip_vertices_extend.html#bpy-ops-mesh-rip-edge-move"), + ("bpy.ops.mesh.sort_elements*", "modeling/meshes/editing/mesh/sort_elements.html#bpy-ops-mesh-sort-elements"), + ("bpy.ops.mesh.split_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-split-normals"), + ("bpy.ops.mesh.symmetry_snap*", "modeling/meshes/editing/mesh/snap_symmetry.html#bpy-ops-mesh-symmetry-snap"), ("bpy.ops.object.gpencil_add*", "grease_pencil/primitives.html#bpy-ops-object-gpencil-add"), ("bpy.ops.object.select_less*", "scene_layout/object/selecting.html#bpy-ops-object-select-less"), ("bpy.ops.object.select_more*", "scene_layout/object/selecting.html#bpy-ops-object-select-more"), ("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"), ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), - ("bpy.ops.transform.tosphere*", "modeling/meshes/editing/transform/to_sphere.html#bpy-ops-transform-tosphere"), + ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-expand"), + ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-filter"), + ("bpy.ops.transform.tosphere*", "modeling/meshes/editing/mesh/transform/to_sphere.html#bpy-ops-transform-tosphere"), ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), @@ -643,13 +919,15 @@ url_manual_mapping = ( ("bpy.types.multicamsequence*", "video_editing/sequencer/strips/effects/multicam.html#bpy-types-multicamsequence"), ("bpy.types.multiplysequence*", "video_editing/sequencer/strips/effects/multiply.html#bpy-types-multiplysequence"), ("bpy.types.multiresmodifier*", "modeling/modifiers/generate/multiresolution.html#bpy-types-multiresmodifier"), - ("bpy.types.object.use_extra*", "scene_layout/object/properties/relations/extras.html#bpy-types-object-use-extra"), + ("bpy.types.object.use_extra*", "scene_layout/object/properties/relations.html#bpy-types-object-use-extra"), ("bpy.types.overdropsequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-overdropsequence"), - ("bpy.types.paint.show_brush*", "sculpt_paint/brush/display.html#bpy-types-paint-show-brush"), - ("bpy.types.paint.use_cavity*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-paint-use-cavity"), + ("bpy.types.paint.show_brush*", "sculpt_paint/brush/cursor.html#bpy-types-paint-show-brush"), + ("bpy.types.paint.use_cavity*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-paint-use-cavity"), ("bpy.types.particlesettings*", "physics/particles/index.html#bpy-types-particlesettings"), + ("bpy.types.pose.use_auto_ik*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-auto-ik"), + ("bpy.types.preferencesinput*", "editors/preferences/input.html#bpy-types-preferencesinput"), ("bpy.types.sceneeevee.bloom*", "render/eevee/render_settings/bloom.html#bpy-types-sceneeevee-bloom"), - ("bpy.types.scenerenderlayer*", "render/layers/layers.html#bpy-types-scenerenderlayer"), + ("bpy.types.sculpt.show_mask*", "sculpt_paint/sculpting/hide_mask.html#bpy-types-sculpt-show-mask"), ("bpy.types.sequencemodifier*", "video_editing/sequencer/properties/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"), @@ -663,34 +941,45 @@ url_manual_mapping = ( ("bpy.types.softbodysettings*", "physics/soft_body/settings.html#bpy-types-softbodysettings"), ("bpy.types.solidifymodifier*", "modeling/modifiers/generate/solidify.html#bpy-types-solidifymodifier"), ("bpy.types.spacegrapheditor*", "editors/graph_editor/index.html#bpy-types-spacegrapheditor"), + ("bpy.types.spacepreferences*", "editors/preferences/index.html#bpy-types-spacepreferences"), ("bpy.types.spaceview3d.lock*", "editors/3dview/properties/sidebar.html#bpy-types-spaceview3d-lock"), - ("bpy.types.sphfluidsettings*", "physics/fluid/index.html#bpy-types-sphfluidsettings"), ("bpy.types.subtractsequence*", "video_editing/sequencer/strips/effects/subtract.html#bpy-types-subtractsequence"), ("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"), + ("bpy.types.viewlayer.use_ao*", "render/layers/layers.html#bpy-types-viewlayer-use-ao"), ("bpy.ops.curve.smooth_tilt*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-tilt"), + ("bpy.ops.fluid.bake_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-bake-guides"), + ("bpy.ops.fluid.free_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-free-guides"), + ("bpy.ops.font.style_toggle*", "modeling/texts/editing.html#bpy-ops-font-style-toggle"), ("bpy.ops.gpencil.reproject*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-reproject"), - ("bpy.ops.mesh.flip_normals*", "modeling/meshes/editing/normals.html#bpy-ops-mesh-flip-normals"), - ("bpy.ops.object.lightprobe*", "render/eevee/lightprobes/index.html#bpy-ops-object-lightprobe"), - ("bpy.ops.object.make_links*", "scene_layout/object/editing/duplication.html#bpy-ops-object-make-links"), - ("bpy.ops.object.make_local*", "files/linked_libraries.html#bpy-ops-object-make-local"), + ("bpy.ops.graph.easing_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-easing-type"), + ("bpy.ops.graph.handle_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-handle-type"), + ("bpy.ops.mesh.delete_loose*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-delete-loose"), + ("bpy.ops.mesh.flip_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-flip-normals"), + ("bpy.ops.mesh.vert_connect*", "modeling/meshes/editing/vertex/connect_vertex_pairs.html#bpy-ops-mesh-vert-connect"), + ("bpy.ops.nla.tracks_delete*", "editors/nla/editing.html#bpy-ops-nla-tracks-delete"), + ("bpy.ops.object.lightprobe*", "render/eevee/light_probes/index.html#bpy-ops-object-lightprobe"), + ("bpy.ops.object.make_links*", "scene_layout/object/editing/make_links.html#bpy-ops-object-make-links"), + ("bpy.ops.object.make_local*", "files/linked_libraries/introduction.html#bpy-ops-object-make-local"), ("bpy.ops.object.origin_set*", "scene_layout/object/origin.html#bpy-ops-object-origin-set"), - ("bpy.ops.object.parent_set*", "scene_layout/object/properties/relations/parents.html#bpy-ops-object-parent-set"), - ("bpy.ops.object.proxy_make*", "files/linked_libraries.html#bpy-ops-object-proxy-make"), + ("bpy.ops.object.parent_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-set"), + ("bpy.ops.object.proxy_make*", "files/linked_libraries/library_proxies.html#bpy-ops-object-proxy-make"), ("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"), - ("bpy.ops.object.shade_flat*", "modeling/meshes/editing/normals.html#bpy-ops-object-shade-flat"), + ("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"), ("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"), ("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"), ("bpy.ops.screen.area_dupli*", "interface/window_system/areas.html#bpy-ops-screen-area-dupli"), - ("bpy.ops.uv.remove_doubles*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-remove-doubles"), - ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-sphere-project"), + ("bpy.ops.sculpt.dirty_mask*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-dirty-mask"), + ("bpy.ops.sculpt.symmetrize*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-ops-sculpt-symmetrize"), + ("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"), + ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"), ("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"), ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), + ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), ("bpy.types.explodemodifier*", "modeling/modifiers/simulate/explode.html#bpy-types-explodemodifier"), ("bpy.types.fcurvemodifiers*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fcurvemodifiers"), ("bpy.types.floorconstraint*", "animation/constraints/relationship/floor.html#bpy-types-floorconstraint"), - ("bpy.types.fluidmeshvertex*", "physics/fluid/index.html#bpy-types-fluidmeshvertex"), ("bpy.types.fmodifiercycles*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiercycles"), ("bpy.types.fmodifierlimits*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierlimits"), ("bpy.types.imagepaint.mode*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-mode"), @@ -700,6 +989,8 @@ url_manual_mapping = ( ("bpy.types.object.rotation*", "scene_layout/object/properties/transforms.html#bpy-types-object-rotation"), ("bpy.types.particlehairkey*", "physics/particles/emitter/physics/keyed.html#bpy-types-particlehairkey"), ("bpy.types.pivotconstraint*", "animation/constraints/relationship/pivot.html#bpy-types-pivotconstraint"), + ("bpy.types.preferencesedit*", "editors/preferences/editing.html#bpy-types-preferencesedit"), + ("bpy.types.preferencesview*", "editors/preferences/interface.html#bpy-types-preferencesview"), ("bpy.types.rigidbodyobject*", "physics/rigid_body/index.html#bpy-types-rigidbodyobject"), ("bpy.types.sceneeevee.gtao*", "render/eevee/render_settings/ambient_occlusion.html#bpy-types-sceneeevee-gtao"), ("bpy.types.shadernodebevel*", "render/shader_nodes/input/bevel.html#bpy-types-shadernodebevel"), @@ -713,28 +1004,38 @@ 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.texturenodemath*", "editors/texture_node/types/converter/math.html#bpy-types-texturenodemath"), - ("bpy.types.userpreferences*", "editors/preferences/index.html#bpy-types-userpreferences"), + ("bpy.types.volume.filepath*", "modeling/volumes/properties.html#bpy-types-volume-filepath"), ("bpy.ops.curve.select_row*", "modeling/surfaces/selecting.html#bpy-ops-curve-select-row"), ("bpy.ops.curve.tilt_clear*", "modeling/curves/editing/control_points.html#bpy-ops-curve-tilt-clear"), ("bpy.ops.curve.vertex_add*", "modeling/curves/editing/other.html#bpy-ops-curve-vertex-add"), + ("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.gpencil.dissolve*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-dissolve"), - ("bpy.ops.graph.frame_jump*", "editors/graph_editor/fcurves/properties.html#bpy-ops-graph-frame-jump"), - ("bpy.ops.mesh.edge_rotate*", "modeling/meshes/editing/edges.html#bpy-ops-mesh-edge-rotate"), - ("bpy.ops.object.hide_view*", "scene_layout/object/editing/introduction.html#bpy-ops-object-hide-view"), + ("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.mesh.convex_hull*", "modeling/meshes/editing/mesh/convex_hull.html#bpy-ops-mesh-convex-hull"), + ("bpy.ops.mesh.edge_rotate*", "modeling/meshes/editing/edge/rotate_edge.html#bpy-ops-mesh-edge-rotate"), + ("bpy.ops.mesh.unsubdivide*", "modeling/meshes/editing/edge/unsubdivide.html#bpy-ops-mesh-unsubdivide"), + ("bpy.ops.mesh.uvs_reverse*", "modeling/meshes/uv/editing.html#bpy-ops-mesh-uvs-reverse"), + ("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"), ("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"), - ("bpy.ops.transform.mirror*", "scene_layout/object/editing/transform/mirror.html#bpy-ops-transform-mirror"), + ("bpy.ops.scene.view_layer*", "render/layers/layers.html#bpy-ops-scene-view-layer"), + ("bpy.ops.transform.mirror*", "scene_layout/object/editing/mirror.html#bpy-ops-transform-mirror"), ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-resize"), ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-rotate"), - ("bpy.ops.uv.lightmap_pack*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-lightmap-pack"), - ("bpy.ops.uv.smart_project*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-smart-project"), + ("bpy.ops.uv.lightmap_pack*", "modeling/meshes/editing/uv.html#bpy-ops-uv-lightmap-pack"), + ("bpy.ops.uv.smart_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-smart-project"), ("bpy.ops.view3d.localview*", "editors/3dview/navigate/views.html#bpy-ops-view3d-localview"), + ("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"), + ("bpy.types.brush.hardness*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-hardness"), ("bpy.types.curvesmodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-curvesmodifier"), ("bpy.types.ffmpegsettings*", "render/output/file_formats.html#bpy-types-ffmpegsettings"), ("bpy.types.fmodifiernoise*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiernoise"), ("bpy.types.material.paint*", "sculpt_paint/texture_paint/index.html#bpy-types-material-paint"), ("bpy.types.mirrormodifier*", "modeling/modifiers/generate/mirror.html#bpy-types-mirrormodifier"), ("bpy.types.movieclipproxy*", "editors/clip/sidebar.html#bpy-types-movieclipproxy"), - ("bpy.types.object.up_axis*", "scene_layout/object/properties/relations/extras.html#bpy-types-object-up-axis"), + ("bpy.types.object.up_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-up-axis"), ("bpy.types.particlesystem*", "physics/particles/index.html#bpy-types-particlesystem"), ("bpy.types.particletarget*", "physics/particles/emitter/physics/keyed.html#bpy-types-particletarget"), ("bpy.types.remeshmodifier*", "modeling/modifiers/generate/remesh.html#bpy-types-remeshmodifier"), @@ -750,20 +1051,34 @@ url_manual_mapping = ( ("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"), + ("bpy.types.viewlayer.name*", "render/layers/layers.html#bpy-types-viewlayer-name"), ("bpy.types.voronoitexture*", "render/materials/legacy_textures/types/voronoi.html#bpy-types-voronoitexture"), ("bpy.types.walknavigation*", "editors/3dview/navigate/walk_fly.html#bpy-types-walknavigation"), ("bpy.ops.*.select_circle*", "interface/selecting.html#bpy-ops-select-circle"), ("bpy.ops.anim.keying_set*", "animation/keyframes/keying_sets.html#bpy-ops-anim-keying-set"), + ("bpy.ops.armature.delete*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-delete"), ("bpy.ops.curve.subdivide*", "modeling/curves/editing/segments.html#bpy-ops-curve-subdivide"), ("bpy.ops.ed.undo_history*", "interface/undo_redo.html#bpy-ops-ed-undo-history"), - ("bpy.ops.mesh.edge_split*", "modeling/meshes/editing/edges.html#bpy-ops-mesh-edge-split"), - ("bpy.ops.mesh.mark_sharp*", "modeling/meshes/editing/edges.html#bpy-ops-mesh-mark-sharp"), + ("bpy.ops.fluid.bake_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-bake-data"), + ("bpy.ops.fluid.bake_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-bake-mesh"), + ("bpy.ops.fluid.free_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-free-data"), + ("bpy.ops.fluid.free_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-free-mesh"), + ("bpy.ops.font.select_all*", "modeling/texts/selecting.html#bpy-ops-font-select-all"), + ("bpy.ops.mesh.customdata*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata"), + ("bpy.ops.mesh.edge_split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-edge-split"), + ("bpy.ops.mesh.fill_holes*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-fill-holes"), + ("bpy.ops.mesh.mark_sharp*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-mesh-mark-sharp"), + ("bpy.ops.mesh.symmetrize*", "modeling/meshes/editing/mesh/symmetrize.html#bpy-ops-mesh-symmetrize"), + ("bpy.ops.mesh.uvs_rotate*", "modeling/meshes/uv/editing.html#bpy-ops-mesh-uvs-rotate"), + ("bpy.ops.nla.apply_scale*", "editors/nla/editing.html#bpy-ops-nla-apply-scale"), + ("bpy.ops.nla.clear_scale*", "editors/nla/editing.html#bpy-ops-nla-clear-scale"), + ("bpy.ops.nla.mute_toggle*", "editors/nla/editing.html#bpy-ops-nla-mute-toggle"), ("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.rigidbody.world*", "physics/rigid_body/world.html#bpy-ops-rigidbody-world"), - ("bpy.ops.transform.shear*", "modeling/meshes/editing/transform/shear.html#bpy-ops-transform-shear"), - ("bpy.ops.uv.cube_project*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-cube-project"), - ("bpy.ops.uv.pack_islands*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-pack-islands"), + ("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"), ("bpy.ops.wm.app_template*", "advanced/app_templates.html#bpy-ops-wm-app-template"), ("bpy.ops.wm.batch_rename*", "files/blend/rename.html#bpy-ops-wm-batch-rename"), ("bpy.ops.wm.redraw_timer*", "advanced/operators.html#bpy-ops-wm-redraw-timer"), @@ -780,13 +1095,14 @@ url_manual_mapping = ( ("bpy.types.crosssequence*", "video_editing/sequencer/strips/transitions/cross.html#bpy-types-crosssequence"), ("bpy.types.curvemodifier*", "modeling/modifiers/deform/curve.html#bpy-types-curvemodifier"), ("bpy.types.fieldsettings*", "physics/forces/force_fields/index.html#bpy-types-fieldsettings"), - ("bpy.types.fluidsettings*", "physics/fluid/index.html#bpy-types-fluidsettings"), ("bpy.types.imagesequence*", "video_editing/sequencer/strips/movie_image.html#bpy-types-imagesequence"), ("bpy.types.marbletexture*", "render/materials/legacy_textures/types/marble.html#bpy-types-marbletexture"), ("bpy.types.modifier.show*", "modeling/modifiers/introduction.html#bpy-types-modifier-show"), ("bpy.types.moviesequence*", "video_editing/sequencer/strips/movie_image.html#bpy-types-moviesequence"), ("bpy.types.movietracking*", "movie_clip/tracking/index.html#bpy-types-movietracking"), - ("bpy.types.object.parent*", "scene_layout/object/properties/relations/parents.html#bpy-types-object-parent"), + ("bpy.types.nlastrip.mute*", "editors/nla/properties_modifiers.html#bpy-types-nlastrip-mute"), + ("bpy.types.nlastrip.name*", "editors/nla/properties_modifiers.html#bpy-types-nlastrip-name"), + ("bpy.types.object.parent*", "scene_layout/object/editing/parent.html#bpy-types-object-parent"), ("bpy.types.oceanmodifier*", "modeling/modifiers/simulate/ocean.html#bpy-types-oceanmodifier"), ("bpy.types.particlebrush*", "physics/particles/mode.html#bpy-types-particlebrush"), ("bpy.types.scene.gravity*", "physics/forces/gravity.html#bpy-types-scene-gravity"), @@ -794,30 +1110,37 @@ url_manual_mapping = ( ("bpy.types.scenesequence*", "video_editing/sequencer/strips/scene.html#bpy-types-scenesequence"), ("bpy.types.screwmodifier*", "modeling/modifiers/generate/screw.html#bpy-types-screwmodifier"), ("bpy.types.sequenceproxy*", "video_editing/sequencer/properties/proxy_cache.html#bpy-types-sequenceproxy"), - ("bpy.types.shaderfxlight*", "grease_pencil/visual_effects/light.html#bpy-types-shaderfxlight"), ("bpy.types.shaderfxswirl*", "grease_pencil/visual_effects/swirl.html#bpy-types-shaderfxswirl"), ("bpy.types.shadernodergb*", "render/shader_nodes/input/rgb.html#bpy-types-shadernodergb"), - ("bpy.types.smokemodifier*", "physics/smoke/index.html#bpy-types-smokemodifier"), ("bpy.types.soundsequence*", "video_editing/sequencer/strips/sound.html#bpy-types-soundsequence"), ("bpy.types.spaceoutliner*", "editors/outliner.html#bpy-types-spaceoutliner"), ("bpy.types.spacetimeline*", "editors/timeline.html#bpy-types-spacetimeline"), ("bpy.types.stuccitexture*", "render/materials/legacy_textures/types/stucci.html#bpy-types-stuccitexture"), + ("bpy.types.volumedisplay*", "modeling/volumes/properties.html#bpy-types-volumedisplay"), ("bpy.types.windowmanager*", "interface/index.html#bpy-types-windowmanager"), ("bpy.ops.*.select_lasso*", "interface/selecting.html#bpy-ops-select-lasso"), ("bpy.ops.curve.decimate*", "modeling/curves/editing/curve.html#bpy-ops-curve-decimate"), ("bpy.ops.curve.separate*", "modeling/curves/editing/curve.html#bpy-ops-curve-separate"), + ("bpy.ops.fluid.bake_all*", "physics/fluid/type/domain/cache.html#bpy-ops-fluid-bake-all"), + ("bpy.ops.fluid.free_all*", "physics/fluid/type/domain/cache.html#bpy-ops-fluid-free-all"), ("bpy.ops.gpencil.delete*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-delete"), ("bpy.ops.gpencil.select*", "grease_pencil/selecting.html#bpy-ops-gpencil-select"), - ("bpy.ops.mesh.mark_seam*", "modeling/meshes/editing/edges.html#bpy-ops-mesh-mark-seam"), - ("bpy.ops.mesh.subdivide*", "modeling/meshes/editing/subdividing/subdivide.html#bpy-ops-mesh-subdivide"), - ("bpy.ops.object.convert*", "scene_layout/object/editing/introduction.html#bpy-ops-object-convert"), + ("bpy.ops.graph.decimate*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-decimate"), + ("bpy.ops.mesh.fill_grid*", "modeling/meshes/editing/face/grid_fill.html#bpy-ops-mesh-fill-grid"), + ("bpy.ops.mesh.intersect*", "modeling/meshes/editing/face/intersect_knife.html#bpy-ops-mesh-intersect"), + ("bpy.ops.mesh.mark_seam*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-mesh-mark-seam"), + ("bpy.ops.mesh.polybuild*", "modeling/meshes/tools/poly_build.html#bpy-ops-mesh-polybuild"), + ("bpy.ops.mesh.subdivide*", "modeling/meshes/editing/edge/subdivide.html#bpy-ops-mesh-subdivide"), + ("bpy.ops.mesh.wireframe*", "modeling/meshes/editing/face/wireframe.html#bpy-ops-mesh-wireframe"), + ("bpy.ops.object.convert*", "scene_layout/object/editing/convert.html#bpy-ops-object-convert"), ("bpy.ops.object.gpencil*", "grease_pencil/index.html#bpy-ops-object-gpencil"), ("bpy.ops.object.speaker*", "render/output/audio/speaker.html#bpy-ops-object-speaker"), - ("bpy.ops.transform.bend*", "modeling/meshes/editing/transform/bend.html#bpy-ops-transform-bend"), + ("bpy.ops.transform.bend*", "modeling/meshes/editing/mesh/transform/bend.html#bpy-ops-transform-bend"), ("bpy.ops.transform.tilt*", "modeling/curves/editing/control_points.html#bpy-ops-transform-tilt"), ("bpy.ops.wm.search_menu*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-menu"), ("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"), ("bpy.types.blendtexture*", "render/materials/legacy_textures/types/blend.html#bpy-types-blendtexture"), + ("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"), ("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"), ("bpy.types.colormanaged*", "render/color_management.html#bpy-types-colormanaged"), ("bpy.types.glowsequence*", "video_editing/sequencer/strips/effects/glow.html#bpy-types-glowsequence"), @@ -844,42 +1167,59 @@ url_manual_mapping = ( ("bpy.types.unitsettings*", "scene_layout/scene/properties.html#bpy-types-unitsettings"), ("bpy.types.vertexcolors*", "sculpt_paint/vertex_paint/index.html#bpy-types-vertexcolors"), ("bpy.types.view3dcursor*", "editors/3dview/3d_cursor.html#bpy-types-view3dcursor"), + ("bpy.types.volumerender*", "modeling/volumes/properties.html#bpy-types-volumerender"), ("bpy.types.warpmodifier*", "modeling/modifiers/deform/warp.html#bpy-types-warpmodifier"), ("bpy.types.wavemodifier*", "modeling/modifiers/deform/wave.html#bpy-types-wavemodifier"), + ("bpy.types.weldmodifier*", "modeling/modifiers/generate/weld.html#bpy-types-weldmodifier"), ("bpy.types.wipesequence*", "video_editing/sequencer/strips/transitions/wipe.html#bpy-types-wipesequence"), ("bpy.ops.gpencil.paste*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-paste"), ("bpy.ops.image.project*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-ops-image-project"), - ("bpy.ops.mesh.decimate*", "modeling/meshes/editing/cleanup.html#bpy-ops-mesh-decimate"), - ("bpy.ops.object.*clear*", "scene_layout/object/editing/transform/clear_apply.html#bpy-ops-object-clear"), - ("bpy.ops.object.delete*", "scene_layout/object/editing/introduction.html#bpy-ops-object-delete"), + ("bpy.ops.mesh.decimate*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-decimate"), + ("bpy.ops.mesh.dissolve*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve"), + ("bpy.ops.mesh.rip_move*", "modeling/meshes/editing/vertex/rip_vertices.html#bpy-ops-mesh-rip-move"), + ("bpy.ops.mesh.separate*", "modeling/meshes/editing/mesh/separate.html#bpy-ops-mesh-separate"), + ("bpy.ops.mesh.solidify*", "modeling/meshes/editing/face/solidify_faces.html#bpy-ops-mesh-solidify"), + ("bpy.ops.nla.duplicate*", "editors/nla/editing.html#bpy-ops-nla-duplicate"), + ("bpy.ops.nla.move_down*", "editors/nla/editing.html#bpy-ops-nla-move-down"), + ("bpy.ops.object.*clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-clear"), + ("bpy.ops.object.delete*", "scene_layout/object/editing/delete.html#bpy-ops-object-delete"), ("bpy.ops.screen.header*", "interface/window_system/regions.html#bpy-ops-screen-header"), + ("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"), ("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"), ("bpy.ops.wm.debug_menu*", "advanced/operators.html#bpy-ops-wm-debug-menu"), ("bpy.ops.wm.properties*", "files/data_blocks.html#bpy-ops-wm-properties"), ("bpy.types.addsequence*", "video_editing/sequencer/strips/effects/add.html#bpy-types-addsequence"), ("bpy.types.camera.show*", "render/cameras.html#bpy-types-camera-show"), ("bpy.types.consoleline*", "editors/python_console.html#bpy-types-consoleline"), + ("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"), ("bpy.types.object.lock*", "scene_layout/object/properties/transforms.html#bpy-types-object-lock"), ("bpy.types.object.show*", "scene_layout/object/properties/display.html#bpy-types-object-show"), ("bpy.types.particlekey*", "physics/particles/emitter/physics/keyed.html#bpy-types-particlekey"), ("bpy.types.posebone.ik*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik"), - ("bpy.types.renderlayer*", "render/layers/layers.html#bpy-types-renderlayer"), + ("bpy.types.preferences*", "editors/preferences/index.html#bpy-types-preferences"), + ("bpy.types.renderlayer*", "render/layers/passes.html#bpy-types-renderlayer"), ("bpy.types.shaderfxrim*", "grease_pencil/visual_effects/rim.html#bpy-types-shaderfxrim"), ("bpy.types.spaceview3d*", "editors/3dview/index.html#bpy-types-spaceview3d"), ("bpy.types.uipopupmenu*", "interface/controls/buttons/menus.html#bpy-types-uipopupmenu"), ("bpy.types.vertexpaint*", "sculpt_paint/vertex_paint/index.html#bpy-types-vertexpaint"), + ("bpy.types.volumegrids*", "modeling/volumes/properties.html#bpy-types-volumegrids"), ("bpy.types.woodtexture*", "render/materials/legacy_textures/types/wood.html#bpy-types-woodtexture"), ("bpy.ops.*.select_box*", "interface/selecting.html#bpy-ops-select-box"), ("bpy.ops.curve.delete*", "modeling/curves/editing/curve.html#bpy-ops-curve-delete"), ("bpy.ops.curve.reveal*", "modeling/curves/editing/curve.html#bpy-ops-curve-reveal"), ("bpy.ops.curve.smooth*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth"), + ("bpy.ops.fluid.preset*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-ops-fluid-preset"), ("bpy.ops.gpencil.copy*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-copy"), - ("bpy.ops.object.align*", "scene_layout/object/editing/transform/tools.html#bpy-ops-object-align"), + ("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.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.object.align*", "scene_layout/object/editing/transform/align_objects.html#bpy-ops-object-align"), ("bpy.ops.object.empty*", "modeling/empties.html#bpy-ops-object-empty"), ("bpy.ops.object.quick*", "physics/introduction.html#bpy-ops-object-quick"), - ("bpy.ops.uv.mark_seam*", "modeling/meshes/editing/uv/unwrapping/seams.html#bpy-ops-uv-mark-seam"), + ("bpy.ops.uv.mark_seam*", "modeling/meshes/uv/unwrapping/seams.html#bpy-ops-uv-mark-seam"), ("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.bpy_struct*", "files/data_blocks.html#bpy-types-bpy-struct"), @@ -887,21 +1227,28 @@ url_manual_mapping = ( ("bpy.types.compositor*", "compositing/index.html#bpy-types-compositor"), ("bpy.types.constraint*", "animation/constraints/index.html#bpy-types-constraint"), ("bpy.types.imagepaint*", "sculpt_paint/texture_paint/index.html#bpy-types-imagepaint"), - ("bpy.types.lightprobe*", "render/eevee/lightprobes/index.html#bpy-types-lightprobe"), + ("bpy.types.lightprobe*", "render/eevee/light_probes/index.html#bpy-types-lightprobe"), ("bpy.types.nodesocket*", "interface/controls/nodes/parts.html#bpy-types-nodesocket"), + ("bpy.types.paint.tile*", "sculpt_paint/texture_paint/tool_settings/tiling.html#bpy-types-paint-tile"), ("bpy.types.pointcache*", "physics/baking.html#bpy-types-pointcache"), ("bpy.types.pointlight*", "render/lights/light_object.html#bpy-types-pointlight"), - ("bpy.types.renderview*", "render/output/multiview/index.html#bpy-types-renderview"), + ("bpy.types.renderview*", "render/output/stereoscopy/index.html#bpy-types-renderview"), ("bpy.types.sceneeevee*", "render/eevee/index.html#bpy-types-sceneeevee"), ("bpy.types.vectorfont*", "modeling/texts/index.html#bpy-types-vectorfont"), ("bpy.ops.curve.split*", "modeling/curves/editing/curve.html#bpy-ops-curve-split"), - ("bpy.ops.mesh.bisect*", "modeling/meshes/editing/subdividing/bisect.html#bpy-ops-mesh-bisect"), - ("bpy.ops.object.join*", "scene_layout/object/editing/introduction.html#bpy-ops-object-join"), + ("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.mesh.bisect*", "modeling/meshes/editing/mesh/bisect.html#bpy-ops-mesh-bisect"), + ("bpy.ops.mesh.delete*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-delete"), + ("bpy.ops.nla.move_up*", "editors/nla/editing.html#bpy-ops-nla-move-up"), + ("bpy.ops.object.hook*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook"), + ("bpy.ops.object.join*", "scene_layout/object/editing/join.html#bpy-ops-object-join"), ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), - ("bpy.ops.view3d.snap*", "scene_layout/object/editing/transform/control/snap.html#bpy-ops-view3d-snap"), - ("bpy.types.*texspace*", "editors/uv/generated_uvs.html#bpy-types-texspace"), + ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), + ("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"), ("bpy.types.arealight*", "render/lights/light_object.html#bpy-types-arealight"), ("bpy.types.blenddata*", "files/data_blocks.html#bpy-types-blenddata"), + ("bpy.types.bone.hide*", "animation/armatures/bones/properties/display.html#bpy-types-bone-hide"), ("bpy.types.colorramp*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp"), ("bpy.types.dopesheet*", "editors/dope_sheet/index.html#bpy-types-dopesheet"), ("bpy.types.fmodifier*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifier"), @@ -911,16 +1258,27 @@ url_manual_mapping = ( ("bpy.types.nodegroup*", "interface/controls/nodes/groups.html#bpy-types-nodegroup"), ("bpy.types.spotlight*", "render/lights/light_object.html#bpy-types-spotlight"), ("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"), ("bpy.types.uipopover*", "interface/controls/buttons/menus.html#bpy-types-uipopover"), + ("bpy.types.viewlayer*", "render/layers/layers.html#bpy-types-viewlayer"), ("bpy.ops.collection*", "scene_layout/collections/collections.html#bpy-ops-collection"), ("bpy.ops.constraint*", "animation/constraints/index.html#bpy-ops-constraint"), ("bpy.ops.curve.draw*", "modeling/curves/editing/other.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.mesh.knife*", "modeling/meshes/editing/subdividing/knife.html#bpy-ops-mesh-knife"), - ("bpy.ops.mesh.noise*", "modeling/meshes/editing/transform/noise.html#bpy-ops-mesh-noise"), - ("bpy.ops.mesh.screw*", "modeling/meshes/editing/duplicating/screw.html#bpy-ops-mesh-screw"), + ("bpy.ops.graph.bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-bake"), + ("bpy.ops.graph.copy*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-copy"), + ("bpy.ops.graph.snap*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap"), + ("bpy.ops.image.tile*", "modeling/meshes/uv/workflows/udims.html#bpy-ops-image-tile"), + ("bpy.ops.mesh.bevel*", "modeling/meshes/editing/edge/bevel.html#bpy-ops-mesh-bevel"), + ("bpy.ops.mesh.inset*", "modeling/meshes/editing/face/inset_faces.html#bpy-ops-mesh-inset"), + ("bpy.ops.mesh.knife*", "modeling/meshes/tools/knife.html#bpy-ops-mesh-knife"), + ("bpy.ops.mesh.merge*", "modeling/meshes/editing/mesh/merge.html#bpy-ops-mesh-merge"), + ("bpy.ops.mesh.screw*", "modeling/meshes/editing/edge/screw.html#bpy-ops-mesh-screw"), + ("bpy.ops.mesh.split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-split"), + ("bpy.ops.nla.delete*", "editors/nla/editing.html#bpy-ops-nla-delete"), + ("bpy.ops.paint.mask*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-paint-mask"), ("bpy.ops.safe_areas*", "render/cameras.html#bpy-ops-safe-areas"), ("bpy.types.armature*", "animation/armatures/index.html#bpy-types-armature"), ("bpy.types.editbone*", "animation/armatures/bones/editing/index.html#bpy-types-editbone"), @@ -939,27 +1297,33 @@ url_manual_mapping = ( ("bpy.types.shapekey*", "animation/shape_keys/index.html#bpy-types-shapekey"), ("bpy.types.spacenla*", "editors/nla/index.html#bpy-types-spacenla"), ("bpy.types.sunlight*", "render/lights/light_object.html#bpy-types-sunlight"), - ("bpy.ops.mesh.spin*", "modeling/meshes/editing/duplicating/spin.html#bpy-ops-mesh-spin"), + ("bpy.ops.mesh.fill*", "modeling/meshes/editing/face/fill.html#bpy-ops-mesh-fill"), + ("bpy.ops.mesh.poke*", "modeling/meshes/editing/face/poke_faces.html#bpy-ops-mesh-poke"), + ("bpy.ops.mesh.spin*", "modeling/meshes/tools/spin.html#bpy-ops-mesh-spin"), + ("bpy.ops.nla.split*", "editors/nla/editing.html#bpy-ops-nla-split"), ("bpy.ops.rigidbody*", "physics/rigid_body/index.html#bpy-ops-rigidbody"), ("bpy.ops.sequencer*", "video_editing/index.html#bpy-ops-sequencer"), ("bpy.ops.transform*", "scene_layout/object/editing/transform/index.html#bpy-ops-transform"), ("bpy.ops.uv.select*", "editors/uv/selecting.html#bpy-ops-uv-select"), - ("bpy.ops.uv.stitch*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-stitch"), - ("bpy.ops.uv.unwrap*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-unwrap"), + ("bpy.ops.uv.stitch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-stitch"), + ("bpy.ops.uv.unwrap*", "modeling/meshes/editing/uv.html#bpy-ops-uv-unwrap"), ("bpy.types.animviz*", "animation/motion_paths.html#bpy-types-animviz"), ("bpy.types.lattice*", "animation/lattice.html#bpy-types-lattice"), - ("bpy.types.library*", "files/linked_libraries.html#bpy-types-library"), + ("bpy.types.library*", "files/linked_libraries/index.html#bpy-types-library"), ("bpy.types.speaker*", "render/output/audio/speaker.html#bpy-types-speaker"), - ("bpy.types.textbox*", "modeling/texts/layout.html#bpy-types-textbox"), + ("bpy.types.textbox*", "modeling/texts/properties.html#bpy-types-textbox"), ("bpy.types.texture*", "render/materials/legacy_textures/index.html#bpy-types-texture"), ("bpy.ops.armature*", "animation/armatures/index.html#bpy-ops-armature"), ("bpy.ops.nla.bake*", "animation/actions.html#bpy-ops-nla-bake"), + ("bpy.ops.nla.snap*", "editors/nla/editing.html#bpy-ops-nla-snap"), + ("bpy.ops.nla.swap*", "editors/nla/editing.html#bpy-ops-nla-swap"), ("bpy.ops.outliner*", "editors/outliner.html#bpy-ops-outliner"), ("bpy.ops.particle*", "physics/particles/index.html#bpy-ops-particle"), - ("bpy.ops.uv.align*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-align"), - ("bpy.ops.uv.reset*", "modeling/meshes/editing/uv/unwrapping/mapping_types.html#bpy-ops-uv-reset"), + ("bpy.ops.uv.align*", "modeling/meshes/uv/editing.html#bpy-ops-uv-align"), + ("bpy.ops.uv.reset*", "modeling/meshes/editing/uv.html#bpy-ops-uv-reset"), ("bpy.ops.wm.addon*", "editors/preferences/addons.html#bpy-ops-wm-addon"), ("bpy.types.action*", "animation/actions.html#bpy-types-action"), + ("bpy.types.camera*", "render/cameras.html#bpy-types-camera"), ("bpy.types.cycles*", "render/cycles/index.html#bpy-types-cycles"), ("bpy.types.driver*", "animation/drivers/index.html#bpy-types-driver"), ("bpy.types.fcurve*", "editors/graph_editor/fcurves/index.html#bpy-types-fcurve"), @@ -970,6 +1334,7 @@ url_manual_mapping = ( ("bpy.types.sculpt*", "sculpt_paint/sculpting/index.html#bpy-types-sculpt"), ("bpy.types.shader*", "render/shader_nodes/shader/index.html#bpy-types-shader"), ("bpy.types.spline*", "modeling/curves/properties/active_spline.html#bpy-types-spline"), + ("bpy.types.volume*", "modeling/volumes/index.html#bpy-types-volume"), ("bpy.types.window*", "interface/index.html#bpy-types-window"), ("bpy.ops.buttons*", "interface/index.html#bpy-ops-buttons"), ("bpy.ops.console*", "editors/python_console.html#bpy-ops-console"), @@ -981,7 +1346,7 @@ url_manual_mapping = ( ("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"), ("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"), ("bpy.ops.texture*", "render/materials/legacy_textures/index.html#bpy-ops-texture"), - ("bpy.ops.uv.weld*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-weld"), + ("bpy.ops.uv.weld*", "modeling/meshes/uv/editing.html#bpy-ops-uv-weld"), ("bpy.ops.wm.tool*", "interface/tool_system.html#bpy-ops-wm-tool"), ("bpy.types.addon*", "editors/preferences/addons.html#bpy-types-addon"), ("bpy.types.brush*", "sculpt_paint/brush/brush.html#bpy-types-brush"), @@ -996,6 +1361,7 @@ url_manual_mapping = ( ("bpy.types.space*", "editors/index.html#bpy-types-space"), ("bpy.types.theme*", "editors/preferences/themes.html#bpy-types-theme"), ("bpy.ops.action*", "animation/actions.html#bpy-ops-action"), + ("bpy.ops.camera*", "render/cameras.html#bpy-ops-camera"), ("bpy.ops.cycles*", "render/cycles/index.html#bpy-ops-cycles"), ("bpy.ops.dpaint*", "physics/dynamic_paint/index.html#bpy-ops-dpaint"), ("bpy.ops.export*", "files/import_export.html#bpy-ops-export"), @@ -1005,7 +1371,7 @@ url_manual_mapping = ( ("bpy.ops.render*", "render/index.html#bpy-ops-render"), ("bpy.ops.script*", "advanced/scripting/index.html#bpy-ops-script"), ("bpy.ops.sculpt*", "sculpt_paint/sculpting/index.html#bpy-ops-sculpt"), - ("bpy.ops.uv.pin*", "modeling/meshes/editing/uv/layout.html#bpy-ops-uv-pin"), + ("bpy.ops.uv.pin*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pin"), ("bpy.ops.view3d*", "editors/3dview/index.html#bpy-ops-view3d"), ("bpy.types.area*", "interface/window_system/areas.html#bpy-types-area"), ("bpy.types.boid*", "physics/particles/emitter/physics/boids.html#bpy-types-boid"), @@ -1014,11 +1380,10 @@ url_manual_mapping = ( ("bpy.types.menu*", "interface/controls/buttons/menus.html#bpy-types-menu"), ("bpy.types.mesh*", "modeling/meshes/index.html#bpy-types-mesh"), ("bpy.types.pose*", "animation/armatures/posing/index.html#bpy-types-pose"), - ("bpy.types.text*", "modeling/texts/index.html#bpy-types-text"), + ("bpy.types.text*", "editors/text_editor.html#bpy-types-text"), ("bpy.ops.brush*", "sculpt_paint/brush/brush.html#bpy-ops-brush"), ("bpy.ops.cloth*", "physics/cloth/index.html#bpy-ops-cloth"), ("bpy.ops.curve*", "modeling/curves/index.html#bpy-ops-curve"), - ("bpy.ops.fluid*", "physics/fluid/index.html#bpy-ops-fluid"), ("bpy.ops.graph*", "editors/graph_editor/index.html#bpy-ops-graph"), ("bpy.ops.image*", "files/media/image_formats.html#bpy-ops-image"), ("bpy.ops.mball*", "modeling/metas/index.html#bpy-ops-mball"), diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py index 656e2b3bd54..fc3ffe4dd88 100644 --- a/release/scripts/modules/sys_info.py +++ b/release/scripts/modules/sys_info.py @@ -70,9 +70,13 @@ def write_sysinfo(filepath): output.write("build linkflags: %s\n" % prepr(bpy.app.build_linkflags)) output.write("build system: %s\n" % prepr(bpy.app.build_system)) - # python info + # Python info. output.write(title("Python")) - output.write("version: %s\n" % (sys.version)) + output.write("version: %s\n" % (sys.version.replace("\n", " "))) + output.write("file system encoding: %s:%s\n" % ( + sys.getfilesystemencoding(), + sys.getfilesystemencodeerrors(), + )) output.write("paths:\n") for p in sys.path: output.write("\t%r\n" % p) diff --git a/release/scripts/presets/gpencil_material/fill_only.py b/release/scripts/presets/gpencil_material/fill_only.py index c60811d25bc..57d5dc3b860 100644 --- a/release/scripts/presets/gpencil_material/fill_only.py +++ b/release/scripts/presets/gpencil_material/fill_only.py @@ -7,8 +7,6 @@ gpcolor.stroke_style = 'SOLID' gpcolor.color = (0.0, 0.0, 0.0, 0.0) gpcolor.stroke_image = None gpcolor.pixel_size = 100.0 -gpcolor.use_stroke_pattern = False -gpcolor.use_stroke_texture_mix = False gpcolor.mix_stroke_factor = 0.0 gpcolor.alignment_mode = 'PATH' gpcolor.fill_style = 'SOLID' @@ -18,18 +16,11 @@ gpcolor.gradient_type = 'LINEAR' gpcolor.mix_color = (1.0, 1.0, 1.0, 0.2) gpcolor.mix_factor = 0.0 gpcolor.flip = False -gpcolor.pattern_shift = (0.0, 0.0) -gpcolor.pattern_scale = (1.0, 1.0) -gpcolor.pattern_radius = 0.5 -gpcolor.pattern_angle = 0.0 -gpcolor.pattern_gridsize = 0.1 -gpcolor.use_fill_pattern = False gpcolor.texture_offset = (0.0, 0.0) gpcolor.texture_scale = (1.0, 1.0) gpcolor.texture_angle = 0.0 gpcolor.texture_opacity = 1.0 gpcolor.texture_clamp = False -gpcolor.use_fill_texture_mix = False gpcolor.mix_factor = 0.0 gpcolor.show_stroke = False gpcolor.show_fill = True diff --git a/release/scripts/presets/gpencil_material/stroke_and_fill.py b/release/scripts/presets/gpencil_material/stroke_and_fill.py index ee18eeb0114..eff728a7857 100644 --- a/release/scripts/presets/gpencil_material/stroke_and_fill.py +++ b/release/scripts/presets/gpencil_material/stroke_and_fill.py @@ -7,8 +7,6 @@ gpcolor.stroke_style = 'SOLID' gpcolor.color = (0.0, 0.0, 0.0, 1.0) gpcolor.stroke_image = None gpcolor.pixel_size = 100.0 -gpcolor.use_stroke_pattern = False -gpcolor.use_stroke_texture_mix = False gpcolor.mix_stroke_factor = 0.0 gpcolor.alignment_mode = 'PATH' gpcolor.fill_style = 'SOLID' @@ -18,18 +16,11 @@ gpcolor.gradient_type = 'LINEAR' gpcolor.mix_color = (1.0, 1.0, 1.0, 0.2) gpcolor.mix_factor = 0.0 gpcolor.flip = False -gpcolor.pattern_shift = (0.0, 0.0) -gpcolor.pattern_scale = (1.0, 1.0) -gpcolor.pattern_radius = 0.5 -gpcolor.pattern_angle = 0.0 -gpcolor.pattern_gridsize = 0.1 -gpcolor.use_fill_pattern = False gpcolor.texture_offset = (0.0, 0.0) gpcolor.texture_scale = (1.0, 1.0) gpcolor.texture_angle = 0.0 gpcolor.texture_opacity = 1.0 gpcolor.texture_clamp = False -gpcolor.use_fill_texture_mix = False gpcolor.mix_factor = 0.0 gpcolor.show_stroke = True gpcolor.show_fill = True diff --git a/release/scripts/presets/gpencil_material/stroke_only.py b/release/scripts/presets/gpencil_material/stroke_only.py index 3ca05c6a073..1724a62bffc 100644 --- a/release/scripts/presets/gpencil_material/stroke_only.py +++ b/release/scripts/presets/gpencil_material/stroke_only.py @@ -7,8 +7,6 @@ gpcolor.stroke_style = 'SOLID' gpcolor.color = (0.0, 0.0, 0.0, 1.0) gpcolor.stroke_image = None gpcolor.pixel_size = 100.0 -gpcolor.use_stroke_pattern = False -gpcolor.use_stroke_texture_mix = False gpcolor.mix_stroke_factor = 0.0 gpcolor.alignment_mode = 'PATH' gpcolor.fill_style = 'SOLID' @@ -18,18 +16,11 @@ gpcolor.gradient_type = 'LINEAR' gpcolor.mix_color = (1.0, 1.0, 1.0, 0.2) gpcolor.mix_factor = 0.0 gpcolor.flip = False -gpcolor.pattern_shift = (0.0, 0.0) -gpcolor.pattern_scale = (1.0, 1.0) -gpcolor.pattern_radius = 0.5 -gpcolor.pattern_angle = 0.0 -gpcolor.pattern_gridsize = 0.1 -gpcolor.use_fill_pattern = False gpcolor.texture_offset = (0.0, 0.0) gpcolor.texture_scale = (1.0, 1.0) gpcolor.texture_angle = 0.0 gpcolor.texture_opacity = 1.0 gpcolor.texture_clamp = False -gpcolor.use_fill_texture_mix = False gpcolor.mix_factor = 0.0 gpcolor.show_stroke = True gpcolor.show_fill = False diff --git a/release/scripts/presets/interface_theme/blender_light.xml b/release/scripts/presets/interface_theme/blender_light.xml index dee7d2d2c59..48ad0a8367e 100644 --- a/release/scripts/presets/interface_theme/blender_light.xml +++ b/release/scripts/presets/interface_theme/blender_light.xml @@ -8,12 +8,14 @@ icon_saturation="0.5" widget_emboss="#00000005" editor_outline="#1f1f1f" + widget_text_cursor="#3399e6" axis_x="#ff3352" axis_y="#8bdc00" axis_z="#2890ff" gizmo_hi="#ffffff" gizmo_primary="#f5f14d" gizmo_secondary="#63ffff" + gizmo_view_align="#ffffff" gizmo_a="#4da84d" gizmo_b="#a33535" icon_scene="#e6e6e6ff" @@ -377,6 +379,8 @@ face_dot="#ff8500" facedot_size="4" freestyle_face_mark="#7fff7f33" + face_back="#ff0000b3" + face_front="#0000ffb3" nurb_uline="#909000" nurb_vline="#803060" nurb_sel_uline="#f0ff40" @@ -402,6 +406,7 @@ bone_pose="#50c8ff" bone_pose_active="#8cffff" bone_solid="#e6e6e6" + bone_locked_weight="#ff000080" bundle_solid="#c8c8c8" camera_path="#000000" skin_root="#b44d4d" @@ -434,7 +439,7 @@ > <gradients> <ThemeGradientColors - show_grad="FALSE" + background_type="SINGLE_COLOR" high_gradient="#646464" gradient="#646464" > @@ -457,6 +462,8 @@ grid="#5e5e5e" frame_current="#5680c2" time_scrub_background="#808080e6" + time_marker_line="#00000060" + time_marker_line_selected="#ffffff60" window_sliders="#969696" channels_region="#999999" dopesheet_channel="#2e6399" @@ -565,6 +572,8 @@ <ThemeNLAEditor grid="#5e5e5e" view_sliders="#969696" + dopesheet_channel="#5a85b2" + nla_track="#424242" active_action="#cc701a66" active_action_unset="#9987614d" preview_range="#a14d0066" @@ -582,6 +591,8 @@ keyframe_border_selected="#000000ff" frame_current="#5680c2" time_scrub_background="#808080e6" + time_marker_line="#00000060" + time_marker_line_selected="#ffffff60" > <space> <ThemeSpaceGeneric @@ -629,6 +640,8 @@ grid="#4d4d4d" frame_current="#5680c2" time_scrub_background="#808080e6" + time_marker_line="#00000060" + time_marker_line_selected="#ffffff60" value_sliders="#000000" view_sliders="#969696" dopesheet_channel="#2e639924" @@ -709,7 +722,9 @@ face_dot="#ff8500" facedot_size="3" freestyle_face_mark="#7fff7f33" - editmesh_active="#ffffff80" + face_back="#00000000" + face_front="#00000000" + editmesh_active="#ffffff40" wire_edit="#c0c0c0" edge_select="#ff8500" scope_back="#727272ff" @@ -774,22 +789,28 @@ <ThemeSequenceEditor grid="#404040" window_sliders="#a0a0a0" - movie_strip="#516987" - movieclip_strip="#20208f" - image_strip="#6d5881" - scene_strip="#4e983e" - audio_strip="#2e8f8f" - effect_strip="#a9547c" - transition_strip="#a25f6f" - meta_strip="#6d9183" - text_strip="#a29700" + movie_strip="#4d6890" + movieclip_strip="#8f4c4c" + image_strip="#8f744b" + scene_strip="#828f50" + audio_strip="#4c8f8f" + effect_strip="#4c456c" + color_strip="#8f8f8f" + meta_strip="#5b4d91" + mask_strip="#8f5656" + text_strip="#824c8f" + active_strip="#d9d9d9" + selected_strip="#ff6a00" frame_current="#5680c2" time_scrub_background="#292929e6" + time_marker_line="#00000060" + time_marker_line_selected="#ffffff60" keyframe="#ff8500" draw_action="#50c8ff" preview_back="#000000" metadatabg="#000000" metadatatext="#ffffff" + preview_range="#a14d0066" > <space> <ThemeSpaceGeneric @@ -859,6 +880,7 @@ </properties> <text_editor> <ThemeTextEditor + line_numbers="#d0d0d0" line_numbers_background="#313133" selected_text="#19191a" cursor="#ff0000" @@ -920,6 +942,7 @@ matte_node="#977474" distor_node="#749797" noodle_curving="0" + grid_levels="2" input_node="#ff6675" output_node="#ff6675" filter_node="#6c696f" @@ -1017,14 +1040,18 @@ <ThemeInfo info_selected="#6080ff" info_selected_text="#ffffff" - info_error="#990000" + info_error="#990000ff" info_error_text="#ffffff" - info_warning="#b36a00" + info_warning="#b36a00ff" info_warning_text="#ffffff" - info_info="#1d4383" + info_info="#1d4383ff" info_info_text="#ffffff" - info_debug="#d3d3d3" + info_debug="#d3d3d3ff" info_debug_text="#000000" + info_property="#3ace87ff" + info_property_text="#ffffff" + info_operator="#3ace87ff" + info_operator_text="#ffffff" > <space> <ThemeSpaceGeneric @@ -1143,8 +1170,12 @@ locked_marker="#7f7f7f" path_before="#ff0000" path_after="#0000ff" + path_keyframe_before="#ffc4c4" + path_keyframe_after="#c4c4ff" frame_current="#5680c2" time_scrub_background="#292929e6" + time_marker_line="#00000060" + time_marker_line_selected="#ffffff60" strips="#0c0a0a" strips_selected="#ff8c00" metadatabg="#000000" diff --git a/release/scripts/presets/keyconfig/blender.py b/release/scripts/presets/keyconfig/blender.py index 11cd76335f1..0bff9974aaa 100644 --- a/release/scripts/presets/keyconfig/blender.py +++ b/release/scripts/presets/keyconfig/blender.py @@ -108,6 +108,38 @@ class Prefs(bpy.types.KeyConfigPreferences): update=update_fn, ) + v3d_mmb_action: EnumProperty( + name="MMB Action", + items=( + ('ORBIT', "Orbit", + "Orbit", + 0), + ('PAN', "Pan", + "Set the view axis where each mouse direction always maps to the same axis", + 1), + ), + description=( + "The action when Middle-Mouse dragging in the viewport. Shift-Middle-Mouse is used for the other action" + ), + update=update_fn, + ) + + v3d_alt_mmb_drag_action: EnumProperty( + name="Alt-MMB Drag Action", + items=( + ('RELATIVE', "Relative", + "Set the view axis where each mouse direction maps to an axis relative to the current orientation", + 0), + ('ABSOLUTE', "Absolute", + "Set the view axis where each mouse direction always maps to the same axis", + 1), + ), + description=( + "Action when Alt-MMB dragging in the 3D viewport" + ), + update=update_fn, + ) + # Developer note, this is an experemental option. use_pie_click_drag: BoolProperty( name="Pie Menu on Drag", @@ -124,35 +156,35 @@ class Prefs(bpy.types.KeyConfigPreferences): ) def draw(self, layout): - is_select_left = (self.select_mouse == 'LEFT') + layout.use_property_split = True - split = layout.split() - col = split.column(align=True) - col.label(text="Select With:") - col.row().prop(self, "select_mouse", expand=True) + is_select_left = (self.select_mouse == 'LEFT') + # General settings. + col = layout.column() + col.row().prop(self, "select_mouse", text="Select with Mouse Button", expand=True) + col.row().prop(self, "spacebar_action", text="Spacebar Action", expand=True) if is_select_left: - col.label(text="Activate Gizmo:") - col.row().prop(self, "gizmo_action", expand=True) - else: - col.label() - col.label() + col.row().prop(self, "gizmo_action", text="Activate Gizmo Event", expand=True) - col.prop(self, "use_select_all_toggle") + # Checkboxes sub-layout. + col = layout.column() + sub = col.column(align=True) + sub.prop(self, "use_select_all_toggle") - col = split.column(align=True) - col.label(text="Spacebar Action:") - col.row().prop(self, "spacebar_action", expand=True) + # 3DView settings. + col = layout.column() + col.label(text="3D View") + col.row().prop(self, "v3d_tilde_action", text="Grave Accent / Tilde Action", expand=True) + col.row().prop(self, "v3d_mmb_action", text="Middle Mouse Action", expand=True) + col.row().prop(self, "v3d_alt_mmb_drag_action", text="Alt Middle Mouse Drag Action", expand=True) - layout.label(text="3D View:") - split = layout.split() - col = split.column() - col.prop(self, "use_v3d_tab_menu") - col.prop(self, "use_pie_click_drag") - col = split.column() - col.label(text="Tilde Action:") - col.row().prop(self, "v3d_tilde_action", expand=True) - col.prop(self, "use_v3d_shade_ex_pie") + # Checkboxes sub-layout. + col = layout.column() + sub = col.column(align=True) + sub.prop(self, "use_v3d_tab_menu") + sub.prop(self, "use_pie_click_drag") + sub.prop(self, "use_v3d_shade_ex_pie") blender_default = bpy.utils.execfile(os.path.join(DIRNAME, "keymap_data", "blender_default.py")) @@ -176,6 +208,8 @@ def load(): ), spacebar_action=kc_prefs.spacebar_action, v3d_tilde_action=kc_prefs.v3d_tilde_action, + use_v3d_mmb_pan=(kc_prefs.v3d_mmb_action == 'PAN'), + v3d_alt_mmb_drag_action=kc_prefs.v3d_alt_mmb_drag_action, use_select_all_toggle=kc_prefs.use_select_all_toggle, use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu, use_v3d_shade_ex_pie=kc_prefs.use_v3d_shade_ex_pie, diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 629bc24abb3..614a76c3994 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -50,9 +50,13 @@ class Params: "use_v3d_tab_menu", # Use extended pie menu for shading. "use_v3d_shade_ex_pie", + # Swap orbit/pan keys (for 2D workflows). + "use_v3d_mmb_pan", # Experimental option. "use_pie_click_drag", "v3d_tilde_action", + # Alt-MMB axis switching 'RELATIVE' or 'ABSOLUTE' axis switching. + "v3d_alt_mmb_drag_action", ) def __init__( @@ -68,8 +72,10 @@ class Params: use_gizmo_drag=True, use_v3d_tab_menu=False, use_v3d_shade_ex_pie=False, + use_v3d_mmb_pan=False, use_pie_click_drag=False, v3d_tilde_action='VIEW', + v3d_alt_mmb_drag_action='RELATIVE', ): from sys import platform self.apple = (platform == 'darwin') @@ -116,7 +122,9 @@ class Params: self.use_select_all_toggle = use_select_all_toggle self.use_v3d_tab_menu = use_v3d_tab_menu self.use_v3d_shade_ex_pie = use_v3d_shade_ex_pie + self.use_v3d_mmb_pan = use_v3d_mmb_pan self.v3d_tilde_action = v3d_tilde_action + self.v3d_alt_mmb_drag_action = v3d_alt_mmb_drag_action self.use_pie_click_drag = use_pie_click_drag if not use_pie_click_drag: @@ -288,6 +296,17 @@ def _template_items_proportional_editing(*, connected=False): ] +def _template_items_change_frame(params): + if params.select_mouse == 'LEFTMOUSE' and not params.legacy: + return [ + ("anim.change_frame", {"type": 'RIGHTMOUSE', "value": 'PRESS', "shift": True}, None), + ] + else: + return [ + ("anim.change_frame", {"type": params.action_mouse, "value": 'PRESS'}, None), + ] + + # Tool System Templates def _template_items_tool_select(params, operator, cursor_operator, *, extend): @@ -755,7 +774,9 @@ def km_outliner(params): {"properties": [("all", True)]}), ("outliner.item_openclose", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties": [("all", False)]}), + # Fall through to generic context menu if the item(s) selected have no type specific actions. ("outliner.operation", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, None), + op_menu("OUTLINER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), ("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True}, None), ("outliner.show_hierarchy", {"type": 'HOME', "value": 'PRESS'}, None), @@ -777,8 +798,8 @@ def km_outliner(params): ("outliner.drivers_add_selected", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), ("outliner.drivers_delete_selected", {"type": 'D', "value": 'PRESS', "ctrl": True, "alt": True}, None), ("outliner.collection_new", {"type": 'C', "value": 'PRESS'}, None), - ("outliner.collection_delete", {"type": 'X', "value": 'PRESS'}, None), - ("outliner.collection_delete", {"type": 'DEL', "value": 'PRESS'}, None), + ("outliner.delete", {"type": 'X', "value": 'PRESS'}, None), + ("outliner.delete", {"type": 'DEL', "value": 'PRESS'}, None), ("object.move_to_collection", {"type": 'M', "value": 'PRESS'}, None), ("object.link_to_collection", {"type": 'M', "value": 'PRESS', "shift": True}, None), ("outliner.collection_exclude_set", {"type": 'E', "value": 'PRESS'}, None), @@ -847,12 +868,12 @@ def km_uv_editor(params): op_menu_pie("IMAGE_MT_uvs_snap_pie", {"type": 'S', "value": 'PRESS', "shift": True}), op_menu("IMAGE_MT_uvs_select_mode", {"type": 'TAB', "value": 'PRESS', "ctrl": True}), *_template_items_proportional_editing(connected=False), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), - ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), - ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": False}, None), + ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True, "repeat": False}, None), ("wm.context_toggle", {"type": 'TAB', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.use_snap')]}), ("wm.context_menu_enum", {"type": 'TAB', "value": 'PRESS', "shift": True, "ctrl": True}, @@ -945,8 +966,13 @@ def km_view3d(params): ("view3d.localview", {"type": 'MOUSESMARTZOOM', "value": 'ANY'}, None), ("view3d.localview_remove_from", {"type": 'M', "value": 'PRESS'}, None), # Navigation. - ("view3d.rotate", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), - ("view3d.move", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), + *(( + ("view3d.rotate", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), + ("view3d.move", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), + ) if params.use_v3d_mmb_pan else ( + ("view3d.rotate", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), + ("view3d.move", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), + )), ("view3d.zoom", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "ctrl": True}, None), ("view3d.dolly", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("view3d.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS', "ctrl": True}, @@ -1043,14 +1069,30 @@ def km_view3d(params): {"properties": [("type", 'LEFT'), ("align_active", True)]}), ("view3d.view_axis", {"type": 'NUMPAD_7', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'BOTTOM'), ("align_active", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH', "alt": True}, - {"properties": [("type", 'TOP'), ("relative", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'SOUTH', "alt": True}, - {"properties": [("type", 'BOTTOM'), ("relative", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'EAST', "alt": True}, - {"properties": [("type", 'RIGHT'), ("relative", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'WEST', "alt": True}, - {"properties": [("type", 'LEFT'), ("relative", True)]}), + *(( + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH', "alt": True}, + {"properties": [("type", 'TOP'), ("relative", True)]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'SOUTH', "alt": True}, + {"properties": [("type", 'BOTTOM'), ("relative", True)]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'EAST', "alt": True}, + {"properties": [("type", 'RIGHT'), ("relative", True)]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'WEST', "alt": True}, + {"properties": [("type", 'LEFT'), ("relative", True)]}), + ) if params.v3d_alt_mmb_drag_action == 'RELATIVE' else ( + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH', "alt": True}, + {"properties": [("type", 'TOP')]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'SOUTH', "alt": True}, + {"properties": [("type", 'BOTTOM')]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'EAST', "alt": True}, + {"properties": [("type", 'RIGHT')]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'WEST', "alt": True}, + {"properties": [("type", 'LEFT')]}), + # Match the pie menu. + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH_WEST', "alt": True}, + {"properties": [("type", 'FRONT')]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH_EAST', "alt": True}, + {"properties": [("type", 'BACK')]}), + )), ("view3d.view_center_pick", {"type": 'MIDDLEMOUSE', "value": 'CLICK', "alt": True}, None), ("view3d.ndof_orbit_zoom", {"type": 'NDOF_MOTION', "value": 'ANY'}, None), ("view3d.ndof_orbit", {"type": 'NDOF_MOTION', "value": 'ANY', "ctrl": True}, None), @@ -1113,19 +1155,19 @@ def km_view3d(params): ("view3d.copybuffer", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("view3d.pastebuffer", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), # Transform. - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), - ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True}, None), - ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), - ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), - ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True, "repeat": False}, None), + ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": False}, None), + ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True, "repeat": False}, None), ("wm.context_toggle", {"type": 'TAB', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.use_snap')]}), op_panel("VIEW3D_PT_snapping", {"type": 'TAB', "value": 'PRESS', "shift": True, "ctrl": True}, [("keep_open", False)]), ("object.transform_axis_target", {"type": 'T', "value": 'PRESS', "shift": True}, None), - ("transform.skin_resize", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), + ("transform.skin_resize", {"type": 'A', "value": 'PRESS', "ctrl": True, "repeat": False}, None), ]) if not params.legacy: @@ -1181,9 +1223,9 @@ def km_view3d(params): {"properties": [("type", 'RIGHT')]}), ("transform.create_orientation", {"type": 'SPACE', "value": 'PRESS', "ctrl": True, "alt": True}, {"properties": [("use", True)]}), - ("transform.translate", {"type": 'T', "value": 'PRESS', "shift": True}, + ("transform.translate", {"type": 'T', "value": 'PRESS', "shift": True, "repeat": False}, {"properties": [("texture_space", True)]}), - ("transform.resize", {"type": 'T', "value": 'PRESS', "shift": True, "alt": True}, + ("transform.resize", {"type": 'T', "value": 'PRESS', "shift": True, "alt": True, "repeat": False}, {"properties": [("texture_space", True)]}), # Old pivot. ("wm.context_set_enum", {"type": 'COMMA', "value": 'PRESS'}, @@ -1232,8 +1274,9 @@ def km_mask_editing(params): # click select keymap it's fine to have the context menu instead. items.extend([ ("mask.select", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, - {"properties": [("extend", False), ("deselect", False), ("toggle", False), - ("deselect_all", not params.legacy)]}), + {"properties": [ + ("extend", False), ("deselect", False), ("toggle", False), + ("deselect_all", not params.legacy)]}), ("transform.translate", {"type": 'EVT_TWEAK_R', "value": 'ANY'}, None), ]) @@ -1282,10 +1325,10 @@ def km_mask_editing(params): ("mask.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None), ("mask.copy_splines", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("mask.paste_splines", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, {"properties": [("mode", 'MASK_SHRINKFATTEN')]}), ]) @@ -1348,7 +1391,6 @@ def km_time_scrub(_params): items.extend([ ("anim.change_frame", {"type": "LEFTMOUSE", "value": 'PRESS'}, None), - ("graph.cursor_set", {"type": "LEFTMOUSE", "value": 'PRESS'}, None), ]) return keymap @@ -1406,8 +1448,9 @@ def km_graph_editor(params): ("wm.context_toggle", {"type": 'H', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'space_data.show_handles')]}), ("graph.clickselect", {"type": params.select_mouse, "value": 'PRESS'}, - {"properties": [("extend", False), ("deselect_all", not params.legacy), - ("column", False), ("curves", False)]}), + {"properties": [ + ("extend", False), ("deselect_all", not params.legacy), + ("column", False), ("curves", False)]}), ("graph.clickselect", {"type": params.select_mouse, "value": 'PRESS', "alt": True}, {"properties": [("extend", False), ("column", True), ("curves", False)]}), ("graph.clickselect", {"type": params.select_mouse, "value": 'PRESS', "shift": True}, @@ -1429,8 +1472,7 @@ def km_graph_editor(params): ("graph.select_leftright", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("mode", 'RIGHT'), ("extend", False)]}), *_template_items_select_actions(params, "graph.select_all"), - ("graph.select_box", {"type": 'B', "value": 'PRESS'}, - {"properties": [("axis_range", False)]}), + ("graph.select_box", {"type": 'B', "value": 'PRESS'}, None), ("graph.select_box", {"type": 'B', "value": 'PRESS', "alt": True}, {"properties": [("axis_range", True)]}), ("graph.select_box", {"type": params.select_tweak, "value": 'ANY'}, @@ -1484,12 +1526,12 @@ def km_graph_editor(params): ("graph.fmodifier_add", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("only_active", False)]}), ("anim.channels_editable_toggle", {"type": 'TAB', "value": 'PRESS'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.transform", {"type": 'E', "value": 'PRESS'}, + ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TIME_EXTEND')]}), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), ("wm.context_toggle", {"type": 'O', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.use_proportional_fcurve')]}), op_menu_pie("VIEW3D_MT_proportional_editing_falloff_pie", {"type": 'O', "value": 'PRESS', "shift": True}), @@ -1740,13 +1782,13 @@ def km_node_editor(params): ("node.translate_attach", {"type": 'G', "value": 'PRESS'}, None), ("node.translate_attach", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), ("node.translate_attach", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties": [("release_confirm", True)]}), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, {"properties": [("release_confirm", True)]}), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), ("node.move_detach_links", {"type": 'D', "value": 'PRESS', "alt": True}, None), ("node.move_detach_links_release", {"type": params.action_tweak, "value": 'ANY', "alt": True}, None), ("node.move_detach_links", {"type": params.select_tweak, "value": 'ANY', "alt": True}, None), @@ -1816,6 +1858,7 @@ def km_file_browser(params): ("file.delete", {"type": 'DEL', "value": 'PRESS'}, None), ("file.smoothscroll", {"type": 'TIMER1', "value": 'ANY', "any": True}, None), ("file.bookmark_add", {"type": 'B', "value": 'PRESS', "ctrl": True}, None), + ("file.start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None), ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, {"properties": [("increment", 1)]}), ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True}, @@ -1932,7 +1975,8 @@ def km_dopesheet_generic(_params): sidebar_key={"type": 'N', "value": 'PRESS'}, ), ("wm.context_set_enum", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, - {"properties": [("data_path", 'area.type'), ("value", 'GRAPH_EDITOR')]}) + {"properties": [("data_path", 'area.type'), ("value", 'GRAPH_EDITOR')]}), + ("action.extrapolation_type", {"type": 'E', "value": 'PRESS', "shift": True}, None), ]) return keymap @@ -1948,8 +1992,9 @@ def km_dopesheet(params): items.extend([ ("action.clickselect", {"type": params.select_mouse, "value": 'PRESS'}, - {"properties": [("extend", False), ("deselect_all", not params.legacy), - ("column", False), ("channel", False)]}), + {"properties": [ + ("extend", False), ("deselect_all", not params.legacy), + ("column", False), ("channel", False)]}), ("action.clickselect", {"type": params.select_mouse, "value": 'PRESS', "alt": True}, {"properties": [("extend", False), ("column", True), ("channel", False)]}), ("action.clickselect", {"type": params.select_mouse, "value": 'PRESS', "shift": True}, @@ -2003,6 +2048,7 @@ def km_dopesheet(params): ("action.handle_type", {"type": 'V', "value": 'PRESS'}, None), ("action.interpolation_type", {"type": 'T', "value": 'PRESS'}, None), ("action.extrapolation_type", {"type": 'E', "value": 'PRESS', "shift": True}, None), + ("action.easing_type", {"type": 'E', "value": 'PRESS', "ctrl": True}, None), ("action.keyframe_type", {"type": 'R', "value": 'PRESS'}, None), ("action.sample", {"type": 'O', "value": 'PRESS', "shift": True, "alt": True}, None), op_menu("DOPESHEET_MT_delete", {"type": 'X', "value": 'PRESS'}), @@ -2020,15 +2066,15 @@ def km_dopesheet(params): ("action.view_frame", {"type": 'NUMPAD_0', "value": 'PRESS'}, None), ("anim.channels_editable_toggle", {"type": 'TAB', "value": 'PRESS'}, None), ("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None), - ("transform.transform", {"type": 'G', "value": 'PRESS'}, + ("transform.transform", {"type": 'G', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TIME_TRANSLATE')]}), ("transform.transform", {"type": params.select_tweak, "value": 'ANY'}, {"properties": [("mode", 'TIME_TRANSLATE')]}), - ("transform.transform", {"type": 'E', "value": 'PRESS'}, + ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TIME_EXTEND')]}), - ("transform.transform", {"type": 'S', "value": 'PRESS'}, + ("transform.transform", {"type": 'S', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TIME_SCALE')]}), - ("transform.transform", {"type": 'T', "value": 'PRESS', "shift": True}, + ("transform.transform", {"type": 'T', "value": 'PRESS', "shift": True, "repeat": False}, {"properties": [("mode", 'TIME_SLIDE')]}), ("wm.context_toggle", {"type": 'O', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.use_proportional_action')]}), @@ -2037,6 +2083,7 @@ def km_dopesheet(params): ("marker.rename", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), ("marker.camera_bind", {"type": 'B', "value": 'PRESS', "ctrl": True}, None), *_template_items_context_menu("DOPESHEET_MT_context_menu", params.context_menu_event), + *_template_items_change_frame(params), ]) return keymap @@ -2151,17 +2198,18 @@ def km_nla_editor(params): ("nla.clear_scale", {"type": 'S', "value": 'PRESS', "alt": True}, None), op_menu_pie("NLA_MT_snap_pie", {"type": 'S', "value": 'PRESS', "shift": True}), ("nla.fmodifier_add", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None), - ("transform.transform", {"type": 'G', "value": 'PRESS'}, + ("transform.transform", {"type": 'G', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TRANSLATION')]}), ("transform.transform", {"type": params.select_tweak, "value": 'ANY'}, {"properties": [("mode", 'TRANSLATION')]}), - ("transform.transform", {"type": 'E', "value": 'PRESS'}, + ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TIME_EXTEND')]}), - ("transform.transform", {"type": 'S', "value": 'PRESS'}, + ("transform.transform", {"type": 'S', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TIME_SCALE')]}), ("marker.add", {"type": 'M', "value": 'PRESS'}, None), ("marker.rename", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), *_template_items_context_menu("NLA_MT_context_menu", params.context_menu_event), + *_template_items_change_frame(params), ]) return keymap @@ -2313,6 +2361,7 @@ def km_text(params): ("text.scroll", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ("text.selection_set", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), ("text.cursor_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), + ("text.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, None), ("text.scroll", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, {"properties": [("lines", -1)]}), ("text.scroll", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, @@ -2365,9 +2414,9 @@ def km_sequencer(params): items.extend([ *_template_items_select_actions(params, "sequencer.select_all"), - ("sequencer.cut", {"type": 'K', "value": 'PRESS'}, + ("sequencer.split", {"type": 'K', "value": 'PRESS'}, {"properties": [("type", 'SOFT')]}), - ("sequencer.cut", {"type": 'K', "value": 'PRESS', "shift": True}, + ("sequencer.split", {"type": 'K', "value": 'PRESS', "shift": True}, {"properties": [("type", 'HARD')]}), ("sequencer.mute", {"type": 'H', "value": 'PRESS'}, {"properties": [("unselected", False)]}), @@ -2418,15 +2467,16 @@ def km_sequencer(params): ("sequencer.snap", {"type": 'S', "value": 'PRESS', "shift": True}, None), ("sequencer.swap_inputs", {"type": 'S', "value": 'PRESS', "alt": True}, None), *( - (("sequencer.cut_multicam", + (("sequencer.split_multicam", {"type": NUMBERS_1[i], "value": 'PRESS'}, {"properties": [("camera", i + 1)]}) for i in range(10) ) ), ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'}, - {"properties": [("extend", False), ("deselect_all", True), - ("linked_handle", False), ("left_right", 'NONE'), ("linked_time", False)]}), + {"properties": [ + ("extend", False), ("deselect_all", True), + ("linked_handle", False), ("left_right", 'NONE'), ("linked_time", False)]}), ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS', "shift": True}, {"properties": [("extend", True), ("linked_handle", False), ("left_right", 'NONE'), ("linked_time", False)]}), ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS', "alt": True}, @@ -2453,15 +2503,17 @@ def km_sequencer(params): ("sequencer.select_box", {"type": params.select_tweak, "value": 'ANY', "ctrl": True}, {"properties": [("tweak", True), ("mode", 'SUB')]}), ("sequencer.select_box", {"type": 'B', "value": 'PRESS'}, None), + ("sequencer.select_box", {"type": 'B', "value": 'PRESS', "ctrl": True}, + {"properties": [("include_handles", True)]}), ("sequencer.select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}, None), op_menu("SEQUENCER_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}), op_menu("SEQUENCER_MT_change", {"type": 'C', "value": 'PRESS'}), ("sequencer.slip", {"type": 'S', "value": 'PRESS'}, None), ("wm.context_set_int", {"type": 'O', "value": 'PRESS'}, {"properties": [("data_path", 'scene.sequence_editor.overlay_frame'), ("value", 0)]}), - ("transform.seq_slide", {"type": 'G', "value": 'PRESS'}, None), + ("transform.seq_slide", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.seq_slide", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.transform", {"type": 'E', "value": 'PRESS'}, + ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, {"properties": [("mode", 'TIME_EXTEND')]}), ("marker.add", {"type": 'M', "value": 'PRESS'}, None), ("marker.rename", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), @@ -2700,10 +2752,10 @@ def km_clip_editor(params): {"properties": [("data_path", 'space_data.show_marker_search')]}), ("wm.context_toggle", {"type": 'M', "value": 'PRESS'}, {"properties": [("data_path", 'space_data.use_mute_footage')]}), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), ("clip.clear_track_path", {"type": 'T', "value": 'PRESS', "alt": True}, {"properties": [("action", 'REMAINED'), ("clear_active", False)]}), ("clip.clear_track_path", {"type": 'T', "value": 'PRESS', "shift": True}, @@ -2757,10 +2809,10 @@ def km_clip_graph_editor(params): {"properties": [("action", 'ALL'), ("clear_active", True)]}), ("clip.graph_disable_markers", {"type": 'D', "value": 'PRESS', "shift": True}, {"properties": [("action", 'TOGGLE')]}), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), ]) if params.select_mouse == 'LEFTMOUSE' and not params.legacy: @@ -2890,15 +2942,6 @@ def km_animation(params): ("anim.end_frame_set", {"type": 'END', "value": 'PRESS', "ctrl": True}, None), ]) - if params.select_mouse == 'LEFTMOUSE' and not params.legacy: - items.extend([ - ("anim.change_frame", {"type": 'RIGHTMOUSE', "value": 'PRESS', "shift": True}, None), - ]) - else: - items.extend([ - ("anim.change_frame", {"type": params.action_mouse, "value": 'PRESS'}, None), - ]) - return keymap @@ -2984,6 +3027,8 @@ def km_grease_pencil(_params): # Draw ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "key_modifier": 'D'}, {"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}), + ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "key_modifier": 'D', "shift": True}, + {"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}), # Draw - straight lines ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True, "key_modifier": 'D'}, {"properties": [("mode", 'DRAW_STRAIGHT'), ("wait_for_input", False)]}), @@ -3108,17 +3153,17 @@ def km_grease_pencil_stroke_edit_mode(params): # Move to layer op_menu("GPENCIL_MT_move_to_layer", {"type": 'M', "value": 'PRESS'}), # Transform tools - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), - ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), - ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True}, None), - ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), - ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True, "repeat": False}, None), + ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True, "repeat": False}, None), + ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": False}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, {"properties": [("mode", 'GPENCIL_SHRINKFATTEN')]}), - ("transform.transform", {"type": 'F', "value": 'PRESS', "shift": True}, + ("transform.transform", {"type": 'F', "value": 'PRESS', "shift": True, "repeat": False}, {"properties": [("mode", 'GPENCIL_OPACITY')]}), # Proportional editing. *_template_items_proportional_editing(connected=True), @@ -3133,6 +3178,10 @@ def km_grease_pencil_stroke_edit_mode(params): {"properties": [("mode", 1)]}), ("gpencil.selectmode_toggle", {"type": 'THREE', "value": 'PRESS'}, {"properties": [("mode", 2)]}), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Context menu *_template_items_context_menu("VIEW3D_MT_gpencil_edit_context_menu", params.context_menu_event), ]) @@ -3176,6 +3225,12 @@ def km_grease_pencil_stroke_paint_mode(params): {"properties": [("unselected", False)]}), ("gpencil.hide", {"type": 'H', "value": 'PRESS', "shift": True}, {"properties": [("unselected", True)]}), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Active material + op_menu("GPENCIL_MT_material_active", {"type": 'U', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Draw context menu *_template_items_context_panel("VIEW3D_PT_gpencil_draw_context_menu", params.context_menu_event), ]) @@ -3287,6 +3342,25 @@ def km_grease_pencil_stroke_paint_fill(params): return keymap +def km_grease_pencil_stroke_paint_tint(params): + items = [] + keymap = ( + "Grease Pencil Stroke Paint (Tint)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + def km_grease_pencil_stroke_sculpt_mode(params): items = [] keymap = ( @@ -3301,14 +3375,22 @@ def km_grease_pencil_stroke_sculpt_mode(params): # Brush strength ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.strength')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.strength')]}), # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.size')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.size')]}), # Copy ("gpencil.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), # Display *_grease_pencil_display(), + # Keyframe menu + ("gpencil.blank_frame_add", {"type": 'I', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'X', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Context menu *_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event), ]) @@ -3316,28 +3398,382 @@ def km_grease_pencil_stroke_sculpt_mode(params): return keymap -def km_grease_pencil_stroke_weight_mode(_params): +def km_grease_pencil_stroke_sculpt_smooth(_params): items = [] keymap = ( - "Grease Pencil Stroke Weight Mode", + "Grease Pencil Stroke Sculpt (Smooth)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_thickness(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Thickness)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_strength(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Strength)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_grab(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Grab)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_push(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Push)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_twist(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Twist)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_pinch(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Pinch)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_randomize(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Randomize)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_clone(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Clone)", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) items.extend([ - # Painting + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_weight_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Weight Mode", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.size')]}), + # Display + *_grease_pencil_display(), + # Keyframe menu + ("gpencil.blank_frame_add", {"type": 'I', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'X', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), + # Context menu + *_template_items_context_panel("VIEW3D_PT_gpencil_weight_context_menu", params.context_menu_event), + ]) + + return keymap + + +def km_grease_pencil_stroke_weight_draw(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Weight (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Draw + ("gpencil.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex Mode", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Selection + *_grease_pencil_selection(params), # Brush strength ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.strength')]}), - # Brush sze + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.size')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), # Display *_grease_pencil_display(), + # Tools + op_tool("builtin_brush.Draw", {"type": 'D', "value": 'PRESS'}), + # Keyframe menu + ("gpencil.blank_frame_add", {"type": 'I', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'X', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), + # Vertex Paint context menu + op_panel("VIEW3D_PT_gpencil_vertex_context_menu", params.context_menu_event), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_draw(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_blur(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Blur)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_average(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Average)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_smear(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Smear)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_replace(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Replace)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), ]) return keymap @@ -3346,7 +3782,7 @@ def km_grease_pencil_stroke_weight_mode(_params): def km_face_mask(params): items = [] keymap = ( - "Face Mask", + "Paint Face Mask (Weight, Vertex, Texture)", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) @@ -3371,7 +3807,7 @@ def km_face_mask(params): def km_weight_paint_vertex_selection(params): items = [] keymap = ( - "Weight Paint Vertex Selection", + "Paint Vertex Selection (Weight, Vertex)", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) @@ -3426,7 +3862,8 @@ def km_pose(params): {"properties": [("direction", 'CHILD'), ("extend", False)]}), ("pose.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, {"properties": [("direction", 'CHILD'), ("extend", True)]}), - ("pose.select_linked", {"type": 'L', "value": 'PRESS'}, None), + ("pose.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), + ("pose.select_linked_pick", {"type": 'L', "value": 'PRESS'}, None), ("pose.select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}, None), ("pose.select_mirror", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("pose.constraint_add_with_targets", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None), @@ -3440,14 +3877,13 @@ def km_pose(params): ("armature.layers_show_all", {"type": 'ACCENT_GRAVE', "value": 'PRESS', "ctrl": True}, None), ("armature.armature_layers", {"type": 'M', "value": 'PRESS', "shift": True}, None), ("pose.bone_layers", {"type": 'M', "value": 'PRESS'}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True}, - {"properties": [("mode", 'BONE_SIZE')]}), + ("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": False}, None), ("anim.keyframe_insert_menu", {"type": 'I', "value": 'PRESS'}, None), ("anim.keyframe_delete_v3d", {"type": 'I', "value": 'PRESS', "alt": True}, None), ("anim.keying_set_active_set", {"type": 'I', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), - ("poselib.browse_interactive", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), + ("poselib.browse_interactive", {"type": 'L', "value": 'PRESS', "alt": True}, None), ("poselib.pose_add", {"type": 'L', "value": 'PRESS', "shift": True}, None), - ("poselib.pose_remove", {"type": 'L', "value": 'PRESS', "alt": True}, None), + ("poselib.pose_remove", {"type": 'L', "value": 'PRESS', "shift": True, "alt": True}, None), ("poselib.pose_rename", {"type": 'L', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("pose.push", {"type": 'E', "value": 'PRESS', "ctrl": True}, None), ("pose.relax", {"type": 'E', "value": 'PRESS', "alt": True}, None), @@ -3587,10 +4023,10 @@ def km_paint_curve(params): ("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), ]) return keymap @@ -3618,7 +4054,7 @@ def km_curve(params): {"properties": [("deselect", False)]}), ("curve.select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True}, {"properties": [("deselect", True)]}), - ("curve.shortest_path_pick", {"type": params.select_mouse, "value": 'CLICK', "ctrl": True}, None), + ("curve.shortest_path_pick", {"type": params.select_mouse, "value": params.select_mouse_value, "ctrl": True}, None), ("curve.separate", {"type": 'P', "value": 'PRESS'}, None), ("curve.split", {"type": 'Y', "value": 'PRESS'}, None), ("curve.extrude_move", {"type": 'E', "value": 'PRESS'}, None), @@ -3630,8 +4066,8 @@ def km_curve(params): ("curve.dissolve_verts", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), ("curve.dissolve_verts", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, None), ("curve.tilt_clear", {"type": 'T', "value": 'PRESS', "alt": True}, None), - ("transform.tilt", {"type": 'T', "value": 'PRESS', "ctrl": True}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, + ("transform.tilt", {"type": 'T', "value": 'PRESS', "ctrl": True, "repeat": False}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, {"properties": [("mode", 'CURVE_SHRINKFATTEN')]}), ("curve.reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None), ("curve.hide", {"type": 'H', "value": 'PRESS'}, @@ -3833,6 +4269,7 @@ def km_weight_paint(params): {"properties": [("data_path", 'weight_paint_object.data.use_paint_mask_vertex')]}), ("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.weight_paint.brush.use_smooth_stroke')]}), + op_menu_pie("VIEW3D_MT_wpaint_vgroup_lock_pie", {"type" : 'K', "value": 'PRESS'}), *_template_items_context_panel("VIEW3D_PT_paint_weight_context_menu", params.context_menu_event), ]) @@ -3866,12 +4303,14 @@ def km_sculpt(params): ("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("mode", 'SMOOTH')]}), # Partial Visibility Show/hide - ("paint.hide_show", {"type": 'H', "value": 'PRESS', "shift": True}, - {"properties": [("action", 'SHOW'), ("area", 'INSIDE')]}), - ("paint.hide_show", {"type": 'H', "value": 'PRESS'}, - {"properties": [("action", 'HIDE'), ("area", 'INSIDE')]}), - ("paint.hide_show", {"type": 'H', "value": 'PRESS', "alt": True}, - {"properties": [("action", 'SHOW'), ("area", 'ALL')]}), + ("sculpt.face_set_change_visibility", {"type": 'H', "value": 'PRESS'}, + {"properties": [("mode", 'TOGGLE')]}), + ("sculpt.face_set_change_visibility", {"type": 'H', "value": 'PRESS', "shift": True}, + {"properties": [("mode", 'HIDE_ACTIVE')]}), + ("sculpt.face_set_change_visibility", {"type": 'H', "value": 'PRESS', "alt": True}, + {"properties": [("mode", 'SHOW_ALL')]}), + ("sculpt.mask_expand", {"type": 'W', "value": 'PRESS', "shift": True}, + {"properties": [("use_normals", False), ("keep_previous_mask", False), ("invert", False), ("smooth_iterations", 0), ("create_face_set", True)]}), # Subdivision levels *_template_items_object_subdivision_set(), ("object.subdivision_set", {"type": 'PAGE_UP', "value": 'PRESS'}, @@ -3887,14 +4326,15 @@ def km_sculpt(params): ("wm.context_toggle", {"type": 'M', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'scene.tool_settings.sculpt.show_mask')]}), ("sculpt.mask_expand", {"type": 'A', "value": 'PRESS', "shift": True}, - {"properties": [("use_normals", False), ("keep_previous_mask", False), ("invert", True), ("smooth_iterations", 2)]}), + {"properties": [("use_normals", False), ("keep_previous_mask", False), ("invert", True), ("smooth_iterations", 2), ("create_face_set", False)]}), ("sculpt.mask_expand", {"type": 'A', "value": 'PRESS', "shift": True, 'alt': True}, - {"properties": [("use_normals", True), ("keep_previous_mask", True), ("invert", False), ("smooth_iterations", 0)]}), + {"properties": [("use_normals", True), ("keep_previous_mask", True), ("invert", False), ("smooth_iterations", 0), ("create_face_set", False)]}), # Dynamic topology ("sculpt.dynamic_topology_toggle", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), ("sculpt.set_detail_size", {"type": 'D', "value": 'PRESS', "shift": True}, None), # Remesh ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), + ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS', "shift": True}, None), ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None), # Brush properties ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, @@ -3945,6 +4385,7 @@ def km_sculpt(params): {"properties": [("data_path", 'tool_settings.sculpt.brush.use_smooth_stroke')]}), op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), op_menu_pie("VIEW3D_MT_sculpt_mask_edit_pie", {"type" : 'A', "value": 'PRESS'}), + op_menu_pie("VIEW3D_MT_sculpt_face_sets_edit_pie", {"type" : 'W', "value": 'PRESS'}), *_template_items_context_panel("VIEW3D_PT_sculpt_context_menu", params.context_menu_event), ]) @@ -4015,7 +4456,7 @@ def km_mesh(params): {"properties": [("inside", True)]}), ("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'}, None), op_menu("VIEW3D_MT_edit_mesh_extrude", {"type": 'E', "value": 'PRESS', "alt": True}), - ("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True}, None), + ("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True, "repeat": False}, None), ("mesh.fill", {"type": 'F', "value": 'PRESS', "alt": True}, None), ("mesh.quads_convert_to_tris", {"type": 'T', "value": 'PRESS', "ctrl": True}, {"properties": [("quad_method", 'BEAUTY'), ("ngon_method", 'BEAUTY')]}), @@ -4027,8 +4468,9 @@ def km_mesh(params): ("mesh.rip_move", {"type": 'V', "value": 'PRESS', "alt": True}, {"properties": [("MESH_OT_rip", [("use_fill", True), ],)]}), ("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True}, None), - op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS', "alt": True}), - ("transform.shrink_fatten", {"type": 'S', "value": 'PRESS', "alt": True}, None), + op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS'}), + op_menu("VIEW3D_MT_edit_mesh_split", {"type": 'M', "value": 'PRESS', "alt": True}), + ("transform.shrink_fatten", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, None), ("mesh.edge_face_add", {"type": 'F', "value": 'PRESS'}, None), ("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None), op_menu("VIEW3D_MT_mesh_add", {"type": 'A', "value": 'PRESS', "shift": True}), @@ -4036,7 +4478,7 @@ def km_mesh(params): ("mesh.split", {"type": 'Y', "value": 'PRESS'}, None), ("mesh.vert_connect_path", {"type": 'J', "value": 'PRESS'}, None), ("mesh.point_normals", {"type": 'L', "value": 'PRESS', "alt": True}, None), - ("transform.vert_slide", {"type": 'V', "value": 'PRESS', "shift": True}, None), + ("transform.vert_slide", {"type": 'V', "value": 'PRESS', "shift": True, "repeat": False}, None), ("mesh.dupli_extrude_cursor", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, {"properties": [("rotate_source", True)]}), ("mesh.dupli_extrude_cursor", {"type": params.action_mouse, "value": 'CLICK', "shift": True, "ctrl": True}, @@ -4131,10 +4573,11 @@ def km_armature(params): ("armature.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), ("armature.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), ("armature.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None), - ("armature.select_linked", {"type": 'L', "value": 'PRESS'}, + ("armature.select_linked_pick", {"type": 'L', "value": 'PRESS'}, {"properties": [("deselect", False)]}), - ("armature.select_linked", {"type": 'L', "value": 'PRESS', "shift": True}, + ("armature.select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True}, {"properties": [("deselect", True)]}), + ("armature.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("armature.shortest_path_pick", {"type": params.select_mouse, "value": params.select_mouse_value, "ctrl": True}, None), # Editing. op_menu("VIEW3D_MT_edit_armature_delete", {"type": 'X', "value": 'PRESS'}), @@ -4146,7 +4589,6 @@ def km_armature(params): ("armature.extrude_forked", {"type": 'E', "value": 'PRESS', "shift": True}, None), ("armature.click_extrude", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None), ("armature.fill", {"type": 'F', "value": 'PRESS'}, None), - ("armature.merge", {"type": 'M', "value": 'PRESS', "alt": True}, None), ("armature.split", {"type": 'Y', "value": 'PRESS'}, None), ("armature.separate", {"type": 'P', "value": 'PRESS'}, None), # Set flags. @@ -4158,11 +4600,10 @@ def km_armature(params): ("armature.armature_layers", {"type": 'M', "value": 'PRESS', "shift": True}, None), ("armature.bone_layers", {"type": 'M', "value": 'PRESS'}, None), # Special transforms. - ("transform.transform", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True}, - {"properties": [("mode", 'BONE_SIZE')]}), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, + ("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": False}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, {"properties": [("mode", 'BONE_ENVELOPE')]}), - ("transform.transform", {"type": 'R', "value": 'PRESS', "ctrl": True}, + ("transform.transform", {"type": 'R', "value": 'PRESS', "ctrl": True, "repeat": False}, {"properties": [("mode", 'BONE_ROLL')]}), # Menus. *_template_items_context_menu("VIEW3D_MT_armature_context_menu", params.context_menu_event), @@ -4235,10 +4676,11 @@ def km_particle(params): *_template_items_select_actions(params, "particle.select_all"), ("particle.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), ("particle.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), - ("particle.select_linked", {"type": 'L', "value": 'PRESS'}, + ("particle.select_linked_pick", {"type": 'L', "value": 'PRESS'}, {"properties": [("deselect", False)]}), - ("particle.select_linked", {"type": 'L', "value": 'PRESS', "shift": True}, + ("particle.select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True}, {"properties": [("deselect", True)]}), + ("particle.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("particle.delete", {"type": 'X', "value": 'PRESS'}, None), ("particle.delete", {"type": 'DEL', "value": 'PRESS'}, None), ("particle.reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None), @@ -4351,7 +4793,7 @@ def km_font(params): ("font.text_insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), ("font.text_insert", {"type": 'BACK_SPACE', "value": 'PRESS', "alt": True}, {"properties": [("accent", True)]}), - *_template_items_context_menu("VIEW3D_MT_edit_text_context_menu", params.context_menu_event), + *_template_items_context_menu("VIEW3D_MT_edit_font_context_menu", params.context_menu_event), ]) return keymap @@ -4465,23 +4907,23 @@ def km_transform_modal_map(_params): ("CONFIRM", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "any": True}, None), ("CANCEL", {"type": 'RIGHTMOUSE', "value": 'PRESS', "any": True}, None), ("CANCEL", {"type": 'ESC', "value": 'PRESS', "any": True}, None), - ("AXIS_X", {"type": 'X', "value": 'PRESS'}, None), - ("AXIS_Y", {"type": 'Y', "value": 'PRESS'}, None), - ("AXIS_Z", {"type": 'Z', "value": 'PRESS'}, None), - ("PLANE_X", {"type": 'X', "value": 'PRESS', "shift": True}, None), - ("PLANE_Y", {"type": 'Y', "value": 'PRESS', "shift": True}, None), - ("PLANE_Z", {"type": 'Z', "value": 'PRESS', "shift": True}, None), - ("CONS_OFF", {"type": 'C', "value": 'PRESS'}, None), - ("TRANSLATE", {"type": 'G', "value": 'PRESS'}, None), - ("ROTATE", {"type": 'R', "value": 'PRESS'}, None), - ("RESIZE", {"type": 'S', "value": 'PRESS'}, None), - ("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True}, None), + ("AXIS_X", {"type": 'X', "value": 'PRESS', "repeat": False}, None), + ("AXIS_Y", {"type": 'Y', "value": 'PRESS', "repeat": False}, None), + ("AXIS_Z", {"type": 'Z', "value": 'PRESS', "repeat": False}, None), + ("PLANE_X", {"type": 'X', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("PLANE_Y", {"type": 'Y', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("PLANE_Z", {"type": 'Z', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("CONS_OFF", {"type": 'C', "value": 'PRESS', "repeat": False}, None), + ("TRANSLATE", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("ROTATE", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("RESIZE", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True, "repeat": False}, None), ("SNAP_INV_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None), ("SNAP_INV_OFF", {"type": 'LEFT_CTRL', "value": 'RELEASE', "any": True}, None), ("SNAP_INV_ON", {"type": 'RIGHT_CTRL', "value": 'PRESS', "any": True}, None), ("SNAP_INV_OFF", {"type": 'RIGHT_CTRL', "value": 'RELEASE', "any": True}, None), - ("ADD_SNAP", {"type": 'A', "value": 'PRESS'}, None), - ("REMOVE_SNAP", {"type": 'A', "value": 'PRESS', "alt": True}, None), + ("ADD_SNAP", {"type": 'A', "value": 'PRESS', "repeat": False}, None), + ("REMOVE_SNAP", {"type": 'A', "value": 'PRESS', "alt": True, "repeat": False}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS'}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS'}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, None), @@ -4497,7 +4939,7 @@ def km_transform_modal_map(_params): ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), - ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None), + ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS', "repeat": False}, None), ]) return keymap @@ -5375,7 +5817,7 @@ def km_3d_view_tool_edit_armature_bone_size(params): {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ ("transform.transform", {"type": params.tool_tweak, "value": 'ANY'}, - {"properties": [("release_confirm", True), ("mode", 'BONE_SIZE')]}), + {"properties": [("release_confirm", True), ("mode", 'BONE_ENVELOPE')]}), ]}, ) @@ -5384,9 +5826,10 @@ def km_3d_view_tool_edit_armature_bone_envelope(params): return ( "3D View Tool: Edit Armature, Bone Envelope", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ - ("transform.transform", {"type": params.tool_tweak, "value": 'ANY'}, - {"properties": [("release_confirm", True), ("mode", 'BONE_ENVELOPE')]}), + ("transform.bbone_resize", {"type": params.tool_tweak, "value": 'ANY'}, + {"properties": [("release_confirm", True)]}), ]}, ) @@ -5433,6 +5876,23 @@ def km_3d_view_tool_edit_mesh_extrude_region(params): ]}, ) +def km_3d_view_tool_edit_mesh_extrude_dissolve_and_intersect(params): + return ( + "3D View Tool: Edit Mesh, Extrude Dissolve and Intersect", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("mesh.extrude_region_dissolve_move_intersect", {"type": params.tool_tweak, "value": 'ANY'}, + {"properties": [ + ("MESH_OT_extrude_region", [("use_dissolve_ortho_edges", True)]), + ("TRANSFORM_OT_translate", [ + ("release_confirm", True), + ("use_automerge_and_split", True), + ("constraint_axis", (False, False, True)), + ("orient_type", 'NORMAL'), + ]), + ]}), + ]}, + ) def km_3d_view_tool_edit_mesh_extrude_along_normals(params): return ( @@ -6014,18 +6474,13 @@ def km_3d_view_tool_edit_gpencil_to_sphere(params): ) -# Also used for weight paint. -def km_3d_view_tool_sculpt_gpencil_paint(_params): +def km_3d_view_tool_edit_gpencil_transform_fill(params): return ( - "3D View Tool: Sculpt Gpencil, Paint", + "3D View Tool: Edit Gpencil, Transform Fill", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, - {"properties": [("wait_for_input", False)]}), - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, - {"properties": [("wait_for_input", False)]}), - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, - {"properties": [("wait_for_input", False)]}), + ("gpencil.transform_fill", {"type": params.tool_tweak, "value": 'ANY'}, + {"properties": [("release_confirm", True)]}), ]}, ) @@ -6072,6 +6527,7 @@ def km_sequencer_editor_tool_select(params): {"items": [ ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'}, {"properties": [("extend", False), ("deselect_all", not params.legacy)]}), + *_template_items_change_frame(params), ]}, ) @@ -6080,19 +6536,34 @@ def km_sequencer_editor_tool_select_box(params): return ( "Sequencer Tool: Select Box", {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, - {"items": _template_items_tool_select_actions_simple( - "sequencer.select_box", type=params.tool_tweak, value='ANY', - properties=[("tweak", True)], - )}, + {"items": [ + *_template_items_tool_select_actions_simple( + "sequencer.select_box", type=params.tool_tweak, value='ANY', + properties=[("tweak", params.select_mouse == 'LEFTMOUSE')], + ), + # RMB select can already set the frame, match the tweak tool. + *(_template_items_change_frame(params) + if params.select_mouse == 'LEFTMOUSE' else []), + ]}, + ) + + +def km_sequencer_editor_tool_generic_sample(params): + return ( + "Sequencer Tool: Sample", + {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, + {"items": [ + ("sequencer.sample", {"type": params.tool_mouse, "value": 'PRESS'}, None), + ]}, ) -def km_sequencer_editor_tool_cut(params): +def km_sequencer_editor_tool_blade(_params): return ( - "Sequencer Tool: Cut", + "Sequencer Tool: Blade", {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, - {"items":[ - ("sequencer.cut", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"items": [ + ("sequencer.split", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("type", 'SOFT'), ("side", 'NO_CHANGE'), ("use_cursor_position", True), ("ignore_selection", True)]}), ]}, ) @@ -6162,8 +6633,25 @@ def generate_keymaps(params=None): km_grease_pencil_stroke_paint_draw_brush(params), km_grease_pencil_stroke_paint_erase(params), km_grease_pencil_stroke_paint_fill(params), + km_grease_pencil_stroke_paint_tint(params), km_grease_pencil_stroke_sculpt_mode(params), + km_grease_pencil_stroke_sculpt_smooth(params), + km_grease_pencil_stroke_sculpt_thickness(params), + km_grease_pencil_stroke_sculpt_strength(params), + km_grease_pencil_stroke_sculpt_grab(params), + km_grease_pencil_stroke_sculpt_push(params), + km_grease_pencil_stroke_sculpt_twist(params), + km_grease_pencil_stroke_sculpt_pinch(params), + km_grease_pencil_stroke_sculpt_randomize(params), + km_grease_pencil_stroke_sculpt_clone(params), km_grease_pencil_stroke_weight_mode(params), + km_grease_pencil_stroke_weight_draw(params), + km_grease_pencil_stroke_vertex_mode(params), + km_grease_pencil_stroke_vertex_draw(params), + km_grease_pencil_stroke_vertex_blur(params), + km_grease_pencil_stroke_vertex_average(params), + km_grease_pencil_stroke_vertex_smear(params), + km_grease_pencil_stroke_vertex_replace(params), km_face_mask(params), km_weight_paint_vertex_selection(params), km_pose(params), @@ -6255,6 +6743,7 @@ def generate_keymaps(params=None): km_3d_view_tool_edit_armature_extrude_to_cursor(params), km_3d_view_tool_edit_mesh_add_cube(params), km_3d_view_tool_edit_mesh_extrude_region(params), + km_3d_view_tool_edit_mesh_extrude_dissolve_and_intersect(params), km_3d_view_tool_edit_mesh_extrude_along_normals(params), km_3d_view_tool_edit_mesh_extrude_individual(params), km_3d_view_tool_edit_mesh_extrude_to_cursor(params), @@ -6306,14 +6795,15 @@ def generate_keymaps(params=None): km_3d_view_tool_edit_gpencil_bend(params), km_3d_view_tool_edit_gpencil_shear(params), km_3d_view_tool_edit_gpencil_to_sphere(params), - km_3d_view_tool_sculpt_gpencil_paint(params), + km_3d_view_tool_edit_gpencil_transform_fill(params), km_3d_view_tool_sculpt_gpencil_select(params), km_3d_view_tool_sculpt_gpencil_select_box(params), km_3d_view_tool_sculpt_gpencil_select_circle(params), km_3d_view_tool_sculpt_gpencil_select_lasso(params), km_sequencer_editor_tool_select(params), km_sequencer_editor_tool_select_box(params), - km_sequencer_editor_tool_cut(params), + km_sequencer_editor_tool_blade(params), + km_sequencer_editor_tool_generic_sample(params), ] # ------------------------------------------------------------------------------ diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 0bffd316f30..842a12ed249 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -496,7 +496,9 @@ def km_outliner(params): {"properties": [("all", True)]}), ("outliner.item_openclose", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties": [("all", False)]}), + # Fall through to generic context menu if the item(s) selected have no type specific actions. ("outliner.operation", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, None), + op_menu("OUTLINER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), ("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True}, None), ("outliner.show_hierarchy", {"type": 'A', "value": 'PRESS'}, None), @@ -518,10 +520,8 @@ def km_outliner(params): ("anim.keyframe_delete", {"type": 'S', "value": 'PRESS', "alt": True}, None), ("outliner.drivers_add_selected", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), ("outliner.drivers_delete_selected", {"type": 'D', "value": 'PRESS', "ctrl": True, "alt": True}, None), - ("outliner.collection_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), - ("outliner.collection_delete", {"type": 'DEL', "value": 'PRESS'}, None), - ("outliner.object_operation", {"type": 'BACK_SPACE', "value": 'PRESS'}, {"properties": [("type", 'DELETE')]}), - ("outliner.object_operation", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("type", 'DELETE')]}), + ("outliner.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), + ("outliner.delete", {"type": 'DEL', "value": 'PRESS'}, None), ("object.move_to_collection", {"type": 'G', "value": 'PRESS', "ctrl": True}, None), ("object.link_to_collection", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("outliner.collection_exclude_set", {"type": 'E', "value": 'PRESS'}, None), @@ -557,7 +557,7 @@ def km_uv_editor(params): {"properties": [("data_path", 'tool_settings.uv_select_mode'), ("value", 'FACE')]}), ("wm.context_set_enum", {"type": 'FOUR', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.uv_select_mode'), ("value", 'ISLAND')]}), - + ("uv.select", {"type": 'LEFTMOUSE', "value": 'CLICK'}, {"properties": [("extend", False), ("deselect_all", True)]}), ("uv.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True}, @@ -1682,6 +1682,7 @@ def km_text(params): ("text.scroll", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ("text.selection_set", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), ("text.cursor_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), + ("text.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, None), ("text.scroll", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, {"properties": [("lines", -1)]}), ("text.scroll", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, @@ -1727,10 +1728,8 @@ def km_sequencer(params): ("sequencer.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("sequencer.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("sequencer.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), - ("sequencer.cut", {"type": 'K', "value": 'PRESS'}, + ("sequencer.split", {"type": 'B', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'SOFT')]}), - ("sequencer.cut", {"type": 'K', "value": 'PRESS', "shift": True}, - {"properties": [("type", 'HARD')]}), ("sequencer.mute", {"type": 'M', "value": 'PRESS'}, {"properties": [("unselected", False)]}), ("sequencer.mute", {"type": 'M', "value": 'PRESS', "shift": True}, @@ -1779,7 +1778,7 @@ def km_sequencer(params): ("sequencer.snap", {"type": 'X', "value": 'PRESS'}, None), ("sequencer.swap_inputs", {"type": 'S', "value": 'PRESS', "alt": True}, None), *( - (("sequencer.cut_multicam", + (("sequencer.split_multicam", {"type": NUMBERS_1[i], "value": 'PRESS'}, {"properties": [("camera", i + 1)]}) for i in range(10) @@ -1804,7 +1803,6 @@ def km_sequencer(params): ("sequencer.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, {"properties": [("extend", True)]}), ("sequencer.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "ctrl": True}, None), - ("sequencer.select_box", {"type": 'Q', "value": 'PRESS'}, None), ("sequencer.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties":[("tweak", True), ("mode", 'SET')]}), ("sequencer.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True}, @@ -1823,6 +1821,9 @@ def km_sequencer(params): *_template_items_context_menu("SEQUENCER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ("marker.add", {"type": 'M', "value": 'PRESS'}, None), ("marker.rename", {"type": 'RET', "value": 'PRESS'}, None), + # Tools + op_tool_cycle("builtin.select_box", {"type": 'Q', "value": 'PRESS'}), + op_tool_cycle("builtin.blade", {"type": 'B', "value": 'PRESS'}), ]) return keymap @@ -2271,6 +2272,14 @@ def _grease_pencil_selection(params): ] +def _grease_pencil_display(): + return [ + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_edit_lines')]}), + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True, "alt": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_multiedit_line_only')]}), + ] + def km_grease_pencil_stroke_edit_mode(params): items = [] @@ -2364,6 +2373,10 @@ def km_grease_pencil_stroke_paint_mode(params): op_tool_cycle("builtin_brush.Erase", {"type": 'E', "value": 'PRESS'}), op_tool_cycle("builtin.cutter", {"type": 'K', "value": 'PRESS'}), op_tool_cycle("builtin.cursor", {"type": 'C', "value": 'PRESS'}), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), ]) return keymap @@ -2386,9 +2399,6 @@ def km_grease_pencil_stroke_paint_draw_brush(params): # Draw - straight lines ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "alt": True}, {"properties": [("mode", 'DRAW_STRAIGHT'), ("wait_for_input", False)]}), - # Draw - poly lines - ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "alt": True}, - {"properties": [("mode", 'DRAW_POLY'), ("wait_for_input", False)]}), # Erase ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("mode", 'ERASER'), ("wait_for_input", False)]}), @@ -2470,6 +2480,25 @@ def km_grease_pencil_stroke_paint_fill(params): return keymap +def km_grease_pencil_stroke_paint_tint(params): + items = [] + keymap = ( + "Grease Pencil Stroke Paint (Tint)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + def km_grease_pencil_stroke_sculpt_mode(params): items = [] keymap = ( @@ -2481,30 +2510,246 @@ def km_grease_pencil_stroke_sculpt_mode(params): items.extend([ # Selection *_grease_pencil_selection(params), - # Painting + + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.size')]}), + # Copy + ("gpencil.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), + # Display + *_grease_pencil_display(), + # Context menu + op_panel("VIEW3D_PT_gpencil_sculpt_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_smooth(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Smooth)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_thickness(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Thickness)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_strength(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Strength)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_grab(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Grab)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_push(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Push)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_twist(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Twist)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_pinch(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Pinch)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_randomize(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Randomize)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_clone(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Clone)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_weight_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Weight Mode", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ # Brush strength ("wm.radial_control", {"type": 'U', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.strength')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.strength')]}), # Brush size ("wm.radial_control", {"type": 'S', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.size')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.size')]}), # Context menu - *_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + *_template_items_context_panel("VIEW3D_PT_gpencil_weight_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ]) return keymap -def km_grease_pencil_stroke_weight_mode(params): +def km_grease_pencil_stroke_weight_draw(_params): items = [] keymap = ( - "Grease Pencil Stroke Weight Mode", + "Grease Pencil Stroke Weight (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex Mode", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) @@ -2512,26 +2757,141 @@ def km_grease_pencil_stroke_weight_mode(params): items.extend([ # Selection *_grease_pencil_selection(params), - # Painting - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + # Brush strength + ("wm.radial_control", {"type": 'U', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'S', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + # Display + *_grease_pencil_display(), + # Tools + op_tool("builtin_brush.Draw", {"type": 'D', "value": 'PRESS'}), + # Vertex Paint context menu + op_panel("VIEW3D_PT_gpencil_vertex_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + ]) + + return keymap + +def km_grease_pencil_stroke_vertex_draw(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("wait_for_input", False)]}), - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_blur(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Blur)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_average(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Average)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_smear(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Smear)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("wait_for_input", False)]}), # Brush strength ("wm.radial_control", {"type": 'U', "value": 'PRESS', "shift": True}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.strength')]}), - # Brush size. + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size ("wm.radial_control", {"type": 'S', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.size')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), ]) return keymap +def km_grease_pencil_stroke_vertex_replace(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Replace)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + def km_face_mask(params): items = [] keymap = ( - "Face Mask", + "Paint Face Mask (Weight, Vertex, Texture)", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) @@ -2558,7 +2918,7 @@ def km_face_mask(params): def km_weight_paint_vertex_selection(params): items = [] keymap = ( - "Weight Paint Vertex Selection", + "Paint Vertex Selection (Weight, Vertex)", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) @@ -3015,6 +3375,10 @@ def km_sculpt(params): # Remesh ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None), + # Remesh + ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), + ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS', "shift": True}, None), + ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None), # Brush properties ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, {"properties": [("scalar", 0.9)]}), @@ -3176,7 +3540,7 @@ def km_armature(params): ("armature.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), ("armature.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None), - ("armature.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("armature.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("deselect", False)]}), ("armature.shortest_path_pick", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True, "shift": True}, None), @@ -3278,10 +3642,11 @@ def km_particle(params): ("particle.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("particle.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), ("particle.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), - ("particle.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("particle.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("deselect", False)]}), - ("particle.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, + ("particle.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, {"properties": [("deselect", True)]}), + ("particle.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "ctrl": True}, None), ("particle.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), ("particle.delete", {"type": 'DEL', "value": 'PRESS'}, None), ("particle.reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None), @@ -3387,7 +3752,7 @@ def km_font(params): ("font.text_insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), ("font.text_insert", {"type": 'BACK_SPACE', "value": 'PRESS', "alt": True}, {"properties": [("accent", True)]}), - *_template_items_context_menu("VIEW3D_MT_edit_text_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + *_template_items_context_menu("VIEW3D_MT_edit_font_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ]) @@ -3403,7 +3768,8 @@ def km_object_non_modal(params): ) items.extend([ - + ("object.mode_set",{"type": 'THREE', "value": 'PRESS'}, + {"properties": [("mode", 'POSE')]}), ("object.mode_set_with_submode",{"type": 'ONE', "value": 'PRESS'}, {"properties": [("mode", 'EDIT'), ("mesh_select_mode", {'VERT'})]}), ("object.mode_set_with_submode",{"type": 'TWO', "value": 'PRESS'}, @@ -3422,7 +3788,6 @@ def km_object_non_modal(params): {"properties": [("mode", 'WEIGHT_PAINT')]}), ("object.mode_set",{"type": 'EIGHT', "value": 'PRESS'}, {"properties": [("mode", 'TEXTURE_PAINT')]}), - ("object.mode_set",{"type": 'TWO', "value": 'PRESS'}, {"properties": [("mode", 'EDIT_GPENCIL')]}), ("object.mode_set",{"type": 'THREE', "value": 'PRESS'}, @@ -3432,8 +3797,6 @@ def km_object_non_modal(params): ("object.mode_set",{"type": 'FIVE', "value": 'PRESS'}, {"properties": [("mode", 'WEIGHT_GPENCIL')]}), - ("object.mode_set",{"type": 'THREE', "value": 'PRESS'}, - {"properties": [("mode", 'POSE')]}) ]) return keymap @@ -3456,7 +3819,7 @@ def km_knife_tool_modal_map(_params): ("PANNING", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, None), ("CONFIRM", {"type": 'RET', "value": 'PRESS', "any": True}, None), ("CONFIRM", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "any": True}, None), - ("CONFIRM", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK', "any": True}, None), + ("ADD_CUT_CLOSED", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK', "any": True}, None), ("ADD_CUT", {"type": 'LEFTMOUSE', "value": 'ANY', "any": True}, None), ("NEW_CUT", {"type": 'E', "value": 'PRESS'}, None), ("SNAP_MIDPOINTS_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": False}, None), @@ -3593,6 +3956,14 @@ def km_image_editor_tool_uv_select(params): ) +def km_3d_view_tool_edit_gpencil_select(params): + return ( + "3D View Tool: Edit Gpencil, Tweak", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": _template_items_tool_select(params, "gpencil.select", extend="toggle")}, + ) + + # Fallback for gizmos that don't have custom a custom key-map. @@ -3680,8 +4051,25 @@ def generate_keymaps_impl(params=None): km_grease_pencil_stroke_paint_draw_brush(params), km_grease_pencil_stroke_paint_erase(params), km_grease_pencil_stroke_paint_fill(params), + km_grease_pencil_stroke_paint_tint(params), km_grease_pencil_stroke_sculpt_mode(params), + km_grease_pencil_stroke_sculpt_smooth(params), + km_grease_pencil_stroke_sculpt_thickness(params), + km_grease_pencil_stroke_sculpt_strength(params), + km_grease_pencil_stroke_sculpt_grab(params), + km_grease_pencil_stroke_sculpt_push(params), + km_grease_pencil_stroke_sculpt_twist(params), + km_grease_pencil_stroke_sculpt_pinch(params), + km_grease_pencil_stroke_sculpt_randomize(params), + km_grease_pencil_stroke_sculpt_clone(params), km_grease_pencil_stroke_weight_mode(params), + km_grease_pencil_stroke_weight_draw(params), + km_grease_pencil_stroke_vertex_mode(params), + km_grease_pencil_stroke_vertex_draw(params), + km_grease_pencil_stroke_vertex_blur(params), + km_grease_pencil_stroke_vertex_average(params), + km_grease_pencil_stroke_vertex_smear(params), + km_grease_pencil_stroke_vertex_replace(params), km_face_mask(params), km_weight_paint_vertex_selection(params), km_pose(params), @@ -3713,6 +4101,7 @@ def generate_keymaps_impl(params=None): # Tool System. km_3d_view_tool_select(params), km_image_editor_tool_uv_select(params), + km_3d_view_tool_edit_gpencil_select(params), ] @@ -3738,7 +4127,13 @@ def keymap_transform_tool_mmb(keymap): km_items_new.append(kmi) elif ty == 'EVT_TWEAK_L': kmi = (kmi[0], kmi[1].copy(), kmi[2]) - kmi[1]["type"] = 'EVT_TWEAK_M' + if kmi[1]["value"] == 'ANY': + kmi[1]["type"] = 'MIDDLEMOUSE' + kmi[1]["value"] = 'PRESS' + else: + # Directional tweaking can't be replaced by middle-mouse. + kmi[1]["type"] = 'EVT_TWEAK_M' + km_items_new.append(kmi) km_items.extend(km_items_new) diff --git a/release/scripts/startup/bl_app_templates_system/2D_Animation/__init__.py b/release/scripts/startup/bl_app_templates_system/2D_Animation/__init__.py new file mode 100644 index 00000000000..009cb65d150 --- /dev/null +++ b/release/scripts/startup/bl_app_templates_system/2D_Animation/__init__.py @@ -0,0 +1,64 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# Initialization script for 2D Animation template + +import bpy +from bpy.app.handlers import persistent + + +@persistent +def load_handler(dummy): + import bpy + + # 2D Animation + screen = bpy.data.screens['2D Animation'] + if screen: + for area in screen.areas: + # Set Tool settings as default in properties panel. + if area.type == 'PROPERTIES': + for space in area.spaces: + if space.type != 'PROPERTIES': + continue + space.context = 'TOOL' + + # Open sidebar in Dopesheet. + elif area.type == 'DOPESHEET_EDITOR': + for space in area.spaces: + if space.type != 'DOPESHEET_EDITOR': + continue + space.show_region_ui = True + + # 2D Full Canvas + screen = bpy.data.screens['2D Full Canvas'] + if screen: + for area in screen.areas: + if area.type == 'VIEW_3D': + for space in area.spaces: + if space.type != 'VIEW_3D': + continue + space.shading.type = 'MATERIAL' + space.shading.use_scene_world = True + + +def register(): + bpy.app.handlers.load_factory_startup_post.append(load_handler) + + +def unregister(): + bpy.app.handlers.load_factory_startup_post.remove(load_handler) diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py index 5af2bd22222..d7df29f1769 100644 --- a/release/scripts/startup/bl_operators/__init__.py +++ b/release/scripts/startup/bl_operators/__init__.py @@ -42,6 +42,7 @@ _modules = [ "rigidbody", "screen_play_rendered_anim", "sequencer", + "simulation", "userpref", "uvcalc_follow_active", "uvcalc_lightmap", diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 3ce06647cdc..edcd52c12bd 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -162,7 +162,8 @@ class AddTorus(Operator, object_utils.AddObjectHelper): name="Major Radius", description=("Radius from the origin to the " "center of the cross sections"), - min=0.01, max=100.0, + soft_min=0.0, soft_max=100.0, + min=0.0, max=10_000.0, default=1.0, subtype='DISTANCE', unit='LENGTH', @@ -170,7 +171,8 @@ class AddTorus(Operator, object_utils.AddObjectHelper): minor_radius: FloatProperty( name="Minor Radius", description="Radius of the torus' cross section", - min=0.01, max=100.0, + soft_min=0.0, soft_max=100.0, + min=0.0, max=10_000.0, default=0.25, subtype='DISTANCE', unit='LENGTH', @@ -178,7 +180,8 @@ class AddTorus(Operator, object_utils.AddObjectHelper): abso_major_rad: FloatProperty( name="Exterior Radius", description="Total Exterior Radius of the torus", - min=0.01, max=100.0, + soft_min=0.0, soft_max=100.0, + min=0.0, max=10_000.0, default=1.25, subtype='DISTANCE', unit='LENGTH', @@ -186,7 +189,8 @@ class AddTorus(Operator, object_utils.AddObjectHelper): abso_minor_rad: FloatProperty( name="Interior Radius", description="Total Interior Radius of the torus", - min=0.01, max=100.0, + soft_min=0.0, soft_max=100.0, + min=0.0, max=10_000.0, default=0.75, subtype='DISTANCE', unit='LENGTH', diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 15ff08e0719..cd4c1686747 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -486,7 +486,18 @@ class CLIP_OT_constraint_to_fcurve(Operator): return {'FINISHED'} # Find start and end frames. - for track in clip.tracking.tracks: + if con.object: + tracking_object = clip.tracking.objects.get(con.object, None) + if not tracking_object: + self.report({'ERROR'}, "Motion Tracking object not found") + + return {'CANCELLED'} + + tracks = tracking_object.tracks + else: + tracks = clip.tracking.tracks + + for track in tracks: if sfra is None: sfra = track.markers[0].frame else: diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 6a21f7db654..c83d0b9f4d8 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -390,7 +390,7 @@ class AddPresetFluid(AddPresetBase, Operator): preset_values = [ "fluid.domain_settings.viscosity_base", - "fluidanta.domain_settings.viscosity_exponent", + "fluid.domain_settings.viscosity_exponent", ] preset_subdir = "fluid" @@ -642,10 +642,7 @@ class AddPresetGpencilBrush(AddPresetBase, Operator): "brush.smooth_stroke_factor", "settings.pen_smooth_factor", "settings.pen_smooth_steps", - "settings.pen_thick_smooth_factor", - "settings.pen_thick_smooth_steps", "settings.pen_subdivision_steps", - "settings.random_subdiv", "settings.use_settings_random", "settings.random_pressure", "settings.random_strength", @@ -675,8 +672,6 @@ class AddPresetGpencilMaterial(AddPresetBase, Operator): "gpcolor.color", "gpcolor.stroke_image", "gpcolor.pixel_size", - "gpcolor.use_stroke_pattern", - "gpcolor.use_stroke_texture_mix", "gpcolor.mix_stroke_factor", "gpcolor.alignment_mode", "gpcolor.fill_style", @@ -686,18 +681,11 @@ class AddPresetGpencilMaterial(AddPresetBase, Operator): "gpcolor.mix_color", "gpcolor.mix_factor", "gpcolor.flip", - "gpcolor.pattern_shift", - "gpcolor.pattern_scale", - "gpcolor.pattern_radius", - "gpcolor.pattern_angle", - "gpcolor.pattern_gridsize", - "gpcolor.use_fill_pattern", "gpcolor.texture_offset", "gpcolor.texture_scale", "gpcolor.texture_angle", "gpcolor.texture_opacity", "gpcolor.texture_clamp", - "gpcolor.use_fill_texture_mix", "gpcolor.mix_factor", "gpcolor.show_stroke", "gpcolor.show_fill", diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py index 9a0028d1f14..206f778195e 100644 --- a/release/scripts/startup/bl_operators/sequencer.py +++ b/release/scripts/startup/bl_operators/sequencer.py @@ -79,11 +79,11 @@ class SequencerCrossfadeSounds(Operator): return {'CANCELLED'} -class SequencerCutMulticam(Operator): - """Cut multi-cam strip and select camera""" +class SequencerSplitMulticam(Operator): + """Split multi-cam strip and select camera""" - bl_idname = "sequencer.cut_multicam" - bl_label = "Cut multicam" + bl_idname = "sequencer.split_multicam" + bl_label = "Split multicam" bl_options = {'REGISTER', 'UNDO'} camera: IntProperty( @@ -112,7 +112,7 @@ class SequencerCutMulticam(Operator): s.select = True cfra = context.scene.frame_current - bpy.ops.sequencer.cut(frame=cfra, type='SOFT', side='RIGHT') + bpy.ops.sequencer.split(frame=cfra, type='SOFT', side='RIGHT') for s in context.scene.sequence_editor.sequences_all: if s.select and s.type == 'MULTICAM' and s.frame_final_start <= cfra and cfra < s.frame_final_end: context.scene.sequence_editor.active_strip = s @@ -369,7 +369,7 @@ def calculate_duration_frames(context, duration_seconds): classes = ( SequencerCrossfadeSounds, - SequencerCutMulticam, + SequencerSplitMulticam, SequencerDeinterlaceSelectedMovies, SequencerFadesClear, SequencerFadesAdd, diff --git a/release/scripts/startup/bl_operators/simulation.py b/release/scripts/startup/bl_operators/simulation.py new file mode 100644 index 00000000000..5d9c9476318 --- /dev/null +++ b/release/scripts/startup/bl_operators/simulation.py @@ -0,0 +1,39 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +import bpy + +class NewSimulation(bpy.types.Operator): + """Create a new simulation data block and edit it in the opened simulation editor""" + + bl_idname = "simulation.new" + bl_label = "New Simulation" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return context.area.type == 'NODE_EDITOR' and context.space_data.tree_type == 'SimulationNodeTree' + + def execute(self, context): + simulation = bpy.data.simulations.new("Simulation") + context.space_data.simulation = simulation + return {'FINISHED'} + +classes = ( + NewSimulation, +) diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index 4cb6ddd3fa3..2e14df1920f 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -52,8 +52,10 @@ def module_filesystem_remove(path_base, module_name): # This duplicates shutil.copytree from Python 3.8, with the new dirs_exist_ok # argument that we need. Once we upgrade to 3.8 we can remove this. def _preferences_copytree(entries, src, dst): - import shutil import os + import shutil + from shutil import Error + os.makedirs(dst, exist_ok=True) errors = [] @@ -108,20 +110,30 @@ class PREFERENCES_OT_copy_prev(Operator): bl_idname = "preferences.copy_prev" bl_label = "Copy Previous Settings" - @staticmethod - def previous_version(): - ver = bpy.app.version - ver_old = ((ver[0] * 100) + ver[1]) - 1 - return ver_old // 100, ver_old % 100 + @classmethod + def _old_version_path(cls, version): + return bpy.utils.resource_path('USER', version[0], version[1]) - @staticmethod - def _old_path(): - ver = bpy.app.version - ver_old = ((ver[0] * 100) + ver[1]) - 1 - return bpy.utils.resource_path('USER', ver_old // 100, ver_old % 100) + @classmethod + def previous_version(cls): + # Find config folder from previous version. + import os + version = bpy.app.version + version_old = ((version[0] * 100) + version[1]) - 1 + while version_old % 10 > 0: + version_split = version_old // 100, version_old % 100 + if os.path.isdir(cls._old_version_path(version_split)): + return version_split + version_old = version_old - 1 + return None - @staticmethod - def _new_path(): + @classmethod + def _old_path(cls): + version_old = cls.previous_version() + return cls._old_version_path(version_old) if version_old else None + + @classmethod + def _new_path(cls): return bpy.utils.resource_path('USER') @classmethod @@ -130,6 +142,8 @@ class PREFERENCES_OT_copy_prev(Operator): old = cls._old_path() new = cls._new_path() + if not old: + return False # Disable operator in case config path is overridden with environment # variable. That case has no automatic per-version configuration. @@ -970,6 +984,7 @@ class PREFERENCES_OT_studiolight_install(Operator): options={'HIDDEN'}, ) type: EnumProperty( + name="Type", items=( ('MATCAP', "MatCap", ""), ('WORLD', "World", ""), @@ -1038,7 +1053,7 @@ class PREFERENCES_OT_studiolight_new(Operator): if os.path.isfile(filepath_final): if not self.ask_overide: self.ask_overide = True - return wm.invoke_props_dialog(self, width=600) + return wm.invoke_props_dialog(self, width=320) else: for studio_light in prefs.studio_lights: if studio_light.name == filename: @@ -1064,7 +1079,7 @@ class PREFERENCES_OT_studiolight_new(Operator): def invoke(self, context, _event): wm = context.window_manager - return wm.invoke_props_dialog(self, width=600) + return wm.invoke_props_dialog(self, width=320) class PREFERENCES_OT_studiolight_uninstall(Operator): diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py index a249599b5d7..7024582ad30 100644 --- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py +++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py @@ -145,6 +145,7 @@ from math import pi class VertexPaintDirt(Operator): + '''Generate a dirt map gradient based on cavity''' bl_idname = "paint.vertex_color_dirt" bl_label = "Dirty Vertex Colors" bl_options = {'REGISTER', 'UNDO'} diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index fcabee94a89..88fa06a913f 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -72,13 +72,19 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): bl_label = "Extrude and Move on Normals" bl_idname = "view3d.edit_mesh_extrude_move_normal" + dissolve_and_intersect: BoolProperty( + name="dissolve_and_intersect", + default=False, + description="Dissolves adjacent faces and intersects new geometry" + ) + @classmethod def poll(cls, context): obj = context.active_object return (obj is not None and obj.mode == 'EDIT') @staticmethod - def extrude_region(context, use_vert_normals): + def extrude_region(context, use_vert_normals, dissolve_and_intersect): mesh = context.object.data totface = mesh.total_face_sel @@ -91,6 +97,17 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): 'INVOKE_REGION_WIN', TRANSFORM_OT_shrink_fatten={}, ) + elif dissolve_and_intersect: + bpy.ops.mesh.extrude_region_dissolve_move_intersect( + 'INVOKE_REGION_WIN', + MESH_OT_extrude_region={ + "use_dissolve_ortho_edges": True, + }, + TRANSFORM_OT_translate={ + "orient_type": 'NORMAL', + "constraint_axis": (False, False, True), + }, + ) else: bpy.ops.mesh.extrude_region_move( 'INVOKE_REGION_WIN', @@ -119,7 +136,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): return {'FINISHED'} def execute(self, context): - return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False) + return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False, self.dissolve_and_intersect) def invoke(self, context, _event): return self.execute(context) @@ -136,7 +153,7 @@ class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator): return (obj is not None and obj.mode == 'EDIT') def execute(self, context): - return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True) + return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True, False) def invoke(self, context, _event): return self.execute(context) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 335a2a633cd..b54ae67a9c5 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -87,8 +87,10 @@ def context_path_validate(context, data_path): # One of the items in the rna path is None, just ignore this value = Ellipsis else: - # We have a real error in the rna path, don't ignore that - raise + # Print invalid path, but don't show error to the users and fully + # break the UI if the operator is bound to an event like left click. + print("context_path_validate error: context.%s not found (invalid keymap entry?)" % data_path) + value = Ellipsis return value @@ -1147,22 +1149,26 @@ rna_property = StringProperty( rna_min = FloatProperty( name="Min", + description="Minimum value of the property", default=-10000.0, precision=3, ) rna_max = FloatProperty( name="Max", + description="Maximum value of the property", default=10000.0, precision=3, ) rna_use_soft_limits = BoolProperty( name="Use Soft Limits", + description="Limits the Property Value slider to a range, values outside the range must be inputted numerically", ) rna_is_overridable_library = BoolProperty( name="Is Library Overridable", + description="Allow the property to be overridden when the Data-Block is linked", default=False, ) @@ -1177,6 +1183,7 @@ rna_vector_subtype_items = ( class WM_OT_properties_edit(Operator): + """Edit the attributes of the property""" bl_idname = "wm.properties_edit" bl_label = "Edit Property" # register only because invoke_props_popup requires. @@ -1468,6 +1475,7 @@ class WM_OT_properties_edit(Operator): class WM_OT_properties_add(Operator): + """Add your own property to the data-block""" bl_idname = "wm.properties_add" bl_label = "Add Property" bl_options = {'UNDO', 'INTERNAL'} @@ -2417,7 +2425,14 @@ class WM_MT_splash(Menu): col = split.column() - col.label() + sub = col.split(factor=0.35) + row = sub.row() + row.alignment = 'RIGHT' + row.label(text="Language") + prefs = context.preferences + sub.prop(prefs.view, "language", text="") + + col.separator() sub = col.split(factor=0.35) row = sub.row() @@ -2459,14 +2474,6 @@ class WM_MT_splash(Menu): label = "Blender Dark" sub.menu("USERPREF_MT_interface_theme_presets", text=label) - # We need to make switching to a language easier first - #sub = col.split(factor=0.35) - #row = sub.row() - #row.alignment = 'RIGHT' - # row.label(text="Language:") - #prefs = context.preferences - #sub.prop(prefs.system, "language", text="") - # Keep height constant if not has_select_mouse: col.label() @@ -2478,8 +2485,8 @@ class WM_MT_splash(Menu): row = layout.row() sub = row.row() - if bpy.types.PREFERENCES_OT_copy_prev.poll(context): - old_version = bpy.types.PREFERENCES_OT_copy_prev.previous_version() + old_version = bpy.types.PREFERENCES_OT_copy_prev.previous_version() + if bpy.types.PREFERENCES_OT_copy_prev.poll(context) and old_version: sub.operator("preferences.copy_prev", text="Load %d.%d Settings" % old_version) sub.operator("wm.save_userpref", text="Save New Settings") else: @@ -2550,6 +2557,36 @@ class WM_MT_splash(Menu): layout.separator() +class WM_MT_splash_about(Menu): + bl_label = "About" + + def draw(self, context): + + layout = self.layout + layout.operator_context = 'EXEC_DEFAULT' + + layout.label(text="Blender is free software") + layout.label(text="Licensed under the GNU General Public License") + layout.separator() + layout.separator() + + split = layout.split() + split.emboss = 'PULLDOWN_MENU' + split.scale_y = 1.3 + + col1 = split.column() + + col1.operator("wm.url_open_preset", text="Release Notes", icon='URL').type = 'RELEASE_NOTES' + col1.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS' + col1.operator("wm.url_open", text="License", icon='URL').url = "https://www.blender.org/about/license/" + + col2 = split.column() + + col2.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER' + col2.operator("wm.url_open", text="Blender Store", icon='URL').url = "https://store.blender.org" + col2.operator("wm.url_open_preset", text="Development Fund", icon='FUND').type = 'FUND' + + class WM_OT_drop_blend_file(Operator): bl_idname = "wm.drop_blend_file" bl_label = "Handle dropped .blend file" @@ -2619,4 +2656,5 @@ classes = ( BatchRenameAction, WM_OT_batch_rename, WM_MT_splash, + WM_MT_splash_about, ) diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 8fc59ca493a..36df0256c3d 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -35,14 +35,17 @@ _modules = [ "properties_data_curve", "properties_data_empty", "properties_data_gpencil", + "properties_data_hair", "properties_data_light", "properties_data_lattice", "properties_data_mesh", "properties_data_metaball", "properties_data_modifier", + "properties_data_pointcloud", "properties_data_shaderfx", "properties_data_lightprobe", "properties_data_speaker", + "properties_data_volume", "properties_mask_common", "properties_material", "properties_material_gpencil", diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index d44af702d46..05abfa02500 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -84,17 +84,12 @@ class DATA_PT_display(ArmatureButtonsPanel, Panel): layout.prop(arm, "display_type", text="Display As") - flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True) - col = flow.column() + col = layout.column(heading="Show") col.prop(arm, "show_names", text="Names") - col = flow.column() col.prop(arm, "show_axes", text="Axes") - col = flow.column() col.prop(arm, "show_bone_custom_shapes", text="Shapes") - col = flow.column() col.prop(arm, "show_group_colors", text="Group Colors") if ob: - col = flow.column() col.prop(ob, "show_in_front", text="In Front") diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index c50b9414667..aca358870c8 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -268,18 +268,43 @@ class BONE_PT_display(BoneButtonsPanel, Panel): col = layout.column() col.prop(bone, "hide", text="Hide") + + +class BONE_PT_display_custom_shape(BoneButtonsPanel, Panel): + bl_label = "Custom Shape" + bl_parent_id = "BONE_PT_display" + + @classmethod + def poll(cls, context): + return context.bone + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + bone = context.bone + pchan = None + + if ob and bone: + pchan = ob.pose.bones[bone.name] + elif bone is None: + bone = context.edit_bone + + if bone and pchan: + col = layout.column() + col.prop(pchan, "custom_shape") + sub = col.column() sub.active = bool(pchan and pchan.custom_shape) + sub.separator() + sub.prop(pchan, "custom_shape_scale", text="Scale") + sub.prop_search(pchan, "custom_shape_transform", + ob.pose, "bones", text="Override Transform") + sub.prop(pchan, "use_custom_shape_bone_size") + sub.separator() sub.prop(bone, "show_wire", text="Wireframe") - if pchan: - col = layout.column() - col.prop(pchan, "custom_shape") - if pchan.custom_shape: - col.prop(pchan, "use_custom_shape_bone_size", text="Bone Size") - col.prop(pchan, "custom_shape_scale", text="Scale") - col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones") - class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel): bl_label = "Inverse Kinematics" @@ -431,6 +456,7 @@ classes = ( BONE_PT_inverse_kinematics, BONE_PT_deform, BONE_PT_display, + BONE_PT_display_custom_shape, BONE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 957b119e9ba..62e1bcdfce4 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -360,8 +360,9 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): col.prop(bg, "rotation") col.prop(bg, "scale") - col.prop(bg, "use_flip_x") - col.prop(bg, "use_flip_y") + col = box.column(heading="Flip") + col.prop(bg, "use_flip_x", text="X") + col.prop(bg, "use_flip_y", text="Y") class DATA_PT_camera_display(CameraButtonsPanel, Panel): @@ -377,21 +378,12 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel): col = layout.column(align=True) - col.separator() - col.prop(cam, "display_size", text="Size") - col.separator() - - flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) - - col = flow.column() + col = layout.column(heading="Show") col.prop(cam, "show_limits", text="Limits") - col = flow.column() col.prop(cam, "show_mist", text="Mist") - col = flow.column() col.prop(cam, "show_sensor", text="Sensor") - col = flow.column() col.prop(cam, "show_name", text="Name") @@ -407,24 +399,20 @@ class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel): cam = context.camera - flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) + layout.prop(cam, "show_composition_thirds") - col = flow.column() + col = layout.column(heading="Center", align=True) col.prop(cam, "show_composition_center") - col = flow.column() - col.prop(cam, "show_composition_center_diagonal") - col = flow.column() - col.prop(cam, "show_composition_thirds") - col = flow.column() - col.prop(cam, "show_composition_golden") - col = flow.column() - col.prop(cam, "show_composition_golden_tria_a") - col = flow.column() - col.prop(cam, "show_composition_golden_tria_b") - col = flow.column() - col.prop(cam, "show_composition_harmony_tri_a") - col = flow.column() - col.prop(cam, "show_composition_harmony_tri_b") + col.prop(cam, "show_composition_center_diagonal", text="Diagonal") + + col = layout.column(heading="Golden", align=True) + col.prop(cam, "show_composition_golden", text="Ratio") + col.prop(cam, "show_composition_golden_tria_a", text="Triangle A") + col.prop(cam, "show_composition_golden_tria_b", text="Triangle B") + + col = layout.column(heading="Harmony", align=True) + col.prop(cam, "show_composition_harmony_tri_a", text="Triangle A") + col.prop(cam, "show_composition_harmony_tri_b", text="Triangle B") class DATA_PT_camera_display_passepartout(CameraButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index b694062dfc5..7e7488f4cf1 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -276,23 +276,23 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): col.prop(act_spline, "use_smooth") else: - sub = col.column(align=True) - sub.prop(act_spline, "use_cyclic_u") + sub = col.column(heading="Cyclic", align=True) + sub.prop(act_spline, "use_cyclic_u", text="U") if is_surf: sub.prop(act_spline, "use_cyclic_v", text="V") if act_spline.type == 'NURBS': - sub = col.column(align=True) + sub = col.column(heading="Bezier", align=True) # sub.active = (not act_spline.use_cyclic_u) - sub.prop(act_spline, "use_bezier_u", text="Bezier U") + sub.prop(act_spline, "use_bezier_u", text="U") if is_surf: subsub = sub.column() subsub.active = (not act_spline.use_cyclic_v) subsub.prop(act_spline, "use_bezier_v", text="V") - sub = col.column(align=True) - sub.prop(act_spline, "use_endpoint_u", text="Endpoint U") + sub = col.column(heading="Endpoint", align=True) + sub.prop(act_spline, "use_endpoint_u", text="U") if is_surf: subsub = sub.column() diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py index 88fdaae0433..1523f69536f 100644 --- a/release/scripts/startup/bl_ui/properties_data_empty.py +++ b/release/scripts/startup/bl_ui/properties_data_empty.py @@ -49,11 +49,15 @@ class DATA_PT_empty(DataButtonsPanel, Panel): col.prop(ob, "empty_image_offset", text="Y", index=1) col = layout.column() - col.row().prop(ob, "empty_image_depth", text="Depth", expand=True) + depth_row = col.row() + depth_row.enabled = not ob.show_in_front + depth_row.prop(ob, "empty_image_depth", text="Depth", expand=True) col.row().prop(ob, "empty_image_side", text="Side", expand=True) - col.prop(ob, "show_empty_image_orthographic", text="Display Orthographic") - col.prop(ob, "show_empty_image_perspective", text="Display Perspective") - col.prop(ob, "show_empty_image_only_axis_aligned") + + col = layout.column(heading="Show in", align=True) + col.prop(ob, "show_empty_image_orthographic", text="Orthographic") + col.prop(ob, "show_empty_image_perspective", text="Perspective") + col.prop(ob, "show_empty_image_only_axis_aligned", text="Only Axis Aligned") class DATA_PT_empty_alpha(DataButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index 883673ffd7a..4ed5264549f 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -22,6 +22,7 @@ from bpy.types import Menu, Panel, UIList from rna_prop_ui import PropertyPanel from bl_ui.properties_grease_pencil_common import ( + GreasePencilLayerMasksPanel, GreasePencilLayerAdjustmentsPanel, GreasePencilLayerRelationsPanel, GreasePencilLayerDisplayPanel, @@ -116,7 +117,7 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): def draw(self, context): layout = self.layout - #layout.use_property_split = True + # layout.use_property_split = True layout.use_property_decorate = False gpd = context.gpencil @@ -166,7 +167,6 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): col = layout.column(align=True) if gpl: - layout = self.layout layout.use_property_split = True layout.use_property_decorate = True @@ -178,6 +178,15 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): col = layout.row(align=True) col.prop(gpl, "opacity", text="Opacity", slider=True) + col = layout.row(align=True) + col.prop(gpl, "use_lights") + + +class DATA_PT_gpencil_layer_masks(LayerDataButtonsPanel, GreasePencilLayerMasksPanel, Panel): + bl_label = "Masks" + bl_parent_id = 'DATA_PT_gpencil_layers' + bl_options = {'DEFAULT_CLOSED'} + class DATA_PT_gpencil_layer_adjustments(LayerDataButtonsPanel, GreasePencilLayerAdjustmentsPanel, Panel): bl_label = "Adjustments" @@ -264,7 +273,7 @@ class DATA_PT_gpencil_onion_skinning_display(DataButtonsPanel, Panel): col.prop(gpd, "use_onion_fade", text="Fade") sub = layout.column() sub.active = gpd.onion_mode in {'RELATIVE', 'SELECTED'} - sub.prop(gpd, "use_onion_loop", text="Loop") + sub.prop(gpd, "use_onion_loop", text="Show Start Frame") class GPENCIL_MT_gpencil_vertex_group(Menu): @@ -364,9 +373,6 @@ class DATA_PT_gpencil_strokes(DataButtonsPanel, Panel): sub.active = gpd.stroke_thickness_space == 'WORLDSPACE' sub.prop(gpd, "pixel_factor", text="Thickness Scale") - layout.prop(gpd, "use_force_fill_recalc", text="Force Fill Update") - layout.prop(gpd, "use_adaptive_uv", text="Adaptive UVs") - class DATA_PT_gpencil_display(DataButtonsPanel, Panel): bl_label = "Viewport Display" @@ -381,8 +387,6 @@ class DATA_PT_gpencil_display(DataButtonsPanel, Panel): gpl = gpd.layers.active layout.prop(gpd, "edit_line_color", text="Edit Line Color") - if gpl: - layout.prop(gpd, "show_stroke_direction", text="Show Stroke Directions") class DATA_PT_gpencil_canvas(DataButtonsPanel, Panel): @@ -411,6 +415,7 @@ class DATA_PT_custom_props_gpencil(DataButtonsPanel, PropertyPanel, Panel): _context_path = "object.data" _property_type = bpy.types.GreasePencil + ############################### @@ -420,6 +425,7 @@ classes = ( DATA_PT_gpencil_onion_skinning, DATA_PT_gpencil_onion_skinning_custom_colors, DATA_PT_gpencil_onion_skinning_display, + DATA_PT_gpencil_layer_masks, DATA_PT_gpencil_layer_adjustments, DATA_PT_gpencil_layer_relations, DATA_PT_gpencil_layer_display, @@ -437,5 +443,6 @@ classes = ( if __name__ == "__main__": # only for live edit. from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_hair.py b/release/scripts/startup/bl_ui/properties_data_hair.py new file mode 100644 index 00000000000..6017765b83d --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_hair.py @@ -0,0 +1,78 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Panel, UIList +from rna_prop_ui import PropertyPanel + + +class DataButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + + @classmethod + def poll(cls, context): + engine = context.scene.render.engine + return hasattr(context, 'hair') and context.hair and (engine in cls.COMPAT_ENGINES) + + +class DATA_PT_context_hair(DataButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + + ob = context.object + hair = context.hair + space = context.space_data + + if ob: + layout.template_ID(ob, "data") + elif hair: + layout.template_ID(space, "pin_id") + + +class DATA_PT_hair(DataButtonsPanel, Panel): + bl_label = "Hair" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + hair = context.hair + pass + +class DATA_PT_custom_props_hair(DataButtonsPanel, PropertyPanel, Panel): + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + _context_path = "object.data" + _property_type = bpy.types.Hair if hasattr(bpy.types, "Hair") else None + + +classes = ( + DATA_PT_context_hair, + DATA_PT_hair, + DATA_PT_custom_props_hair, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 3edce6b3b52..425c94dfdcd 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -55,9 +55,12 @@ class MESH_MT_vertex_group_context_menu(Menu): layout.operator("object.vertex_group_remove", text="Delete All Unlocked Groups").all_unlocked = True layout.operator("object.vertex_group_remove", text="Delete All Groups").all = True layout.separator() - layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All").action = 'LOCK' - layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All").action = 'UNLOCK' - layout.operator("object.vertex_group_lock", text="Lock Invert All").action = 'INVERT' + props = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All") + props.action, props.mask = 'LOCK', 'ALL' + props = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All") + props.action, props.mask = 'UNLOCK', 'ALL' + props = layout.operator("object.vertex_group_lock", text="Lock Invert All") + props.action, props.mask = 'INVERT', 'ALL' class MESH_MT_shape_key_context_menu(Menu): @@ -187,27 +190,20 @@ class DATA_PT_normals(MeshButtonsPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} def draw(self, context): - pass - - -class DATA_PT_normals_auto_smooth(MeshButtonsPanel, Panel): - bl_label = "Auto Smooth" - bl_parent_id = "DATA_PT_normals" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} - - def draw_header(self, context): - mesh = context.mesh - - self.layout.prop(mesh, "use_auto_smooth", text="") - - def draw(self, context): layout = self.layout layout.use_property_split = True mesh = context.mesh - layout.active = mesh.use_auto_smooth and not mesh.has_custom_normals - layout.prop(mesh, "auto_smooth_angle", text="Angle") + col = layout.column(align=False, heading="Auto Smooth") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(mesh, "use_auto_smooth", text="") + sub = sub.row(align=True) + sub.active = mesh.use_auto_smooth and not mesh.has_custom_normals + sub.prop(mesh, "auto_smooth_angle", text="") + row.prop_decorator(mesh, "auto_smooth_angle") class DATA_PT_texture_space(MeshButtonsPanel, Panel): @@ -482,8 +478,11 @@ class DATA_PT_remesh(MeshButtonsPanel, Panel): col.prop(mesh, "remesh_voxel_adaptivity") col.prop(mesh, "use_remesh_fix_poles") col.prop(mesh, "use_remesh_smooth_normals") - col.prop(mesh, "use_remesh_preserve_volume") - col.prop(mesh, "use_remesh_preserve_paint_mask") + + col = layout.column(heading="Preserve") + col.prop(mesh, "use_remesh_preserve_volume", text="Volume") + col.prop(mesh, "use_remesh_preserve_paint_mask", text="Paint Mask") + col.prop(mesh, "use_remesh_preserve_sculpt_face_sets", text="Face Sets") col.operator("object.voxel_remesh", text="Voxel Remesh") else: col.operator("object.quadriflow_remesh", text="QuadriFlow Remesh") @@ -511,12 +510,12 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): else: col.operator("mesh.customdata_custom_splitnormals_add", icon='ADD') - col = layout.column() + col = layout.column(heading="Store") col.enabled = obj is not None and obj.mode != 'EDIT' - col.prop(me, "use_customdata_vertex_bevel") - col.prop(me, "use_customdata_edge_bevel") - col.prop(me, "use_customdata_edge_crease") + col.prop(me, "use_customdata_vertex_bevel", text="Vertex Bevel Weight") + col.prop(me, "use_customdata_edge_bevel", text="Edge Bevel Weight") + col.prop(me, "use_customdata_edge_crease", text="Edge Crease") class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): @@ -540,7 +539,6 @@ classes = ( DATA_PT_vertex_colors, DATA_PT_face_maps, DATA_PT_normals, - DATA_PT_normals_auto_smooth, DATA_PT_texture_space, DATA_PT_remesh, DATA_PT_customdata, diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 197566f16f3..75e9a320130 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -170,7 +170,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.limit_method == 'ANGLE': layout.prop(md, "angle_limit") elif md.limit_method == 'VGROUP': - layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = layout.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') layout.label(text="Face Strength Mode:") layout.row().prop(md, "face_strength_mode", expand=True) @@ -316,7 +318,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "object", text="") col = split.column() col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') layout.label(text="Deformation Axis:") layout.row().prop(md, "deform_axis", expand=True) @@ -381,7 +385,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.label(text="Space:") col.prop(md, "space", text="") col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') col = split.column(align=True) col.active = has_texture @@ -390,6 +396,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.texture_coords == 'OBJECT': col.label(text="Object:") col.prop(md, "texture_coords_object", text="") + obj = md.texture_coords_object + if obj and obj.type == 'ARMATURE': + col.label(text="Bone:") + col.prop_search(md, "texture_coords_bone", obj.data, "bones", text="") elif md.texture_coords == 'UV' and ob.type == 'MESH': col.label(text="UV Map:") col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="") @@ -419,7 +429,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') sub = col.column() sub.active = bool(md.vertex_group) sub.prop(md, "protect") @@ -450,7 +462,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop_search(md, "subtarget", md.object.data, "bones", text="") col = split.column() col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') layout.separator() @@ -484,13 +498,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.prop(md, "iterations") - row = layout.row() - row.active = not is_bind - row.label(text="Anchors Vertex Group:") - - row = layout.row() + row = layout.row(align=True) row.enabled = not is_bind - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop_search(md, "vertex_group", ob, "vertex_groups") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') layout.separator() @@ -519,7 +530,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "use_normalized") layout.label(text="Vertex Group:") - layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = layout.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') def LATTICE(self, layout, ob, md): split = layout.split() @@ -530,7 +543,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') layout.separator() layout.prop(md, "strength", slider=True) @@ -640,6 +655,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row = layout.row() row.prop(md, "use_mirror_u", text="Flip U") row.prop(md, "use_mirror_v", text="Flip V") + row = layout.row() + row.prop(md, "use_mirror_udim", text="Flip UDIM") col = layout.column(align=True) @@ -654,26 +671,53 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "offset_v") def MULTIRES(self, layout, ob, md): - layout.row().prop(md, "subdivision_type", expand=True) + # Changing some of the properties can not be done once there is an + # actual displacement stored for this multires modifier. This check + # will disallow those properties from change. + # This is a bit stupid check but should be sufficient for the usual + # multires usage. It might become less strict and only disallow + # modifications if there is CD_MDISPS layer, or if there is actual + # non-zero displacement but such checks will be too slow to be done + # on every redraw. + have_displacement = (md.total_levels != 0) + + row = layout.row() + row.enabled = not have_displacement + row.prop(md, "subdivision_type", expand=True) split = layout.split() col = split.column() col.prop(md, "levels", text="Preview") - # TODO(sergey): Expose it again after T58473 is solved. - # col.prop(md, "sculpt_levels", text="Sculpt") + col.prop(md, "sculpt_levels", text="Sculpt") col.prop(md, "render_levels", text="Render") - col.prop(md, "quality") + + row = col.row() + row.enabled = not have_displacement + row.prop(md, "quality") col = split.column() col.enabled = ob.mode != 'EDIT' - col.operator("object.multires_subdivide", text="Subdivide") + op = col.operator("object.multires_subdivide", text="Subdivide") + op.mode = 'CATMULL_CLARK' + + op = col.operator("object.multires_subdivide", text="Subdivide Simple") + op.mode = 'SIMPLE' + + op = col.operator("object.multires_subdivide", text="Subdivide Linear") + op.mode = 'LINEAR' + col.operator("object.multires_higher_levels_delete", text="Delete Higher") + col.operator("object.multires_unsubdivide", text="Unsubdivide") col.operator("object.multires_reshape", text="Reshape") col.operator("object.multires_base_apply", text="Apply Base") + col.operator("object.multires_rebuild_subdiv", text="Rebuild Subdivisions") col.prop(md, "uv_smooth", text="") col.prop(md, "show_only_control_edges") - col.prop(md, "use_creases") + + row = col.row() + row.enabled = not have_displacement + row.prop(md, "use_creases") layout.separator() @@ -714,6 +758,19 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "size") col.prop(md, "spatial_size") + layout.separator() + + layout.prop(md, "spectrum") + + if md.spectrum in {'TEXEL_MARSEN_ARSLOE', 'JONSWAP'}: + split = layout.split() + + col = split.column() + col.prop(md, "sharpen_peak_jonswap") + + col = split.column() + col.prop(md, "fetch_jonswap") + layout.label(text="Waves:") split = layout.split() @@ -963,7 +1020,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "factor") col.prop(md, "iterations") col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') def SOFT_BODY(self, layout, _ob, _md): layout.label(text="Settings are inside the Physics tab") @@ -998,12 +1057,23 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): sub = col.row() sub.active = bool(md.vertex_group) sub.prop(md, "thickness_vertex_group", text="Factor") + if solidify_mode == 'NON_MANIFOLD': + sub = col.row() + sub.active = bool(md.vertex_group) + sub.prop(md, "use_flat_faces") if solidify_mode == 'EXTRUDE': col.label(text="Crease:") col.prop(md, "edge_crease_inner", text="Inner") col.prop(md, "edge_crease_outer", text="Outer") col.prop(md, "edge_crease_rim", text="Rim") + col.label(text="Bevel:") + col.prop(md, "bevel_convex") + else: + col.label(text="Bevel:") + col.prop(md, "bevel_convex") + col.separator() + col.prop(md, "nonmanifold_merge_threshold") col = split.column() @@ -1031,6 +1101,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row.active = md.use_rim row.prop(md, "material_offset_rim", text="Rim") + col.separator() + + row = col.row(align=True) + row.label(text="Shell Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "shell_vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.label(text="Rim Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "rim_vertex_group", ob, "vertex_groups", text="") + def SUBSURF(self, layout, ob, md): from bpy import context layout.row().prop(md, "subdivision_type", expand=True) @@ -1089,13 +1170,24 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.label(text="Settings are inside the Physics tab") def SURFACE_DEFORM(self, layout, _ob, md): - col = layout.column() + split = layout.split() + col = split.column() col.active = not md.is_bound - col.prop(md, "target") - col.prop(md, "falloff") + col.label(text="Target:") + col.prop(md, "target", text="") - layout.separator() + col = split.column() + col.label(text="Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", _ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') + + split = layout.split() + col = split.column() + col.prop(md, "falloff") + col = split.column() + col.prop(md, "strength") col = layout.column() @@ -1132,12 +1224,30 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.label(text="From:") col.prop(md, "object_from", text="") - col.prop(md, "use_volume_preserve") - col = split.column() col.label(text="To:") col.prop(md, "object_to", text="") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + + split = layout.split() + col = split.column() + obj = md.object_from + if obj and obj.type == 'ARMATURE': + col.label(text="Bone:") + col.prop_search(md, "bone_from", obj.data, "bones", text="") + + col = split.column() + obj = md.object_to + if obj and obj.type == 'ARMATURE': + col.label(text="Bone:") + col.prop_search(md, "bone_to", obj.data, "bones", text="") + + split = layout.split() + col = split.column() + col.prop(md, "use_volume_preserve") + col = split.column() + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') col = layout.column() @@ -1163,6 +1273,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.texture_coords == 'OBJECT': layout.prop(md, "texture_coords_object", text="Object") + obj = md.texture_coords_object + if obj and obj.type == 'ARMATURE': + layout.prop_search(md, "texture_coords_bone", obj.data, "bones", text="Bone") elif md.texture_coords == 'UV' and ob.type == 'MESH': layout.prop_search(md, "uv_layer", ob.data, "uv_layers") @@ -1202,7 +1315,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.separator() layout.prop(md, "start_position_object") - layout.prop_search(md, "vertex_group", ob, "vertex_groups") + row = layout.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') split = layout.split(factor=0.33) col = split.column() col.label(text="Texture") @@ -1213,6 +1328,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.prop_search(md, "uv_layer", ob.data, "uv_layers") elif md.texture_coords == 'OBJECT': layout.prop(md, "texture_coords_object") + obj = md.texture_coords_object + if obj and obj.type == 'ARMATURE': + layout.prop_search(md, "texture_coords_bone", obj.data, "bones") layout.separator() @@ -1234,17 +1352,22 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.prop(md, "mode") row = layout.row() - row.prop(md, "octree_depth") - row.prop(md, "scale") + if md.mode == 'VOXEL': + layout.prop(md, "voxel_size") + layout.prop(md, "adaptivity") + else: + row.prop(md, "octree_depth") + row.prop(md, "scale") - if md.mode == 'SHARP': - layout.prop(md, "sharpness") + if md.mode == 'SHARP': + layout.prop(md, "sharpness") + + layout.prop(md, "use_remove_disconnected") + row = layout.row() + row.active = md.use_remove_disconnected + row.prop(md, "threshold") layout.prop(md, "use_smooth_shade") - layout.prop(md, "use_remove_disconnected") - row = layout.row() - row.active = md.use_remove_disconnected - row.prop(md, "threshold") @staticmethod def vertex_weight_mask(layout, ob, md): @@ -1257,7 +1380,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if not md.mask_texture: split = layout.split(factor=0.4) split.label(text="Vertex Group Mask:") - split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="") + row = split.row(align=True) + row.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_mask_vertex_group", text="", icon='ARROW_LEFTRIGHT') if not md.mask_vertex_group: split = layout.split(factor=0.4) @@ -1276,6 +1401,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.mask_tex_mapping == 'OBJECT': layout.prop(md, "mask_tex_map_object", text="Object") + obj = md.mask_tex_map_object + if obj and obj.type == 'ARMATURE': + layout.prop_search(md, "mask_tex_map_bone", obj.data, "bones", text="Bone") elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH': layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_layers") @@ -1303,7 +1431,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.separator() - layout.prop(md, "falloff_type") + row = layout.row(align=True) + row.prop(md, "falloff_type") + row.prop(md, "invert_falloff", text="", icon='ARROW_LEFTRIGHT') if md.falloff_type == 'CURVE': layout.template_curve_mapping(md, "map_curve") @@ -1361,7 +1491,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "max_dist") layout.separator() - layout.prop(md, "falloff_type") + row = layout.row(align=True) + row.prop(md, "falloff_type") + row.prop(md, "invert_falloff", text="", icon='ARROW_LEFTRIGHT') # Common mask options layout.separator() @@ -1442,10 +1574,25 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop_search(md, "bone_to", obj.data, "bones", text="") split = layout.split() + col = split.column() + col.label(text="Offset:") + col.prop(md, "offset", text="") + + col = split.column() + col.label(text="Scale:") + col.prop(md, "scale", text="") + + col = split.column() + col.label(text="Rotate:") + col.prop(md, "rotation", text="") + + split = layout.split() col = split.column() col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') col = split.column() col.label(text="UV Map:") @@ -1486,7 +1633,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): def WELD(self, layout, ob, md): layout.prop(md, "merge_threshold", text="Distance") layout.prop(md, "max_interactions") - layout.prop_search(md, "vertex_group", ob, "vertex_groups") + row = layout.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') def DATA_TRANSFER(self, layout, ob, md): row = layout.row(align=True) @@ -1641,7 +1790,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.prop(md, "factor", text="Factor") layout.prop(md, "iterations") - + layout.prop(md, "scale") row = layout.row() row.prop(md, "smooth_type") @@ -1677,6 +1826,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "thresh", text="Threshold") col.prop(md, "face_influence") + def SIMULATION(self, layout, ob, md): + layout.prop(md, "simulation") + layout.prop(md, "data_path") + class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): bl_label = "Modifiers" @@ -1710,132 +1863,110 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): # ...to avoid lengthy if statements # so each type must have a function here. - def GP_NOISE(self, layout, ob, md): + def gpencil_masking(self, layout, ob, md, use_vertex, use_curve=False): gpd = ob.data - split = layout.split() - - col = split.column() - row = col.row(align=True) - row.prop(md, "factor") - row.prop(md, "random", text="", icon='TIME', toggle=True) - row = col.row() - row.enabled = md.random - row.prop(md, "step") - row = col.row() - row.enabled = md.random - row.prop(md, "seed") - col.prop(md, "full_stroke") - col.prop(md, "move_extreme") - - row = layout.row(align=True) - row.label(text="Affect:") - row = layout.row(align=True) - row.prop(md, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True) - row.prop(md, "use_edit_strength", text="Strength", icon='COLOR', toggle=True) - row.prop(md, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True) - row.prop(md, "use_edit_uv", text="UV", icon='MOD_UVPROJECT', toggle=True) + layout.separator() + layout.label(text="Influence Filters:") - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') + split = layout.split(factor=0.25) - col = layout.column() - col.separator() + col1 = split.column() - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + col1.label(text="Layer:") + col1.label(text="Material:") + if use_vertex: + col1.label(text="Vertex Group:") - col = layout.column() - col.separator() + col2 = split.column() - col.label(text="Layer:") - row = col.row(align=True) + split = col2.split(factor=0.6) + row = split.row(align=True) row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) + + row = split.row(align=True) row.prop(md, "layer_pass", text="Pass") row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') - def GP_SMOOTH(self, layout, ob, md): - gpd = ob.data - col = layout.column() - col.prop(md, "factor") - col.prop(md, "step") + split = col2.split(factor=0.6) - col.label(text="Affect:") - row = col.row(align=True) - row.prop(md, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True) - row.prop(md, "use_edit_strength", text="Strength", icon='COLOR', toggle=True) - row.prop(md, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True) - row.prop(md, "use_edit_uv", text="UV", icon='MOD_UVPROJECT', toggle=True) - - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') + row = split.row(align=True) - col = layout.column() - col.separator() + valid = md.material in (slot.material for slot in ob.material_slots) or md.material is None + if valid: + icon = 'SHADING_TEXTURE' + else: + icon = 'ERROR' - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') + row.alert = not valid + row.prop_search(md, "material", gpd, "materials", text="", icon=icon) row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) + + row = split.row(align=True) row.prop(md, "pass_index", text="Pass") row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - col = layout.column() - col.separator() + if use_vertex: + row = col2.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + if use_curve: + col = layout.column() + col.separator() + col.prop(md, "use_custom_curve") + if md.use_custom_curve: + col.template_curve_mapping(md, "curve") - def GP_SUBDIV(self, layout, ob, md): - gpd = ob.data + def GP_NOISE(self, layout, ob, md): split = layout.split() col = split.column() row = col.row(align=True) - row.prop(md, "level") - row.prop(md, "simple", text="", icon='PARTICLE_POINT') + row.prop(md, "factor", text="Position") + row = col.row(align=True) + row.prop(md, "factor_strength", text="Strength") + row = col.row(align=True) + row.prop(md, "factor_thickness", text="Thickness") + row = col.row(align=True) + row.prop(md, "factor_uvs", text="UV") - col = layout.column() col.separator() - - col.label(text="Material:") row = col.row(align=True) + row.prop(md, "random", text="", icon='TIME', toggle=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + subrow = row.row(align=True) + subrow.enabled = md.random + subrow.prop(md, "step") + subrow.prop(md, "seed") - col = layout.column() col.separator() + col.prop(md, "noise_scale") + + self.gpencil_masking(layout, ob, md, True, True) - col.label(text="Layer:") + def GP_SMOOTH(self, layout, ob, md): + col = layout.column() + col.prop(md, "factor") + col.prop(md, "step", text="Repeat") + + col.label(text="Affect:") row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + row.prop(md, "use_edit_position", text="Position", toggle=True) + row.prop(md, "use_edit_strength", text="Strength", toggle=True) + row.prop(md, "use_edit_thickness", text="Thickness", toggle=True) + row.prop(md, "use_edit_uv", text="UV", toggle=True) + + self.gpencil_masking(layout, ob, md, True, True) + + def GP_SUBDIV(self, layout, ob, md): + layout.row().prop(md, "subdivision_type", expand=True) + split = layout.split() + col = split.column() + row = col.row(align=True) + row.prop(md, "level", text="Subdivisions") + + self.gpencil_masking(layout, ob, md, False) def GP_SIMPLIFY(self, layout, ob, md): gpd = ob.data @@ -1857,108 +1988,70 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): elif md.mode == 'MERGE': col.prop(md, "distance") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False) def GP_THICK(self, layout, ob, md): - gpd = ob.data - split = layout.split() - - col = split.column() - row = col.row(align=True) - row.prop(md, "thickness", text="Thickness Factor") + col = layout.column() col.prop(md, "normalize_thickness") - if not md.normalize_thickness: - split = layout.split() - col = split.column() - col.prop(md, "use_custom_curve") + if md.normalize_thickness: + col.prop(md, "thickness") + else: + col.prop(md, "thickness_factor") - if md.use_custom_curve: - col.template_curve_mapping(md, "curve") + self.gpencil_masking(layout, ob, md, True, True) + def GP_TEXTURE(self, layout, ob, md): col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - col = layout.column() - col.separator() + col.prop(md, "mode") + if md.mode in {'STROKE', 'STROKE_AND_FILL'}: + col.label(text="Stroke Texture:") + col.prop(md, "fit_method") + col.prop(md, "uv_offset") + col.prop(md, "uv_scale") - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + if md.mode == 'STROKE_AND_FILL': + col.separator() - col = layout.column() - col.separator() + if md.mode in {'FILL', 'STROKE_AND_FILL'}: + col.label(text="Fill Texture:") + col.prop(md, "fill_rotation", text="Rotation") + col.prop(md, "fill_offset", text="Location") + col.prop(md, "fill_scale", text="Scale") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True) def GP_TINT(self, layout, ob, md): - gpd = ob.data - split = layout.split() + layout.row().prop(md, "tint_type", expand=True) - col = split.column() - col.prop(md, "color") - col.prop(md, "factor") + if md.tint_type == 'UNIFORM': + col = layout.column() + col.prop(md, "color") - row = layout.row() - row.prop(md, "create_materials") - row.prop(md, "modify_color") + col.separator() + col.prop(md, "factor") - col = layout.column() - col.separator() + if md.tint_type == 'GRADIENT': + col = layout.column() + col.label(text="Colors:") + col.template_color_ramp(md, "colors") - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + col.separator() + + col.label(text="Object:") + col.prop(md, "object", text="") + + col.separator() + row = col.row(align=True) + row.prop(md, "radius") + row.prop(md, "factor") - col = layout.column() col.separator() + col.prop(md, "vertex_mode") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True, True) def GP_TIME(self, layout, ob, md): gpd = ob.data @@ -2004,7 +2097,6 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') def GP_COLOR(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() @@ -2014,134 +2106,71 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "value", text="V", slider=True) row = layout.row() - row.prop(md, "create_materials") row.prop(md, "modify_color") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False, True) def GP_OPACITY(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() - col.label(text="Opacity:") - col.prop(md, "factor") + col.prop(md, "modify_color") - row = layout.row() - row.prop(md, "opacity_mode", text="Mode") - - if md.opacity_mode == 'MATERIAL': - row = layout.row() - row.prop(md, "create_materials") - row.prop(md, "modify_color", text="Change") + if md.modify_color == 'HARDNESS': + col.prop(md, "hardness") + show = False else: - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() + col.prop(md, "normalize_opacity") + if md.normalize_opacity is True: + text="Strength" + else: + text="Opacity Factor" - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + col.prop(md, "factor", text=text) + show = True + self.gpencil_masking(layout, ob, md, show, show) def GP_ARRAY(self, layout, ob, md): - gpd = ob.data - col = layout.column() col.prop(md, "count") split = layout.split() col = split.column() - col.label(text="Offset:") - col.prop(md, "offset", text="") - col.prop(md, "offset_object", text="Object") + col.prop(md, "use_constant_offset", text="Constant Offset") + subcol = col.column() + subcol.enabled = md.use_constant_offset + subcol.prop(md, "constant_offset", text="") + + col.prop(md, "use_object_offset") + subcol = col.column() + subcol.enabled = md.use_object_offset + subcol.prop(md, "offset_object", text="") col = split.column() - col.label(text="Shift:") - col.prop(md, "shift", text="") + col.prop(md, "use_relative_offset", text="Relative Offset") + subcol = col.column() + subcol.enabled = md.use_relative_offset + subcol.prop(md, "relative_offset", text="") split = layout.split() col = split.column() - col.label(text="Rotation:") - col.prop(md, "rotation", text="") - col.separator() - row = col.row(align=True) - row.prop(md, "random_rot", text="", icon='TIME', toggle=True) - row.prop(md, "rot_factor", text="") + col.label(text="Random Offset:") + col.prop(md, "random_offset", text="") col = split.column() - col.label(text="Scale:") - col.prop(md, "scale", text="") - col.separator() - row = col.row(align=True) - row.prop(md, "random_scale", text="", icon='TIME', toggle=True) - row.prop(md, "scale_factor", text="") - - col = layout.column() - col.prop(md, "replace_material", text="Material") - col.prop(md, "keep_on_top", text="Keep original stroke on top") + col.label(text="Random Rotation:") + col.prop(md, "random_rotation", text="") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + col = split.column() + col.label(text="Random Scale:") + col.prop(md, "random_scale", text="") col = layout.column() + col.prop(md, "seed") col.separator() + col.prop(md, "replace_material", text="Material Override") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False) def GP_BUILD(self, layout, ob, md): gpd = ob.data @@ -2168,18 +2197,31 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): sub.prop(md, "frame_start", text="Start") sub.prop(md, "frame_end", text="End") - col = layout.column() - col.separator() - col.label(text="Layer:") - row = col.row(align=True) + col.prop(md, "use_percentage") + sub = col.column(align=True) + sub.active = md.use_percentage + sub.prop(md, "percentage_factor") + + layout.label(text="Influence Filters:") + + split = layout.split(factor=0.25) + + col1 = split.column() + + col1.label(text="Layer:") + + col2 = split.column() + + split = col2.split(factor=0.6) + row = split.row(align=True) row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) + + row = split.row(align=True) row.prop(md, "layer_pass", text="Pass") row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') def GP_LATTICE(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() @@ -2188,70 +2230,20 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): layout.prop(md, "strength", slider=True) - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True) def GP_MIRROR(self, layout, ob, md): - gpd = ob.data - row = layout.row(align=True) row.prop(md, "x_axis") row.prop(md, "y_axis") row.prop(md, "z_axis") - layout.label(text="Object:") + layout.label(text="Mirror Object:") layout.prop(md, "object", text="") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False) def GP_HOOK(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() @@ -2281,71 +2273,16 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.prop(md, "use_falloff_uniform") - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True) def GP_OFFSET(self, layout, ob, md): - gpd = ob.data - col = layout.column() - - col.prop(md, "location") - col.prop(md, "scale") - col.prop(md, "rotation") - - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + split = layout.split() - col = layout.column() - col.separator() + split.column().prop(md, "location") + split.column().prop(md, "rotation") + split.column().prop(md, "scale") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True) def GP_ARMATURE(self, layout, ob, md): split = layout.split() @@ -2371,50 +2308,23 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') def GP_MULTIPLY(self, layout, ob, md): - gpd = ob.data col = layout.column() - col.prop(md, "duplications") + col.prop(md, "duplicates") subcol = col.column() - subcol.enabled = md.duplications > 0 + subcol.enabled = md.duplicates > 0 subcol.prop(md, "distance") subcol.prop(md, "offset", slider=True) subcol.separator() - subcol.prop(md, "enable_fading") - if md.enable_fading: + subcol.prop(md, "use_fade") + if md.use_fade: subcol.prop(md, "fading_center") subcol.prop(md, "fading_thickness", slider=True) subcol.prop(md, "fading_opacity", slider=True) - subcol.separator() - - col.prop(md, "enable_angle_splitting") - if md.enable_angle_splitting: - col.prop(md, "split_angle") - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False) classes = ( @@ -2424,5 +2334,6 @@ classes = ( if __name__ == "__main__": # only for live edit. from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_pointcloud.py b/release/scripts/startup/bl_ui/properties_data_pointcloud.py new file mode 100644 index 00000000000..10ebdea3155 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_pointcloud.py @@ -0,0 +1,78 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Panel, UIList +from rna_prop_ui import PropertyPanel + + +class DataButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + + @classmethod + def poll(cls, context): + engine = context.scene.render.engine + return hasattr(context, 'pointcloud') and context.pointcloud and (engine in cls.COMPAT_ENGINES) + + +class DATA_PT_context_pointcloud(DataButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + + ob = context.object + pointcloud = context.pointcloud + space = context.space_data + + if ob: + layout.template_ID(ob, "data") + elif pointcloud: + layout.template_ID(space, "pin_id") + + +class DATA_PT_pointcloud(DataButtonsPanel, Panel): + bl_label = "Point Cloud" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + pointcloud = context.pointcloud + pass + +class DATA_PT_custom_props_pointcloud(DataButtonsPanel, PropertyPanel, Panel): + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + _context_path = "object.data" + _property_type = bpy.types.PointCloud if hasattr(bpy.types, "PointCloud") else None + + +classes = ( + DATA_PT_context_pointcloud, + DATA_PT_pointcloud, + DATA_PT_custom_props_pointcloud, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_shaderfx.py b/release/scripts/startup/bl_ui/properties_data_shaderfx.py index fce86446dfc..1d4bf37b282 100644 --- a/release/scripts/startup/bl_ui/properties_data_shaderfx.py +++ b/release/scripts/startup/bl_ui/properties_data_shaderfx.py @@ -56,27 +56,30 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): def FX_BLUR(self, layout, fx): - layout.prop(fx, "factor", text="Factor") + layout.prop(fx, "use_dof_mode", text="Use Depth of Field") + layout.separator() + + col = layout.column() + col.enabled = not fx.use_dof_mode + col.prop(fx, "size", text="Size") + col.separator() + col.prop(fx, "rotation") + layout.prop(fx, "samples", text="Samples") - layout.separator() - layout.prop(fx, "use_dof_mode") - if fx.use_dof_mode: - layout.prop(fx, "coc") def FX_COLORIZE(self, layout, fx): layout.prop(fx, "mode", text="Mode") - if fx.mode == 'BITONE': + if fx.mode == 'DUOTONE': layout.prop(fx, "low_color", text="Low Color") if fx.mode == 'CUSTOM': layout.prop(fx, "low_color", text="Color") - if fx.mode == 'BITONE': + if fx.mode == 'DUOTONE': layout.prop(fx, "high_color", text="High Color") - if fx.mode in {'BITONE', 'CUSTOM', 'TRANSPARENT'}: - layout.prop(fx, "factor") + layout.prop(fx, "factor") def FX_WAVE(self, layout, fx): row = layout.row(align=True) @@ -95,7 +98,7 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): layout.prop(fx, "rim_color") layout.prop(fx, "mask_color") - layout.prop(fx, "mode") + layout.prop(fx, "mode", text="Blend") layout.prop(fx, "blur") layout.prop(fx, "samples") @@ -111,7 +114,7 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): layout.prop(fx, "samples") layout.separator() - layout.prop(fx, "use_object", text="Use Object As Pivot") + layout.prop(fx, "use_object", text="Use Object as Pivot") if fx.use_object: row = layout.row() row.prop(fx, "object", text="Object") @@ -127,16 +130,21 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): def FX_GLOW(self, layout, fx): layout.prop(fx, "mode") - layout.prop(fx, "glow_color") if fx.mode == 'LUMINANCE': layout.prop(fx, "threshold") else: layout.prop(fx, "select_color") + layout.prop(fx, "glow_color") layout.separator() - layout.prop(fx, "radius") + layout.prop(fx, "blend_mode", text="Blend") + layout.prop(fx, "opacity") + + layout.prop(fx, "size") + layout.prop(fx, "rotation") layout.prop(fx, "samples") - layout.prop(fx, "use_alpha_mode", text="Use Alpha Mode") + + layout.prop(fx, "use_glow_under", text="Glow Under") def FX_SWIRL(self, layout, fx): layout.prop(fx, "object", text="Object") @@ -144,18 +152,10 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): layout.prop(fx, "radius") layout.prop(fx, "angle") - layout.prop(fx, "use_transparent") - def FX_FLIP(self, layout, fx): layout.prop(fx, "flip_horizontal") layout.prop(fx, "flip_vertical") - def FX_LIGHT(self, layout, fx): - layout.prop(fx, "object", text="Object") - - layout.prop(fx, "energy") - layout.prop(fx, "ambient") - classes = ( DATA_PT_shader_fx, diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py new file mode 100644 index 00000000000..b10bb808edd --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_volume.py @@ -0,0 +1,174 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Panel, UIList +from rna_prop_ui import PropertyPanel + + +class DataButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + + @classmethod + def poll(cls, context): + engine = context.scene.render.engine + return context.volume and (engine in cls.COMPAT_ENGINES) + + +class DATA_PT_context_volume(DataButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + + ob = context.object + volume = context.volume + space = context.space_data + + if ob: + layout.template_ID(ob, "data") + elif volume: + layout.template_ID(space, "pin_id") + + +class DATA_PT_volume_file(DataButtonsPanel, Panel): + bl_label = "OpenVDB File" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + + volume = context.volume + volume.grids.load() + + layout.prop(volume, "filepath", text="") + + if len(volume.filepath): + layout.use_property_split = True + layout.use_property_decorate = False + + col = layout.column(align=True) + col.prop(volume, "is_sequence") + if volume.is_sequence: + col.prop(volume, "frame_duration", text="Frames") + col.prop(volume, "frame_start", text="Start") + col.prop(volume, "frame_offset", text="Offset") + col.prop(volume, "sequence_mode", text="Mode") + + error_msg = volume.grids.error_message + if len(error_msg): + layout.separator() + col = layout.column(align=True) + col.label(text="Failed to load volume:") + col.label(text=error_msg) + + +class VOLUME_UL_grids(UIList): + def draw_item(self, context, layout, data, grid, icon, active_data, active_propname, index): + name = grid.name + data_type = grid.bl_rna.properties['data_type'].enum_items[grid.data_type] + + layout.label(text=name) + row = layout.row() + row.alignment = 'RIGHT' + row.active = False + row.label(text=data_type.name) + + +class DATA_PT_volume_grids(DataButtonsPanel, Panel): + bl_label = "Grids" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + + volume = context.volume + volume.grids.load() + + layout.template_list("VOLUME_UL_grids", "grids", volume, "grids", volume.grids, "active_index", rows=3) + + +class DATA_PT_volume_render(DataButtonsPanel, Panel): + bl_label = "Render" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + volume = context.volume + render = volume.render + + col = layout.column(align=True) + col.prop(render, "space") + + if scene.render.engine == 'CYCLES': + col.prop(render, "step_size") + + col = layout.column(align=True) + col.prop(render, "clipping") + + +class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel): + bl_label = "Viewport Display" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + volume = context.volume + display = volume.display + + col = layout.column(align=True) + col.prop(display, "wireframe_type") + sub = col.row() + sub.active = display.wireframe_type in {'BOXES', 'POINTS'} + sub.prop(display, "wireframe_detail", text="Detail") + + layout.prop(display, "density") + + +class DATA_PT_custom_props_volume(DataButtonsPanel, PropertyPanel, Panel): + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + _context_path = "object.data" + _property_type = bpy.types.Volume + + +classes = ( + DATA_PT_context_volume, + DATA_PT_volume_grids, + DATA_PT_volume_file, + DATA_PT_volume_viewport_display, + DATA_PT_volume_render, + DATA_PT_custom_props_volume, + VOLUME_UL_grids, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py index 5fc03e59f9d..f70789ebeed 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -126,6 +126,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): row = layout.row() layout.prop(freestyle, "mode", text="Control Mode") layout.prop(freestyle, "use_view_map_cache", text="View Map Cache") + layout.prop(freestyle, "as_render_pass", text="As Render Pass") layout.label(text="Edge Detection Options:") split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 2001f46820f..64eda42c87a 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -19,7 +19,7 @@ # <pep8 compliant> import bpy -from bpy.types import Menu, UIList +from bpy.types import Menu, UIList, Operator from bpy.app.translations import pgettext_iface as iface_ @@ -44,38 +44,6 @@ def gpencil_stroke_placement_settings(context, layout): row.prop_enum(tool_settings, propname, 'CURSOR', text="Cursor") -def gpencil_active_brush_settings_simple(context, layout): - tool_settings = context.tool_settings - brush = tool_settings.gpencil_paint.brush - if brush is None: - layout.label(text="No Active Brush") - return - - col = layout.column() - col.label(text="Active Brush: ") - - row = col.row(align=True) - row.operator_context = 'EXEC_REGION_WIN' - row.operator_menu_enum("gpencil.brush_change", "brush", text="", icon='BRUSH_DATA') - row.prop(brush, "name", text="") - - col.prop(brush, "size", slider=True) - row = col.row(align=True) - row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE') - row.prop(brush, "pen_sensitivity_factor", slider=True) - row.prop(brush, "use_pressure", text="", icon='STYLUS_PRESSURE') - row = col.row(align=True) - row.prop(brush, "use_random_strength", text="", icon='RNDCURVE') - row.prop(brush, "strength", slider=True) - row.prop(brush, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') - row = col.row(align=True) - row.prop(brush, "jitter", slider=True) - row.prop(brush, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') - row = col.row() - row.prop(brush, "angle", slider=True) - row.prop(brush, "angle_factor", text="Factor", slider=True) - - # XXX: To be replaced with active tools class AnnotationDrawingToolsPanel: # subclass must set @@ -108,11 +76,6 @@ class AnnotationDrawingToolsPanel: sub.operator("gpencil.blank_frame_add", icon='FILE_NEW') sub.operator("gpencil.active_frames_delete_all", icon='X', text="Delete Frame(s)") - #sub = col.column(align=True) - #sub.prop(context.tool_settings, "use_gpencil_draw_additive", text="Additive Drawing") - #sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing") - #sub.prop(context.tool_settings, "use_gpencil_draw_onback", text="Draw on Back") - col.separator() col.separator() @@ -121,12 +84,9 @@ class AnnotationDrawingToolsPanel: col.label(text="Data Source:") row = col.row(align=True) if is_3d_view: - row.prop(context.tool_settings, "grease_pencil_source", expand=True) + row.prop(context.tool_settings, "annotation_source", expand=True) elif is_clip_editor: - row.prop(context.space_data, "grease_pencil_source", expand=True) - - # col.separator() - # col.separator() + row.prop(context.space_data, "annotation_source", expand=True) gpencil_stroke_placement_settings(context, col) @@ -136,29 +96,33 @@ class GreasePencilSculptOptionsPanel: @classmethod def poll(cls, context): - settings = context.tool_settings.gpencil_sculpt - tool = settings.sculpt_tool + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_sculpt_paint + brush = settings.brush + tool = brush.gpencil_sculpt_tool - return bool(tool in {'SMOOTH', 'RANDOMIZE', 'SMOOTH'}) + return bool(tool in {'SMOOTH', 'RANDOMIZE'}) def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False - settings = context.tool_settings.gpencil_sculpt - tool = settings.sculpt_tool + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_sculpt_paint brush = settings.brush + gp_settings = brush.gpencil_settings + tool = brush.gpencil_sculpt_tool if tool in {'SMOOTH', 'RANDOMIZE'}: - layout.prop(settings, "use_edit_position", text="Affect Position") - layout.prop(settings, "use_edit_strength", text="Affect Strength") - layout.prop(settings, "use_edit_thickness", text="Affect Thickness") + layout.prop(gp_settings, "use_edit_position", text="Affect Position") + layout.prop(gp_settings, "use_edit_strength", text="Affect Strength") + layout.prop(gp_settings, "use_edit_thickness", text="Affect Thickness") if tool == 'SMOOTH': - layout.prop(brush, "use_edit_pressure") + layout.prop(gp_settings, "use_edit_pressure") - layout.prop(settings, "use_edit_uv", text="Affect UV") + layout.prop(gp_settings, "use_edit_uv", text="Affect UV") # GP Object Tool Settings @@ -174,7 +138,7 @@ class GreasePencilDisplayPanel: if context.mode == 'PAINT_GPENCIL': return brush.gpencil_tool != 'ERASE' else: - # GP Sculpt and Weight Paint always have Brush Tip panel. + # GP Sculpt, Vertex and Weight Paint always have Brush Tip panel. return True return False @@ -182,16 +146,18 @@ class GreasePencilDisplayPanel: if self.is_popover: return + tool_settings = context.tool_settings if context.mode == 'PAINT_GPENCIL': - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings - - self.layout.prop(gp_settings, "use_cursor", text="") - elif context.mode in {'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - settings = context.tool_settings.gpencil_sculpt - brush = settings.brush - - self.layout.prop(brush, "use_cursor", text="") + settings = tool_settings.gpencil_paint + elif context.mode == 'SCULPT_GPENCIL': + settings = tool_settings.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = tool_settings.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = tool_settings.gpencil_vertex_paint + brush = settings.brush + if brush: + self.layout.prop(settings, "show_brush", text="") def draw(self, context): layout = self.layout @@ -199,279 +165,101 @@ class GreasePencilDisplayPanel: layout.use_property_decorate = False tool_settings = context.tool_settings - ob = context.active_object + if context.mode == 'PAINT_GPENCIL': + settings = tool_settings.gpencil_paint + elif context.mode == 'SCULPT_GPENCIL': + settings = tool_settings.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = tool_settings.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = tool_settings.gpencil_vertex_paint + brush = settings.brush + gp_settings = brush.gpencil_settings + ob = context.active_object if ob.mode == 'PAINT_GPENCIL': - brush = tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings if self.is_popover: row = layout.row(align=True) - row.prop(gp_settings, "use_cursor", text="") + row.prop(settings, "show_brush", text="") row.label(text="Display Cursor") col = layout.column(align=True) - col.active = gp_settings.use_cursor + col.active = settings.show_brush if brush.gpencil_tool == 'DRAW': col.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing") - if brush.gpencil_tool == 'FILL': - col.prop(brush, "cursor_color_add", text="Cursor Color") - - elif ob.mode in {'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - settings = tool_settings.gpencil_sculpt - brush = settings.brush - tool = settings.sculpt_tool - - if self.is_popover: - row = layout.row(align=True) - row.prop(brush, "use_cursor", text="") - row.label(text="Display Cursor") - + elif ob.mode == 'SCULPT_GPENCIL': col = layout.column(align=True) - col.active = brush.use_cursor + col.active = settings.show_brush col.prop(brush, "cursor_color_add", text="Cursor Color") - if tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}: - col.prop(brush, "cursor_color_sub", text="Inverse Cursor Color") - - -class GPENCIL_MT_pie_tool_palette(Menu): - """A pie menu for quick access to Grease Pencil tools""" - bl_label = "Grease Pencil Tools" - - def draw(self, context): - layout = self.layout - - pie = layout.menu_pie() - gpd = context.gpencil_data - - # W - Drawing Types - col = pie.column() - col.operator("gpencil.draw", text="Draw", icon='GREASEPENCIL').mode = 'DRAW' - col.operator("gpencil.draw", text="Straight Lines", icon='LINE_DATA').mode = 'DRAW_STRAIGHT' - col.operator("gpencil.draw", text="Poly", icon='MESH_DATA').mode = 'DRAW_POLY' - - # E - Eraser - # XXX: needs a dedicated icon... - col = pie.column() - col.operator("gpencil.draw", text="Eraser", icon='FORCE_CURVE').mode = 'ERASER' - - # E - "Settings" Palette is included here too, since it needs to be in a stable position... - if gpd and gpd.layers.active: - col.separator() - col.operator( - "wm.call_menu_pie", - text="Settings...", - icon='SCRIPTWIN').name = "GPENCIL_MT_pie_settings_palette" - - # Editing tools - if gpd: - if gpd.use_stroke_edit_mode and context.editable_gpencil_strokes: - # S - Exit Edit Mode - pie.operator("gpencil.editmode_toggle", text="Exit Edit Mode", icon='EDIT') - - # N - Transforms - col = pie.column() - row = col.row(align=True) - row.operator("transform.translate", icon='MAN_TRANS') - row.operator("transform.rotate", icon='MAN_ROT') - row.operator("transform.resize", text="Scale", icon='MAN_SCALE') - row = col.row(align=True) - row.label(text="Proportional Edit:") - row.prop(context.tool_settings, "use_proportional_edit", text="", icon_only=True) - row.prop(context.tool_settings, "proportional_edit_falloff", text="", icon_only=True) - - # NW - Select (Non-Modal) - col = pie.column() - col.operator("gpencil.select_all", text="Select All", icon='PARTICLE_POINT') - col.operator("gpencil.select_all", text="Select Inverse", icon='BLANK1') - col.operator("gpencil.select_linked", text="Select Linked", icon='LINKED') - col.operator("gpencil.palettecolor_select", text="Select Color", icon='COLOR') - - # NE - Select (Modal) - col = pie.column() - col.operator("gpencil.select_box", text="Box Select", icon='BORDER_RECT') - col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY') - col.operator("gpencil.select_lasso", text="Lasso Select", icon='BORDER_LASSO') - col.operator("gpencil.select_alternate", text="Alternate Select", icon='BORDER_LASSO') - - # SW - Edit Tools - col = pie.column() - col.operator("gpencil.duplicate_move", icon='PARTICLE_PATH', text="Duplicate") - col.operator("gpencil.delete", icon='X', text="Delete...") - - # SE - More Tools - pie.operator("wm.call_menu_pie", text="More...").name = "GPENCIL_MT_pie_tools_more" - else: - # Toggle Edit Mode - pie.operator("gpencil.editmode_toggle", text="Enable Stroke Editing", icon='EDIT') + if brush.gpencil_sculpt_tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}: + col.prop(brush, "cursor_color_subtract", text="Inverse Cursor Color") + elif ob.mode == 'WEIGHT_GPENCIL': + col = layout.column(align=True) + col.active = settings.show_brush -class GPENCIL_MT_pie_settings_palette(Menu): - """A pie menu for quick access to Grease Pencil settings""" - bl_label = "Grease Pencil Settings" + col.prop(brush, "cursor_color_add", text="Cursor Color") - @classmethod - def poll(cls, context): - return bool(context.gpencil_data and context.active_gpencil_layer) + elif ob.mode == 'VERTEX_GPENCIL': + row = layout.row(align=True) + row.prop(settings, "show_brush", text="") + row.label(text="Display Cursor") - def draw(self, context): - layout = self.layout - pie = layout.menu_pie() - gpd = context.gpencil_data - gpl = context.active_gpencil_layer - palcolor = None # context.active_gpencil_palettecolor - - is_editmode = bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) - - # W - Stroke draw settings - col = pie.column(align=True) - if palcolor is not None: - col.enabled = not palcolor.lock - col.label(text="Stroke") - col.prop(palcolor, "color", text="") - col.prop(palcolor, "alpha", text="", slider=True) - - # E - Fill draw settings - col = pie.column(align=True) - if palcolor is not None: - col.enabled = not palcolor.lock - col.label(text="Fill") - col.prop(palcolor, "fill_color", text="") - col.prop(palcolor, "fill_alpha", text="", slider=True) - - # S Brush settings - gpencil_active_brush_settings_simple(context, pie) - - # N - Active Layer - col = pie.column() - col.label(text="Active Layer: ") - - row = col.row() - row.operator_context = 'EXEC_REGION_WIN' - row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL') - row.prop(gpl, "info", text="") - row.operator("gpencil.layer_remove", text="", icon='X') - - row = col.row() - row.prop(gpl, "lock") - row.prop(gpl, "hide") - col.prop(gpl, "use_onion_skinning") - - # NW/NE/SW/SE - These operators are only available in editmode - # as they require strokes to be selected to work - if is_editmode: - # NW - Move stroke Down - col = pie.column(align=True) - col.label(text="Arrange Strokes") - col.operator("gpencil.stroke_arrange", text="Send to Back").direction = 'BOTTOM' - col.operator("gpencil.stroke_arrange", text="Send Backward").direction = 'DOWN' - - # NE - Move stroke Up - col = pie.column(align=True) - col.label(text="Arrange Strokes") - col.operator("gpencil.stroke_arrange", text="Bring to Front").direction = 'TOP' - col.operator("gpencil.stroke_arrange", text="Bring Forward").direction = 'UP' - - # SW - Move stroke to color - col = pie.column(align=True) - col.operator("gpencil.stroke_change_color", text="Move to Color") - - # SE - Join strokes - col = pie.column(align=True) - col.label(text="Join Strokes") - row = col.row() - row.operator("gpencil.stroke_join", text="Join").type = 'JOIN' - row.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY' - col.operator("gpencil.stroke_flip", text="Flip Direction") - - col.prop(gpd, "show_stroke_direction", text="Show Drawing Direction") - - -class GPENCIL_MT_pie_tools_more(Menu): - """A pie menu for accessing more Grease Pencil tools""" - bl_label = "More Grease Pencil Tools" +class GreasePencilBrushFalloff: + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): - gpd = context.gpencil_data - return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) - - def draw(self, _context): - layout = self.layout - - pie = layout.menu_pie() - # gpd = context.gpencil_data - - col = pie.column(align=True) - col.operator("gpencil.copy", text="Copy", icon='COPYDOWN') - col.operator("gpencil.paste", text="Paste", icon='PASTEDOWN').type = 'ACTIVE' - col.operator("gpencil.paste", text="Paste by Layer").type = 'LAYER' - - col = pie.column(align=True) - col.operator("gpencil.select_more", icon='ADD') - col.operator("gpencil.select_less", icon='REMOVE') - - pie.operator("transform.mirror", icon='MOD_MIRROR') - pie.operator("transform.bend", icon='MOD_SIMPLEDEFORM') - pie.operator("transform.shear", icon='MOD_TRIANGULATE') - pie.operator("transform.tosphere", icon='MOD_MULTIRES') - - pie.operator("gpencil.convert", icon='OUTLINER_OB_CURVE', text="Convert...") - pie.operator("wm.call_menu_pie", text="Back to Main Palette...").name = "GPENCIL_MT_pie_tool_palette" - + ts = context.tool_settings + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint -class GPENCIL_MT_pie_sculpt(Menu): - """A pie menu for accessing Grease Pencil stroke sculpt settings""" - bl_label = "Grease Pencil Sculpt" - - @classmethod - def poll(cls, context): - gpd = context.gpencil_data - return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) + return (settings and settings.brush and settings.brush.curve) def draw(self, context): layout = self.layout + ts = context.tool_settings + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint + + if settings: + brush = settings.brush - pie = layout.menu_pie() - - settings = context.tool_settings.gpencil_sculpt - brush = settings.brush - - # W - Launch Sculpt Mode - col = pie.column() - # col.label(text="Tool:") - col.prop(settings, "sculpt_tool", text="") - col.operator("gpencil.sculpt_paint", text="Sculpt", icon='SCULPTMODE_HLT') - - # E - Common Settings - col = pie.column(align=True) - col.prop(brush, "size", slider=True) - row = col.row(align=True) - row.prop(brush, "strength", slider=True) - # row.prop(brush, "use_pressure_strength", text="", icon_only=True) - col.prop(brush, "use_falloff") - if settings.sculpt_tool in {'SMOOTH', 'RANDOMIZE'}: + col = layout.column(align=True) row = col.row(align=True) - row.prop(settings, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True) - row.prop(settings, "use_edit_strength", text="Strength", icon='COLOR', toggle=True) - row.prop(settings, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True) + row.prop(brush, "curve_preset", text="") - # S - Change Brush Type Shortcuts - row = pie.row() - row.prop_enum(settings, "tool", value='GRAB') - row.prop_enum(settings, "tool", value='PUSH') - row.prop_enum(settings, "tool", value='CLONE') + if brush.curve_preset == 'CUSTOM': + layout.template_curve_mapping(brush, "curve", brush=True) - # N - Change Brush Type Shortcuts - row = pie.row() - row.prop_enum(settings, "tool", value='SMOOTH') - row.prop_enum(settings, "tool", value='THICKNESS') - row.prop_enum(settings, "tool", value='STRENGTH') - row.prop_enum(settings, "tool", value='RANDOMIZE') + col = layout.column(align=True) + row = col.row(align=True) + row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH' + row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND' + row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT' + row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP' + row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE' + row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' class GPENCIL_MT_snap(Menu): @@ -512,9 +300,64 @@ class GPENCIL_MT_move_to_layer(Menu): layout.separator() + layout.operator("gpencil.move_to_layer", text="New Layer", icon='ADD').layer = -1 + + +class GPENCIL_MT_layer_active(Menu): + bl_label = "Change Active Layer" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + + gpd = context.gpencil_data + if gpd: + gpl_active = context.active_gpencil_layer + tot_layers = len(gpd.layers) + i = tot_layers - 1 + while i >= 0: + gpl = gpd.layers[i] + if gpl.info == gpl_active.info: + icon = 'GREASEPENCIL' + else: + icon = 'NONE' + layout.operator("gpencil.layer_active", text=gpl.info, icon=icon).layer = i + i -= 1 + + layout.separator() + layout.operator("gpencil.layer_add", text="New Layer", icon='ADD') +class GPENCIL_MT_material_active(Menu): + bl_label = "Change Active Material" + + @classmethod + def poll(cls, context): + ob = context.active_object + tool_settings = context.scene.tool_settings + mode = tool_settings.gpencil_paint.color_mode + if mode != 'MATERIAL': + return False + + if ob is None or len(ob.material_slots) == 0: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + ob = context.active_object + mat_active = ob.active_material + + for slot in ob.material_slots: + mat = slot.material + if mat: + icon = mat.id_data.preview.icon_id + layout.operator("gpencil.material_set", text=mat.name, icon_value=icon).slot = mat.name + + class GPENCIL_MT_gpencil_draw_delete(Menu): bl_label = "Delete" @@ -602,7 +445,7 @@ class AnnotationDataPanel: # Owner selector. if context.space_data.type == 'CLIP_EDITOR': - layout.row().prop(context.space_data, "grease_pencil_source", expand=True) + layout.row().prop(context.space_data, "annotation_source", expand=True) layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.annotation_add", unlink="gpencil.data_unlink") @@ -674,7 +517,7 @@ class AnnotationOnionSkin: if gpl is None: return False - return True + return True def draw_header(self, context): gpl = context.active_annotation_layer @@ -702,30 +545,6 @@ class AnnotationOnionSkin: sub.prop(gpl, "annotation_onion_after_range", text="After") -class GreasePencilToolsPanel: - # For use in "2D" Editors without their own toolbar - # subclass must set - # bl_space_type = 'IMAGE_EDITOR' - bl_label = "Grease Pencil Settings" - bl_region_type = 'UI' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, _context): - # XXX - disabled in 2.8 branch. - # return (context.gpencil_data is not None) - return False - - def draw(self, context): - layout = self.layout - - gpencil_active_brush_settings_simple(context, layout) - - layout.separator() - - gpencil_stroke_placement_settings(context, layout) - - class GreasePencilMaterialsPanel: # Mix-in, use for properties editor and top-bar. def draw(self, context): @@ -759,7 +578,7 @@ class GreasePencilMaterialsPanel: col.separator() - col.menu("GPENCIL_MT_color_context_menu", icon='DOWNARROW_HLT', text="") + col.menu("GPENCIL_MT_material_context_menu", icon='DOWNARROW_HLT', text="") if is_sortable: col.separator() @@ -770,8 +589,8 @@ class GreasePencilMaterialsPanel: col.separator() sub = col.column(align=True) - sub.operator("gpencil.color_isolate", icon='RESTRICT_VIEW_ON', text="").affect_visibility = True - sub.operator("gpencil.color_isolate", icon='LOCKED', text="").affect_visibility = False + sub.operator("gpencil.material_isolate", icon='RESTRICT_VIEW_ON', text="").affect_visibility = True + sub.operator("gpencil.material_isolate", icon='LOCKED', text="").affect_visibility = False if show_full_ui: row = layout.row() @@ -786,8 +605,8 @@ class GreasePencilMaterialsPanel: if ob.data.use_stroke_edit_mode: row = layout.row(align=True) row.operator("gpencil.stroke_change_color", text="Assign") - row.operator("gpencil.color_select", text="Select").deselect = False - row.operator("gpencil.color_select", text="Deselect").deselect = True + row.operator("gpencil.material_select", text="Select").deselect = False + row.operator("gpencil.material_select", text="Deselect").deselect = True # stroke color ma = None if is_view3d and brush is not None: @@ -800,11 +619,7 @@ class GreasePencilMaterialsPanel: if ma is not None and ma.grease_pencil is not None: gpcolor = ma.grease_pencil - if ( - gpcolor.stroke_style == 'SOLID' or - gpcolor.use_stroke_pattern or - gpcolor.use_stroke_texture_mix - ): + if gpcolor.stroke_style == 'SOLID': row = layout.row() row.prop(gpcolor, "color", text="Stroke Color") @@ -813,6 +628,44 @@ class GreasePencilMaterialsPanel: row.template_ID(space, "pin_id") +class GreasePencilVertexcolorPanel: + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + ts = context.scene.tool_settings + is_vertex = context.mode == 'VERTEX_GPENCIL' + gpencil_paint = ts.gpencil_vertex_paint if is_vertex else ts.gpencil_paint + brush = gpencil_paint.brush + gp_settings = brush.gpencil_settings + tool = brush.gpencil_vertex_tool if is_vertex else brush.gpencil_tool + + ob = context.object + + if ob: + col = layout.column() + col.template_color_picker(brush, "color", value_slider=True) + + sub_row = layout.row(align=True) + sub_row.prop(brush, "color", text="") + sub_row.prop(brush, "secondary_color", text="") + + sub_row.operator("gpencil.tint_flip", icon='FILE_REFRESH', text="") + + row = layout.row(align=True) + row.template_ID(gpencil_paint, "palette", new="palette.new") + if gpencil_paint.palette: + layout.template_palette(gpencil_paint, "palette", color=True) + + if tool in {'DRAW', 'FILL'} and is_vertex is False: + row = layout.row(align=True) + row.prop(gp_settings, "vertex_mode", text="Mode") + row = layout.row(align=True) + row.prop(gp_settings, "vertex_color_factor", slider=True, text="Mix Factor") + + class GPENCIL_UL_layer(UIList): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): # assert(isinstance(item, bpy.types.GPencilLayer) @@ -830,9 +683,10 @@ class GPENCIL_UL_layer(UIList): row.prop(gpl, "info", text="", emboss=False) row = layout.row(align=True) - row.prop(gpl, "mask_layer", text="", - icon='MOD_MASK' if gpl.mask_layer else 'LAYER_ACTIVE', - emboss=False) + + icon_mask = 'MOD_MASK' if gpl.use_mask_layer else 'LAYER_ACTIVE' + + row.prop(gpl, "use_mask_layer", text="", icon=icon_mask, emboss=False) subrow = row.row(align=True) subrow.prop( @@ -868,16 +722,12 @@ class GreasePencilSimplifyPanel: layout.active = rd.simplify_gpencil col = layout.column() - col.prop(rd, "simplify_gpencil_onplay", text="Playback Only") - col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers") - col.prop(rd, "simplify_gpencil_shader_fx", text="ShaderFX") - col.prop(rd, "simplify_gpencil_blend", text="Layers Blending") - col.prop(rd, "simplify_gpencil_tint", text="Layers Tinting") - + col.prop(rd, "simplify_gpencil_onplay") col.prop(rd, "simplify_gpencil_view_fill") - sub = col.column() - sub.active = rd.simplify_gpencil_view_fill - sub.prop(rd, "simplify_gpencil_remove_lines", text="Lines") + col.prop(rd, "simplify_gpencil_modifier") + col.prop(rd, "simplify_gpencil_shader_fx") + col.prop(rd, "simplify_gpencil_tint") + col.prop(rd, "simplify_gpencil_antialiasing") class GreasePencilLayerAdjustmentsPanel: @@ -913,6 +763,65 @@ class GreasePencilLayerAdjustmentsPanel: col.prop(gpl, "lock_material") +class GPENCIL_UL_masks(UIList): + def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): + mask = item + if self.layout_type in {'DEFAULT', 'COMPACT'}: + row = layout.row(align=True) + row.prop(mask, "name", text="", emboss=False, icon_value=icon) + row.prop(mask, "invert", text="", emboss=False) + row.prop(mask, "hide", text="", emboss=False) + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.prop(mask, "name", text="", emboss=False, icon_value=icon) + + +class GPENCIL_MT_layer_mask_menu(Menu): + bl_label = "Layer Specials" + + def draw(self, context): + layout = self.layout + ob = context.object + gpd = ob.data + gpl_active = gpd.layers.active + done = False + for gpl in gpd.layers: + if gpl != gpl_active and gpl.info not in gpl_active.mask_layers: + done = True + layout.operator("gpencil.layer_mask_add", text=gpl.info).name=gpl.info + + if done is False: + layout.label(text="No layers to add") + + +class GreasePencilLayerMasksPanel: + def draw_header(self, context): + ob = context.active_object + gpd = ob.data + gpl = gpd.layers.active + + self.layout.prop(gpl, "use_mask_layer", text="") + + def draw(self, context): + ob = context.active_object + gpd = ob.data + gpl = gpd.layers.active + + layout = self.layout + layout.enabled = gpl.use_mask_layer + + if gpl: + rows = 4 + row = layout.row() + col = row.column() + col.template_list("GPENCIL_UL_masks", "", gpl, "mask_layers", gpl.mask_layers, + "active_mask_index", rows=rows, sort_lock=True) + + col2 = row.column(align=True) + col2.menu("GPENCIL_MT_layer_mask_menu", icon='ADD', text="") + col2.operator("gpencil.layer_mask_remove", icon='REMOVE', text="") + + class GreasePencilLayerRelationsPanel: def draw(self, context): @@ -952,20 +861,59 @@ class GreasePencilLayerDisplayPanel: col.prop(gpl, "use_solo_mode", text="Show Only On Keyframed") -classes = ( - GPENCIL_MT_pie_tool_palette, - GPENCIL_MT_pie_settings_palette, - GPENCIL_MT_pie_tools_more, - GPENCIL_MT_pie_sculpt, +class GreasePencilFlipTintColors(Operator): + bl_label = "Flip Colors" + bl_idname = "gpencil.tint_flip" + bl_description = "Switch Tint colors" + def execute(self, context): + try: + ts = context.tool_settings + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint + + brush = settings.brush + if brush is not None: + color = brush.color + secondary_color = brush.secondary_color + + orig_prim = color.hsv + orig_sec = secondary_color.hsv + + color.hsv = orig_sec + secondary_color.hsv = orig_prim + + return {'FINISHED'} + + except Exception as e: + utils_core.error_handlers(self, "gpencil.tint_flip", e, + "Flip Colors could not be completed") + + return {'CANCELLED'} + + +classes = ( GPENCIL_MT_snap, GPENCIL_MT_cleanup, GPENCIL_MT_move_to_layer, + GPENCIL_MT_layer_active, + GPENCIL_MT_material_active, GPENCIL_MT_gpencil_draw_delete, + GPENCIL_MT_layer_mask_menu, GPENCIL_UL_annotation_layer, GPENCIL_UL_layer, + GPENCIL_UL_masks, + + GreasePencilFlipTintColors, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 0849437b680..6aaec9940e8 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -74,7 +74,7 @@ class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} _context_path = "material" _property_type = bpy.types.Material @@ -172,10 +172,11 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel): layout.prop(mat, "use_nodes", icon='NODETREE') layout.separator() + layout.use_property_split = True + if mat.use_nodes: panel_node_draw(layout, mat.node_tree, 'OUTPUT_MATERIAL', "Surface") else: - layout.use_property_split = True layout.prop(mat, "diffuse_color", text="Base Color") layout.prop(mat, "metallic") layout.prop(mat, "specular_intensity", text="Specular") @@ -197,6 +198,8 @@ class EEVEE_MATERIAL_PT_volume(MaterialButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + mat = context.material panel_node_draw(layout, mat.node_tree, 'OUTPUT_MATERIAL', "Volume") diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index 4f419ec1f18..5d10a2cef4a 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -27,26 +27,31 @@ from bl_ui.properties_grease_pencil_common import ( ) -class GPENCIL_MT_color_context_menu(Menu): +class GPENCIL_MT_material_context_menu(Menu): bl_label = "Material Specials" def draw(self, _context): layout = self.layout - layout.operator("gpencil.color_reveal", icon='RESTRICT_VIEW_OFF', text="Show All") - layout.operator("gpencil.color_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True + layout.operator("gpencil.material_reveal", icon='RESTRICT_VIEW_OFF', text="Show All") + layout.operator("gpencil.material_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True layout.separator() - layout.operator("gpencil.color_lock_all", icon='LOCKED', text="Lock All") - layout.operator("gpencil.color_unlock_all", icon='UNLOCKED', text="UnLock All") + layout.operator("gpencil.material_lock_all", icon='LOCKED', text="Lock All") + layout.operator("gpencil.material_unlock_all", icon='UNLOCKED', text="UnLock All") - layout.operator("gpencil.stroke_lock_color", text="Lock Unselected") + layout.operator("gpencil.material_lock_unused", text="Lock Unselected") layout.operator("gpencil.lock_layer", text="Lock Unused") layout.separator() layout.operator("object.material_slot_remove_unused") + layout.operator("gpencil.stroke_merge_material", text="Merge Similar") + + layout.separator() + layout.operator("gpencil.material_to_vertex_color", text="Convert Materials to Vertex Color") + layout.operator("gpencil.extract_palette_vertex", text="Extract Palette from Vertex Color") class GPENCIL_UL_matslots(UIList): @@ -142,27 +147,25 @@ class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel): col.prop(gpcolor, "stroke_style", text="Style") + row = col.row() + row.prop(gpcolor, "color", text="Base Color") + if gpcolor.stroke_style == 'TEXTURE': row = col.row() row.enabled = not gpcolor.lock col = row.column(align=True) col.template_ID(gpcolor, "stroke_image", open="image.open") + + if gpcolor.stroke_style == 'TEXTURE': + row = col.row() + row.prop(gpcolor, "mix_stroke_factor", text="Blend", slider=True) if gpcolor.mode == 'LINE': col.prop(gpcolor, "pixel_size", text="UV Factor") - col.prop(gpcolor, "use_stroke_pattern", text="Use As Stencil Mask") - if gpcolor.use_stroke_pattern is False: - col.prop(gpcolor, "use_stroke_texture_mix", text="Mix Color") - if gpcolor.use_stroke_texture_mix is True: - col.prop(gpcolor, "mix_stroke_factor", text="Factor") - - if (gpcolor.stroke_style == 'SOLID' or gpcolor.use_stroke_pattern or gpcolor.use_stroke_texture_mix): - col.prop(gpcolor, "color", text="Color") - if gpcolor.mode in {'DOTS', 'BOX'}: col.prop(gpcolor, "alignment_mode") - if gpcolor.mode == 'LINE' and gpcolor.stroke_style != 'TEXTURE': + if gpcolor.mode == 'LINE': col.prop(gpcolor, "use_overlap_strokes") @@ -188,55 +191,37 @@ class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel): col.enabled = not gpcolor.lock col.prop(gpcolor, "fill_style", text="Style") - if gpcolor.fill_style == 'GRADIENT': - col.prop(gpcolor, "gradient_type") - - if gpcolor.fill_style != 'TEXTURE': - col.prop(gpcolor, "fill_color", text="Color") + if gpcolor.fill_style == 'SOLID': + col.prop(gpcolor, "fill_color", text="Base Color") - if gpcolor.fill_style in {'GRADIENT', 'CHECKER'}: - col.prop(gpcolor, "mix_color", text="Secondary Color") + elif gpcolor.fill_style == 'GRADIENT': + col.prop(gpcolor, "gradient_type") - if gpcolor.fill_style == 'GRADIENT': - col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True) + col.prop(gpcolor, "fill_color", text="Base Color") + col.prop(gpcolor, "mix_color", text="Secondary Color") + col.prop(gpcolor, "mix_factor", text="Blend", slider=True) + col.prop(gpcolor, "flip", text="Flip Colors") - if gpcolor.fill_style in {'GRADIENT', 'CHECKER'}: - col.prop(gpcolor, "flip", text="Flip Colors") + col.prop(gpcolor, "texture_offset", text="Location") - col.prop(gpcolor, "pattern_shift", text="Location") - col.prop(gpcolor, "pattern_scale", text="Scale") + row = col.row() + row.enabled = gpcolor.gradient_type == 'LINEAR' + row.prop(gpcolor, "texture_angle", text="Rotation") - if gpcolor.gradient_type == 'RADIAL' and gpcolor.fill_style not in {'SOLID', 'CHECKER'}: - col.prop(gpcolor, "pattern_radius", text="Radius") - else: - if gpcolor.fill_style != 'SOLID': - col.prop(gpcolor, "pattern_angle", text="Angle") + col.prop(gpcolor, "texture_scale", text="Scale") - if gpcolor.fill_style == 'CHECKER': - col.prop(gpcolor, "pattern_gridsize", text="Box Size") + elif gpcolor.fill_style == 'TEXTURE': + col.prop(gpcolor, "fill_color", text="Base Color") - # Texture - if gpcolor.fill_style == 'TEXTURE' or (gpcolor.use_fill_texture_mix is True and gpcolor.fill_style == 'SOLID'): col.template_ID(gpcolor, "fill_image", open="image.open") - if gpcolor.fill_style == 'TEXTURE': - col.prop(gpcolor, "use_fill_pattern", text="Use as Stencil Mask") - if gpcolor.use_fill_pattern is True: - col.prop(gpcolor, "fill_color", text="Color") + col.prop(gpcolor, "mix_factor", text="Blend", slider=True) - col.prop(gpcolor, "texture_offset", text="Offset") + col.prop(gpcolor, "texture_offset", text="Location") + col.prop(gpcolor, "texture_angle", text="Rotation") col.prop(gpcolor, "texture_scale", text="Scale") - col.prop(gpcolor, "texture_angle") - col.prop(gpcolor, "texture_opacity") col.prop(gpcolor, "texture_clamp", text="Clip Image") - if gpcolor.use_fill_pattern is False: - col.prop(gpcolor, "use_fill_texture_mix", text="Mix with Color") - - if gpcolor.use_fill_texture_mix is True: - col.prop(gpcolor, "fill_color", text="Mix Color") - col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True) - class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel): bl_label = "Preview" @@ -278,7 +263,7 @@ class MATERIAL_PT_gpencil_material_presets(PresetPanel, Panel): classes = ( GPENCIL_UL_matslots, - GPENCIL_MT_color_context_menu, + GPENCIL_MT_material_context_menu, MATERIAL_PT_gpencil_slots, MATERIAL_PT_gpencil_preview, MATERIAL_PT_gpencil_material_presets, @@ -291,5 +276,6 @@ classes = ( if __name__ == "__main__": # only for live edit. from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index bb020084b03..8ce53ed30eb 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -212,45 +212,31 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) obj = context.object obj_type = obj.type - is_geometry = (obj_type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'}) + is_geometry = (obj_type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'VOLUME', 'HAIR', 'POINTCLOUD'}) is_wire = (obj_type in {'CAMERA', 'EMPTY'}) is_empty_image = (obj_type == 'EMPTY' and obj.empty_display_type == 'IMAGE') is_dupli = (obj.instance_type != 'NONE') is_gpencil = (obj_type == 'GPENCIL') - col = flow.column() + col = layout.column(heading="Show") col.prop(obj, "show_name", text="Name") - - col = flow.column() col.prop(obj, "show_axis", text="Axis") # Makes no sense for cameras, armatures, etc.! # but these settings do apply to dupli instances if is_geometry or is_dupli: - col = flow.column() col.prop(obj, "show_wire", text="Wireframe") if obj_type == 'MESH' or is_dupli: - col = flow.column() col.prop(obj, "show_all_edges", text="All Edges") - - col = flow.column() if is_geometry: col.prop(obj, "show_texture_space", text="Texture Space") - col = flow.column() col.prop(obj.display, "show_shadows", text="Shadow") - - col = flow.column() col.prop(obj, "show_in_front", text="In Front") # if obj_type == 'MESH' or is_empty_image: # col.prop(obj, "show_transparent", text="Transparency") - - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() if is_wire: # wire objects only use the max. display type for duplis col.active = is_dupli @@ -258,28 +244,17 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): if is_geometry or is_dupli or is_empty_image or is_gpencil: # Only useful with object having faces/materials... - col = flow.column() col.prop(obj, "color") - -class OBJECT_PT_display_bounds(ObjectButtonsPanel, Panel): - bl_label = "Bounds" - bl_parent_id = "OBJECT_PT_display" - bl_options = {'DEFAULT_CLOSED'} - - def draw_header(self, context): - - obj = context.object - - self.layout.prop(obj, "show_bounds", text="") - - def draw(self, context): - layout = self.layout - obj = context.object - layout.use_property_split = True - - layout.active = obj.show_bounds or (obj.display_type == 'BOUNDS') - layout.prop(obj, "display_bounds_type", text="Shape") + col = layout.column(align=False, heading="Bounds") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(obj, "show_bounds", text="") + sub = sub.row(align=True) + sub.active = obj.show_bounds or (obj.display_type == 'BOUNDS') + sub.prop(obj, "display_bounds_type", text="") + row.prop_decorator(obj, "display_bounds_type") class OBJECT_PT_instancing(ObjectButtonsPanel, Panel): @@ -295,7 +270,6 @@ class OBJECT_PT_instancing(ObjectButtonsPanel, Panel): row.prop(ob, "instance_type", expand=True) layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) if ob.instance_type == 'VERTS': layout.prop(ob, "use_instance_vertices_rotation", text="Align to Vertex Normal") @@ -305,9 +279,9 @@ class OBJECT_PT_instancing(ObjectButtonsPanel, Panel): col.prop(ob, "instance_collection", text="Collection") if ob.instance_type != 'NONE' or ob.particle_systems: - col = flow.column(align=True) - col.prop(ob, "show_instancer_for_viewport") - col.prop(ob, "show_instancer_for_render") + col = layout.column(heading="Show Instancer", align=True) + col.prop(ob, "show_instancer_for_viewport", text="Viewport") + col.prop(ob, "show_instancer_for_render", text="Render") class OBJECT_PT_instancing_size(ObjectButtonsPanel, Panel): @@ -385,16 +359,18 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) layout = self.layout ob = context.object - col = flow.column() - col.prop(ob, "hide_viewport", text="Show in Viewports", toggle=False, invert_checkbox=True) - col = flow.column() - col.prop(ob, "hide_render", text="Show in Renders", toggle=False, invert_checkbox=True) - col = flow.column() - col.prop(ob, "hide_select", text="Selectable", toggle=False, invert_checkbox=True) + layout.prop(ob, "hide_select", text="Selectable", toggle=False, invert_checkbox=True) + + col = layout.column(heading="Show in") + col.prop(ob, "hide_viewport", text="Viewports", toggle=False, invert_checkbox=True) + col.prop(ob, "hide_render", text="Renders", toggle=False, invert_checkbox=True) + + if context.object.type == 'GPENCIL': + col = layout.column(heading="Grease Pencil") + col.prop(ob, "use_grease_pencil_lights", toggle=False) class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel): @@ -415,7 +391,6 @@ classes = ( OBJECT_PT_motion_paths, OBJECT_PT_motion_paths_display, OBJECT_PT_display, - OBJECT_PT_display_bounds, OBJECT_PT_visibility, OBJECT_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py index 748961bb40f..e859798c085 100644 --- a/release/scripts/startup/bl_ui/properties_output.py +++ b/release/scripts/startup/bl_ui/properties_output.py @@ -94,14 +94,14 @@ class RENDER_PT_dimensions(RenderOutputButtonsPanel, Panel): return args @staticmethod - def draw_framerate(layout, sub, rd): + def draw_framerate(layout, rd): if RENDER_PT_dimensions._preset_class is None: RENDER_PT_dimensions._preset_class = bpy.types.RENDER_MT_framerate_presets args = rd.fps, rd.fps_base, RENDER_PT_dimensions._preset_class.bl_label fps_label_text, show_framerate = RENDER_PT_dimensions._draw_framerate_label(*args) - sub.menu("RENDER_MT_framerate_presets", text=fps_label_text) + layout.menu("RENDER_MT_framerate_presets", text=fps_label_text) if show_framerate: col = layout.column(align=True) @@ -136,10 +136,8 @@ class RENDER_PT_dimensions(RenderOutputButtonsPanel, Panel): col.prop(scene, "frame_end", text="End") col.prop(scene, "frame_step", text="Step") - col = layout.split() - col.alignment = 'RIGHT' - col.label(text="Frame Rate") - self.draw_framerate(layout, col, rd) + col = layout.column(heading="Frame Rate") + self.draw_framerate(col, rd) class RENDER_PT_frame_remapping(RenderOutputButtonsPanel, Panel): @@ -171,10 +169,8 @@ class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel): rd = context.scene.render - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - col = flow.column() + col = layout.column(heading="Pipeline") col.prop(rd, "use_compositing") - col = flow.column() col.prop(rd, "use_sequencer") layout.prop(rd, "dither_intensity", text="Dither", slider=True) @@ -192,44 +188,23 @@ class RENDER_PT_stamp(RenderOutputButtonsPanel, Panel): rd = context.scene.render - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + if rd.use_sequencer: + layout.prop(rd, "metadata_input") - col = flow.column() + col = layout.column(heading="Include") col.prop(rd, "use_stamp_date", text="Date") - col = flow.column() col.prop(rd, "use_stamp_time", text="Time") - - col = flow.column() col.prop(rd, "use_stamp_render_time", text="Render Time") - col = flow.column() col.prop(rd, "use_stamp_frame", text="Frame") - col = flow.column() col.prop(rd, "use_stamp_frame_range", text="Frame Range") - col = flow.column() col.prop(rd, "use_stamp_memory", text="Memory") - col = flow.column() col.prop(rd, "use_stamp_hostname", text="Hostname") - - col = flow.column() col.prop(rd, "use_stamp_camera", text="Camera") - col = flow.column() col.prop(rd, "use_stamp_lens", text="Lens") - - col = flow.column() col.prop(rd, "use_stamp_scene", text="Scene") - col = flow.column() col.prop(rd, "use_stamp_marker", text="Marker") - - col = flow.column() col.prop(rd, "use_stamp_filename", text="Filename") - col = flow.column() - col.prop(rd, "use_stamp_sequencer_strip", text="Strip Name") - - if rd.use_sequencer: - col = flow.column() - col.prop(rd, "use_stamp_strip_meta", text="Use Strip Metadata") - class RENDER_PT_stamp_note(RenderOutputButtonsPanel, Panel): bl_label = "Note" @@ -293,21 +268,17 @@ class RENDER_PT_output(RenderOutputButtonsPanel, Panel): layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() - col.active = not rd.is_movie_format - col.prop(rd, "use_overwrite") - col = flow.column() - col.active = not rd.is_movie_format - col.prop(rd, "use_placeholder") - col = flow.column() + col = layout.column(heading="Saving") col.prop(rd, "use_file_extension") - col = flow.column() col.prop(rd, "use_render_cache") layout.template_image_settings(image_settings, color_management=False) + if not rd.is_movie_format: + col = layout.column(heading="Image Sequence") + col.prop(rd, "use_overwrite") + col.prop(rd, "use_placeholder") + class RENDER_PT_output_views(RenderOutputButtonsPanel, Panel): bl_label = "Views" diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index a9e8cae3c8b..92d421f63a8 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -89,8 +89,12 @@ class UnifiedPaintPanel: # Grease Pencil settings elif mode == 'PAINT_GPENCIL': return tool_settings.gpencil_paint - elif mode in {'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - return tool_settings.gpencil_sculpt + elif mode == 'SCULPT_GPENCIL': + return tool_settings.gpencil_sculpt_paint + elif mode == 'WEIGHT_GPENCIL': + return tool_settings.gpencil_weight_paint + elif mode == 'VERTEX_GPENCIL': + return tool_settings.gpencil_vertex_paint return None @staticmethod @@ -211,7 +215,7 @@ class ClonePanel(BrushPanel): settings = cls.paint_settings(context) mode = cls.get_brush_mode(context) - if mode in {'PAINT_TEXTURE', 'PAINT_2D'}: + if mode == 'PAINT_TEXTURE': brush = settings.brush return brush.image_tool == 'CLONE' return False @@ -536,6 +540,7 @@ def brush_settings(layout, context, brush, popover=False): # normal_radius_factor layout.prop(brush, "normal_radius_factor", slider=True) + layout.prop(brush, "hardness", slider=True) # auto_smooth_factor and use_inverse_smooth_pressure if capabilities.has_auto_smooth: @@ -582,10 +587,12 @@ def brush_settings(layout, context, brush, popover=False): slider=True, ) - layout.prop(brush, "use_plane_trim", text="Plane Trim") - row = layout.row() - row.active = brush.use_plane_trim - row.prop(brush, "plane_trim", slider=True, text="Distance") + row = layout.row(heading="Plane Trim") + row.prop(brush, "use_plane_trim", text="") + sub = row.row() + sub.active = brush.use_plane_trim + sub.prop(brush, "plane_trim", slider=True, text="") + layout.separator() # height @@ -595,19 +602,14 @@ def brush_settings(layout, context, brush, popover=False): # use_persistent, set_persistent_base if capabilities.has_persistence: ob = context.sculpt_object - do_persistent = True - - # not supported yet for this case - for md in ob.modifiers: - if md.type == 'MULTIRES': - do_persistent = False - break + layout.separator() + layout.prop(brush, "use_persistent") + layout.operator("sculpt.set_persistent_base") + layout.separator() - if do_persistent: - layout.separator() - layout.prop(brush, "use_persistent") - layout.operator("sculpt.set_persistent_base") - layout.separator() + if brush.sculpt_tool == 'CLAY_STRIPS': + row = layout.row() + row.prop(brush, "tip_roundness") if brush.sculpt_tool == 'ELASTIC_DEFORM': layout.separator() @@ -617,17 +619,35 @@ def brush_settings(layout, context, brush, popover=False): if brush.sculpt_tool == 'POSE': layout.separator() + layout.prop(brush, "pose_origin_type") layout.prop(brush, "pose_offset") layout.prop(brush, "pose_smooth_iterations") layout.prop(brush, "pose_ik_segments") + layout.prop(brush, "use_pose_ik_anchored") layout.separator() - + + if brush.sculpt_tool == 'CLOTH': + layout.separator() + layout.prop(brush, "cloth_sim_limit") + layout.prop(brush, "cloth_sim_falloff") + layout.separator() + layout.prop(brush, "cloth_deform_type") + layout.prop(brush, "cloth_force_falloff_type") + layout.separator() + layout.prop(brush, "cloth_mass") + layout.prop(brush, "cloth_damping") + layout.separator() + if brush.sculpt_tool == 'SCRAPE': row = layout.row() + row.prop(brush, "area_radius_factor", slider=True) + row = layout.row() row.prop(brush, "invert_to_scrape_fill", text="Invert to Fill") if brush.sculpt_tool == 'FILL': row = layout.row() + row.prop(brush, "area_radius_factor", slider=True) + row = layout.row() row.prop(brush, "invert_to_scrape_fill", text="Invert to Scrape") if brush.sculpt_tool == 'GRAB': @@ -639,6 +659,14 @@ def brush_settings(layout, context, brush, popover=False): col.prop(brush, "use_multiplane_scrape_dynamic") col.prop(brush, "show_multiplane_scrape_planes_preview") + if brush.sculpt_tool == 'SMOOTH': + col = layout.column() + col.prop(brush, "smooth_deform_type") + if brush.smooth_deform_type == 'SURFACE': + col.prop(brush, "surface_smooth_shape_preservation") + col.prop(brush, "surface_smooth_current_vertex") + col.prop(brush, "surface_smooth_iterations") + if brush.sculpt_tool == 'MASK': layout.row().prop(brush, "mask_tool", expand=True) @@ -782,14 +810,27 @@ def brush_settings_advanced(layout, context, brush, popover=False): use_accumulate = capabilities.has_accumulate use_frontface = True + col = layout.column(heading="Auto-Masking", align=True) + # topology automasking - layout.prop(brush, "use_automasking_topology") + col.prop(brush, "use_automasking_topology", text="Topology") + + # face masks automasking + col.prop(brush, "use_automasking_face_sets", text="Face Sets") + + # boundary edges/face sets automasking + col.prop(brush, "use_automasking_boundary_edges", text="Mesh Boundary") + col.prop(brush, "use_automasking_boundary_face_sets", text="Face Sets Boundary") + col.prop(brush, "automasking_boundary_edges_propagation_steps") + + layout.separator() # sculpt plane settings if capabilities.has_sculpt_plane: layout.prop(brush, "sculpt_plane") - layout.prop(brush, "use_original_normal") - layout.prop(brush, "use_original_plane") + col = layout.column(heading="Use Original", align=True) + col.prop(brush, "use_original_normal", text="Normal") + col.prop(brush, "use_original_plane", text="Plane") layout.separator() # 3D and 2D Texture Paint. @@ -858,7 +899,7 @@ def draw_color_settings(context, layout, brush, color_type=False): UnifiedPaintPanel.prop_unified_color(row, context, brush, "secondary_color", text="") row.separator() row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="", emboss=False) - row.prop(ups, "use_unified_color", text="", icon='WORLD') + row.prop(ups, "use_unified_color", text="", icon='BRUSHES_ALL') # Gradient elif brush.color_type == 'GRADIENT': layout.template_color_ramp(brush, "gradient", expand=True) @@ -994,8 +1035,12 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False): def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False): + tool_settings = context.tool_settings + settings = tool_settings.gpencil_paint gp_settings = brush.gpencil_settings tool = context.workspace.tools.from_space_view3d_mode(context.mode, create=False) + if gp_settings is None: + return # Brush details if brush.gpencil_tool == 'ERASE': @@ -1016,7 +1061,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) row.prop(gp_settings, "eraser_thickness_factor") row = layout.row(align=True) - row.prop(gp_settings, "use_cursor", text="Display Cursor") + row.prop(settings, "show_brush", text="Display Cursor") # FIXME: tools must use their own UI drawing! elif brush.gpencil_tool == 'FILL': @@ -1027,14 +1072,29 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) row = layout.row(align=True) row.prop(gp_settings, "fill_simplify_level", text="Simplify") - else: # brush.gpencil_tool == 'DRAW': + else: # brush.gpencil_tool == 'DRAW/TINT': row = layout.row(align=True) row.prop(brush, "size", text="Radius") row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') + + if gp_settings.use_pressure and context.area.type == 'PROPERTIES': + col = layout.column() + col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True, + use_negative_slope=True) + row = layout.row(align=True) row.prop(gp_settings, "pen_strength", slider=True) row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_strength_pressure and context.area.type == 'PROPERTIES': + col = layout.column() + col.template_curve_mapping(gp_settings, "curve_strength", brush=True, + use_negative_slope=True) + + if brush.gpencil_tool == 'TINT': + row = layout.row(align=True) + row.prop(gp_settings, "vertex_mode", text="Mode") + # FIXME: tools must use their own UI drawing! if tool.idname in { "builtin.arc", @@ -1047,7 +1107,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) settings = context.tool_settings.gpencil_sculpt if compact: row = layout.row(align=True) - row.prop(settings, "use_thickness_curve", text="", icon='CURVE_DATA') + row.prop(settings, "use_thickness_curve", text="", icon='SPHERECURVE') sub = row.row(align=True) sub.active = settings.use_thickness_curve sub.popover( @@ -1064,50 +1124,66 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) def brush_basic_gpencil_sculpt_settings(layout, context, brush, *, compact=False): - tool_settings = context.tool_settings - settings = tool_settings.gpencil_sculpt - tool = settings.sculpt_tool + gp_settings = brush.gpencil_settings + tool = brush.gpencil_sculpt_tool row = layout.row(align=True) row.prop(brush, "size", slider=True) sub = row.row(align=True) sub.enabled = tool not in {'GRAB', 'CLONE'} - sub.prop(brush, "use_pressure_radius", text="") + sub.prop(gp_settings, "use_pressure", text="") row = layout.row(align=True) row.prop(brush, "strength", slider=True) row.prop(brush, "use_pressure_strength", text="") - layout.prop(brush, "use_falloff") - if compact: if tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}: row.separator() - row.prop(brush, "direction", expand=True, text="") + row.prop(gp_settings, "direction", expand=True, text="") else: use_property_split_prev = layout.use_property_split layout.use_property_split = False if tool in {'THICKNESS', 'STRENGTH'}: - layout.row().prop(brush, "direction", expand=True) + layout.row().prop(gp_settings, "direction", expand=True) elif tool == 'PINCH': row = layout.row(align=True) - row.prop_enum(brush, "direction", value='ADD', text="Pinch") - row.prop_enum(brush, "direction", value='SUBTRACT', text="Inflate") + row.prop_enum(gp_settings, "direction", value='ADD', text="Pinch") + row.prop_enum(gp_settings, "direction", value='SUBTRACT', text="Inflate") elif tool == 'TWIST': row = layout.row(align=True) - row.prop_enum(brush, "direction", value='ADD', text="CCW") - row.prop_enum(brush, "direction", value='SUBTRACT', text="CW") + row.prop_enum(gp_settings, "direction", value='ADD', text="CCW") + row.prop_enum(gp_settings, "direction", value='SUBTRACT', text="CW") layout.use_property_split = use_property_split_prev def brush_basic_gpencil_weight_settings(layout, _context, brush, *, compact=False): + gp_settings = brush.gpencil_settings layout.prop(brush, "size", slider=True) row = layout.row(align=True) row.prop(brush, "strength", slider=True) row.prop(brush, "use_pressure_strength", text="") + layout.prop(brush, "weight", slider=True) - layout.prop(brush, "use_falloff") + + +def brush_basic_gpencil_vertex_settings(layout, _context, brush, *, compact=False): + gp_settings = brush.gpencil_settings + + # Brush details + row = layout.row(align=True) + row.prop(brush, "size", text="Radius") + row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') + + if brush.gpencil_vertex_tool in {'DRAW', 'BLUR', 'SMEAR'}: + row = layout.row(align=True) + row.prop(gp_settings, "pen_strength", slider=True) + row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + + if brush.gpencil_vertex_tool in {'DRAW', 'REPLACE'}: + row = layout.row(align=True) + row.prop(gp_settings, "vertex_mode", text="Mode") classes = ( diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 3384032e332..cc8fa511e42 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -136,13 +136,13 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList): if md: row.prop( md, - "show_viewport", + "show_render", emboss=False, icon_only=True, ) row.prop( md, - "show_render", + "show_viewport", emboss=False, icon_only=True, ) @@ -413,6 +413,38 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): box.label(text="Error: %.5f .. %.5f (avg. %.5f)" % (result.min_error, result.max_error, result.avg_error)) +class PARTICLE_PT_hair_dynamics_collision(ParticleButtonsPanel, Panel): + bl_label = "Collisions" + bl_parent_id = "PARTICLE_PT_hair_dynamics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + @classmethod + def poll(cls, context): + return context.particle_system.cloth is not None + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + cloth_md = psys.cloth + cloth_collision = cloth_md.collision_settings + + layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked is False + + layout.use_property_split = True + + col = layout.column() + col.prop(cloth_collision, "collision_quality", text="Quality") + + layout.separator() + + col = layout.column() + col.prop(cloth_collision, "distance_min", slider=True, text="Distance") + col.prop(cloth_collision, "impulse_clamp") + col.prop(cloth_collision, "collection") + + class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel): bl_label = "Structure" bl_parent_id = "PARTICLE_PT_hair_dynamics" @@ -607,7 +639,7 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): col.separator() col.prop(part, "phase_factor", slider=True) - col.prop(part, "phase_factor_random", text="Randomize Phase ", slider=True) + col.prop(part, "phase_factor_random", text="Randomize Phase", slider=True) if part.type != 'HAIR': col.prop(part, "use_dynamic_rotation") @@ -1986,6 +2018,7 @@ classes = ( PARTICLE_PT_emission, PARTICLE_PT_emission_source, PARTICLE_PT_hair_dynamics, + PARTICLE_PT_hair_dynamics_collision, PARTICLE_PT_hair_dynamics_structure, PARTICLE_PT_hair_dynamics_volume, PARTICLE_PT_cache, diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index d9713cb8608..0bf667482c4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -230,7 +230,7 @@ class PHYSICS_PT_cloth_pressure(PhysicButtonsPanel, Panel): col.prop(cloth, "uniform_pressure_force") col = flow.column() - col.prop(cloth, "use_pressure_volume", text="Custom volume") + col.prop(cloth, "use_pressure_volume", text="Custom Volume") col = flow.column() col.active = cloth.use_pressure_volume diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 5397020a521..0cd99efcca9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -227,7 +227,7 @@ def point_cache_ui(self, cache, enabled, cachetype): col.operator("ptcache.bake", text="Bake").bake = True sub = col.row() - sub.enabled = (cache.is_frame_skip or cache.is_outdated) and enabled + sub.enabled = enabled sub.operator("ptcache.bake", text="Calculate To Frame").bake = False sub = col.column() @@ -310,8 +310,10 @@ def basic_force_field_settings_ui(self, field): else: col.prop(field, "flow") - col.prop(field, "apply_to_location", text="Affect Location") - col.prop(field, "apply_to_rotation", text="Affect Rotation") + sub = col.column(heading="Affect") + + sub.prop(field, "apply_to_location", text="Location") + sub.prop(field, "apply_to_rotation", text="Rotation") col = flow.column() sub = col.column(align=True) @@ -336,26 +338,29 @@ def basic_force_field_falloff_ui(self, field): if not field or field.type == 'NONE': return - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - - col = flow.column() + col = layout.column() col.prop(field, "z_direction") col.prop(field, "falloff_power", text="Power") - col = flow.column() - col.prop(field, "use_min_distance", text="Use Minimum") - - sub = col.column(align=True) + col = layout.column(align=False, heading="Min Distance") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(field, "use_min_distance", text="") + sub = sub.row(align=True) sub.active = field.use_min_distance - sub.prop(field, "distance_min", text="Min Distance") - - col = flow.column() - col.prop(field, "use_max_distance", text="Use Maximum") - - sub = col.column(align=True) + sub.prop(field, "distance_min", text="") + row.prop_decorator(field, "distance_min") + + col = layout.column(align=False, heading="Max Distance") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(field, "use_max_distance", text="") + sub = sub.row(align=True) sub.active = field.use_max_distance - sub.prop(field, "distance_max", text="Max Distance") - + sub.prop(field, "distance_max", text="") + row.prop_decorator(field, "distance_max") classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 00dc068a51a..d1ff1dc9f5e 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -123,7 +123,7 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): col.prop(field, "use_object_coords") col.prop(field, "use_2d_force") - elif field.type == 'SMOKE_FLOW': + elif field.type == 'FLUID_FLOW': col = flow.column() col.prop(field, "strength") col.prop(field, "flow") diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 28c9895f53b..4b0791a63e6 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -19,20 +19,18 @@ # <pep8 compliant> import bpy -from bpy.types import ( - Panel, - Menu, -) +from bpy.types import Menu, Panel +from bl_ui.utils import PresetPanel from .properties_physics_common import ( effector_weights_ui, ) -class FLUID_MT_presets(Menu): +class FLUID_PT_presets(PresetPanel, Panel): bl_label = "Fluid Presets" preset_subdir = "fluid" preset_operator = "script.execute_preset" - draw = Menu.draw_preset + preset_add_operator = "fluid.preset_add" class PhysicButtonsPanel: @@ -162,9 +160,6 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): if md.fluid_type == 'DOMAIN': domain = md.domain_settings - # Deactivate UI if guides are enabled but not baked yet. - layout.active = not self.check_domain_has_unbaked_guide(domain) - is_baking_any = domain.is_cache_baking_any has_baked_data = domain.has_cache_baked_data @@ -176,16 +171,17 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): flow.enabled = not is_baking_any and not has_baked_data col = flow.column() + col.enabled = not domain.has_cache_baked_guide col.prop(domain, "resolution_max", text="Resolution Divisions") col.prop(domain, "time_scale", text="Time Scale") col.prop(domain, "cfl_condition", text="CFL Number") col = flow.column() col.prop(domain, "use_adaptive_timesteps") - col1 = col.column(align=True) - col1.enabled = domain.use_adaptive_timesteps - col1.prop(domain, "timesteps_max", text="Timesteps Maximum") - col1.prop(domain, "timesteps_min", text="Minimum") + sub = col.column(align=True) + sub.active = domain.use_adaptive_timesteps + sub.prop(domain, "timesteps_max", text="Timesteps Maximum") + sub.prop(domain, "timesteps_min", text="Minimum") col.separator() @@ -196,12 +192,25 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): sub.prop(domain, "gravity", text="Using Scene Gravity", icon='SCENE_DATA') else: col.prop(domain, "gravity", text="Gravity") - # TODO (sebbas): Clipping var useful for manta openvdb caching? - # col.prop(domain, "clipping", text="Empty Space") + + col = flow.column() + if PhysicButtonsPanel.poll_gas_domain(context): + col.prop(domain, "clipping", text="Empty Space") + col.prop(domain, "delete_in_obstacle", text="Delete In Obstacle") if domain.cache_type == 'MODULAR': col.separator() + + # Deactivate bake operator if guides are enabled but not baked yet. + note_flag = True + if self.check_domain_has_unbaked_guide(domain) and domain.cache_type == 'MODULAR': + note = layout.split() + note_flag = False + note.enabled = note_flag + note.label(icon='INFO', text="Unbaked Guides: Bake Guides or disable them") + split = layout.split() + split.enabled = note_flag bake_incomplete = (domain.cache_frame_pause_data < domain.cache_frame_end) if domain.has_cache_baked_data and not domain.is_cache_baking_data and bake_incomplete: @@ -227,8 +236,8 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): col = grid.column() col.prop(flow, "flow_behavior", expand=False) - if flow.flow_behavior in {'INFLOW'}: - col.prop(flow, "use_inflow", text="Use Inflow") + if flow.flow_behavior in {'INFLOW', 'OUTFLOW'}: + col.prop(flow, "use_inflow", text="Use Flow") col.prop(flow, "subframes", text="Sampling Substeps") @@ -256,16 +265,19 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): row = layout.row() row.prop(effector_settings, "effector_type") - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + grid = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - col = flow.column() + col = grid.column() + col.prop(effector_settings, "subframes", text="Sampling Substeps") + col.prop(effector_settings, "surface_distance", text="Surface Thickness") + col = grid.column() + + col.prop(effector_settings, "use_effector", text="Use Effector") col.prop(effector_settings, "use_plane_init", text="Is Planar") - col.prop(effector_settings, "surface_distance", text="Surface Thickness") if effector_settings.effector_type == 'GUIDE': col.prop(effector_settings, "velocity_factor", text="Velocity Factor") - col = flow.column() col.prop(effector_settings, "guide_mode", text="Guide Mode") @@ -309,8 +321,8 @@ class PHYSICS_PT_borders(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): - bl_label = "Smoke" - bl_parent_id = 'PHYSICS_PT_settings' + bl_label = "Gas" + bl_parent_id = 'PHYSICS_PT_fluid' COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @classmethod @@ -354,10 +366,13 @@ class PHYSICS_PT_smoke_dissolve(PhysicButtonsPanel, Panel): return (context.engine in cls.COMPAT_ENGINES) def draw_header(self, context): - md = context.fluid - domain = md.domain_settings + md = context.fluid.domain_settings + domain = context.fluid.domain_settings - self.layout.prop(domain, "use_dissolve_smoke", text="") + is_baking_any = domain.is_cache_baking_any + + self.layout.enabled = not is_baking_any + self.layout.prop(md, "use_dissolve_smoke", text="") def draw(self, context): layout = self.layout @@ -383,7 +398,7 @@ class PHYSICS_PT_smoke_dissolve(PhysicButtonsPanel, Panel): class PHYSICS_PT_fire(PhysicButtonsPanel, Panel): bl_label = "Fire" - bl_parent_id = 'PHYSICS_PT_settings' + bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @@ -409,20 +424,22 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel): col = flow.column() col.prop(domain, "burning_rate", text="Reaction Speed") - col = flow.column(align=True) - col.prop(domain, "flame_smoke", text="Flame Smoke") - col.prop(domain, "flame_vorticity", text="Vorticity") + row = col.row() + sub = row.column(align=True) + sub.prop(domain, "flame_smoke", text="Flame Smoke") + sub.prop(domain, "flame_vorticity", text="Vorticity") + col = flow.column(align=True) col.prop(domain, "flame_max_temp", text="Temperature Maximum") col.prop(domain, "flame_ignition", text="Minimum") - col = flow.column() - col.prop(domain, "flame_smoke_color", text="Flame Color") + row = col.row() + row.prop(domain, "flame_smoke_color", text="Flame Color") class PHYSICS_PT_liquid(PhysicButtonsPanel, Panel): bl_label = "Liquid" - bl_parent_id = 'PHYSICS_PT_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + bl_parent_id = 'PHYSICS_PT_fluid' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @classmethod def poll(cls, context): @@ -433,6 +450,11 @@ class PHYSICS_PT_liquid(PhysicButtonsPanel, Panel): def draw_header(self, context): md = context.fluid.domain_settings + domain = context.fluid.domain_settings + + is_baking_any = domain.is_cache_baking_any + + self.layout.enabled = not is_baking_any self.layout.prop(md, "use_flip_particles", text="") def draw(self, context): @@ -445,32 +467,32 @@ class PHYSICS_PT_liquid(PhysicButtonsPanel, Panel): is_baking_any = domain.is_cache_baking_any has_baked_data = domain.has_cache_baked_data + layout.enabled = not is_baking_any and not has_baked_data flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) col = flow.column() - col0 = col.column() - col0.enabled = not is_baking_any and not has_baked_data - col0.prop(domain, "simulation_method", expand=False) - col0.prop(domain, "flip_ratio", text="FLIP Ratio") - col0.prop(domain, "particle_radius", text="Particle Radius") - - col1 = flow.column(align=True) - col1.enabled = not is_baking_any and not has_baked_data - col1.prop(domain, "particle_max", text="Particles Maximum") - col1.prop(domain, "particle_min", text="Minimum") - - col1 = flow.column() - col1.enabled = not is_baking_any and not has_baked_data - col1.prop(domain, "particle_number", text="Particle Sampling") - col1.prop(domain, "particle_band_width", text="Narrow Band Width") - col1.prop(domain, "particle_randomness", text="Particle Randomness") - - col2 = flow.column() - col2.enabled = not is_baking_any and not has_baked_data - col2.prop(domain, "use_fractions", text="Fractional Obstacles") - col3 = col2.column() - col3.enabled = domain.use_fractions and col2.enabled - col3.prop(domain, "fractions_threshold", text="Obstacle-Fluid Threshold") + col.prop(domain, "simulation_method", expand=False) + col.prop(domain, "flip_ratio", text="FLIP Ratio") + col = col.column(align=True) + col.prop(domain, "particle_radius", text="Particle Radius") + col.prop(domain, "particle_number", text="Sampling") + col.prop(domain, "particle_randomness", text="Randomness") + + col = flow.column() + col = col.column(align=True) + col.prop(domain, "particle_max", text="Particles Maximum") + col.prop(domain, "particle_min", text="Minimum") + + col.separator() + + col = col.column() + col.prop(domain, "particle_band_width", text="Narrow Band Width") + + col = col.column() + col.prop(domain, "use_fractions", text="Fractional Obstacles") + sub = col.column() + sub.active = domain.use_fractions + sub.prop(domain, "fractions_threshold", text="Obstacle-Fluid Threshold") class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel): @@ -518,7 +540,7 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel): class PHYSICS_PT_flow_initial_velocity(PhysicButtonsPanel, Panel): bl_label = "Initial Velocity" bl_parent_id = 'PHYSICS_PT_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @classmethod def poll(cls, context): @@ -609,15 +631,21 @@ class PHYSICS_PT_flow_texture(PhysicButtonsPanel, Panel): class PHYSICS_PT_adaptive_domain(PhysicButtonsPanel, Panel): bl_label = "Adaptive Domain" - bl_parent_id = 'PHYSICS_PT_fluid' + bl_parent_id = 'PHYSICS_PT_settings' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @classmethod def poll(cls, context): if not PhysicButtonsPanel.poll_gas_domain(context): return False + md = context.fluid + domain = md.domain_settings + # Effector guides require a fixed domain size + if domain.use_guide and domain.guide_source == 'EFFECTOR': + return False + return (context.engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -655,7 +683,7 @@ class PHYSICS_PT_adaptive_domain(PhysicButtonsPanel, Panel): class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): bl_label = "Noise" - bl_parent_id = 'PHYSICS_PT_fluid' + bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @@ -678,9 +706,7 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): layout.use_property_split = True domain = context.fluid.domain_settings - - # Deactivate UI if guides are enabled but not baked yet. - layout.active = domain.use_noise and not self.check_domain_has_unbaked_guide(domain) + layout.active = domain.use_noise is_baking_any = domain.is_cache_baking_any has_baked_noise = domain.has_cache_baked_noise @@ -701,8 +727,16 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): if domain.cache_type == 'MODULAR': col.separator() + # Deactivate bake operator if data has not been baked yet. + note_flag = True + if domain.use_noise and not domain.has_cache_baked_data and domain.cache_type == 'MODULAR': + note = layout.split() + note_flag = False + note.enabled = note_flag + note.label(icon='INFO', text="Unbaked Data: Bake Data first") + split = layout.split() - split.enabled = domain.has_cache_baked_data + split.enabled = domain.has_cache_baked_data and note_flag bake_incomplete = (domain.cache_frame_pause_noise < domain.cache_frame_end) if domain.has_cache_baked_noise and not domain.is_cache_baking_noise and bake_incomplete: @@ -721,7 +755,7 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): bl_label = "Mesh" - bl_parent_id = 'PHYSICS_PT_fluid' + bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @@ -744,9 +778,7 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): layout.use_property_split = True domain = context.fluid.domain_settings - - # Deactivate UI if guides are enabled but not baked yet. - layout.active = domain.use_mesh and not self.check_domain_has_unbaked_guide(domain) + layout.active = domain.use_mesh is_baking_any = domain.is_cache_baking_any has_baked_mesh = domain.has_cache_baked_mesh @@ -780,8 +812,16 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): if domain.cache_type == 'MODULAR': col.separator() + # Deactivate bake operator if data has not been baked yet. + note_flag = True + if domain.use_mesh and not domain.has_cache_baked_data and domain.cache_type == 'MODULAR': + note = layout.split() + note_flag = False + note.enabled = note_flag + note.label(icon='INFO', text="Unbaked Data: Bake Data first") + split = layout.split() - split.enabled = domain.has_cache_baked_data + split.enabled = domain.has_cache_baked_data and note_flag bake_incomplete = (domain.cache_frame_pause_mesh < domain.cache_frame_end) if domain.has_cache_baked_mesh and not domain.is_cache_baking_mesh and bake_incomplete: @@ -800,9 +840,9 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): bl_label = "Particles" - bl_parent_id = 'PHYSICS_PT_fluid' + bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @classmethod def poll(cls, context): @@ -817,9 +857,6 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings - # Deactivate UI if guides are enabled but not baked yet. - layout.active = not self.check_domain_has_unbaked_guide(domain) - is_baking_any = domain.is_cache_baking_any has_baked_particles = domain.has_cache_baked_particles using_particles = domain.use_spray_particles or domain.use_foam_particles or domain.use_bubble_particles @@ -829,36 +866,37 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): sndparticle_combined_export = domain.sndparticle_combined_export col = flow.column() - col.enabled = sndparticle_combined_export in {'OFF', 'FOAM + BUBBLES'} - col.prop(domain, "use_spray_particles", text="Spray") - col = flow.column() - col.enabled = sndparticle_combined_export in {'OFF', 'SPRAY + BUBBLES'} - col.prop(domain, "use_foam_particles", text="Foam") - col = flow.column() - col.enabled = sndparticle_combined_export in {'OFF', 'SPRAY + FOAM'} - col.prop(domain, "use_bubble_particles", text="Bubbles") + row = col.row() + row.enabled = sndparticle_combined_export in {'OFF', 'FOAM + BUBBLES'} + row.prop(domain, "use_spray_particles", text="Spray") + row.prop(domain, "use_foam_particles", text="Foam") + row.prop(domain, "use_bubble_particles", text="Bubbles") + + col.separator() + + col.prop(domain, "sndparticle_combined_export") flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - flow.enabled = not is_baking_any and not has_baked_particles and using_particles + flow.enabled = not is_baking_any and not has_baked_particles + flow.active = using_particles col = flow.column() - col.prop(domain, "sndparticle_combined_export") col.prop(domain, "particle_scale", text="Upres Factor") col.separator() col = flow.column(align=True) - col.prop(domain, "sndparticle_tau_max_wc", text="Wave Crest Potential Maximum") - col.prop(domain, "sndparticle_tau_min_wc", text="Minimum") + col.prop(domain, "sndparticle_potential_max_wavecrest", text="Wave Crest Potential Maximum") + col.prop(domain, "sndparticle_potential_min_wavecrest", text="Minimum") col.separator() col = flow.column(align=True) - col.prop(domain, "sndparticle_tau_max_ta", text="Trapped Air Potential Maximum") - col.prop(domain, "sndparticle_tau_min_ta", text="Minimum") + col.prop(domain, "sndparticle_potential_max_trappedair", text="Trapped Air Potential Maximum") + col.prop(domain, "sndparticle_potential_min_trappedair", text="Minimum") col.separator() col = flow.column(align=True) - col.prop(domain, "sndparticle_tau_max_k", text="Kinetic Energy Potential Maximum") - col.prop(domain, "sndparticle_tau_min_k", text="Minimum") + col.prop(domain, "sndparticle_potential_max_energy", text="Kinetic Energy Potential Maximum") + col.prop(domain, "sndparticle_potential_min_energy", text="Minimum") col.separator() col = flow.column(align=True) @@ -867,18 +905,18 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): col.separator() col = flow.column(align=True) - col.prop(domain, "sndparticle_k_wc", text="Wave Crest Particle Sampling") - col.prop(domain, "sndparticle_k_ta", text="Trapped Air Particle Sampling") + col.prop(domain, "sndparticle_sampling_wavecrest", text="Wave Crest Particle Sampling") + col.prop(domain, "sndparticle_sampling_trappedair", text="Trapped Air Particle Sampling") col.separator() col = flow.column(align=True) - col.prop(domain, "sndparticle_l_max", text="Particle Life Maximum") - col.prop(domain, "sndparticle_l_min", text="Minimum") + col.prop(domain, "sndparticle_life_max", text="Particle Life Maximum") + col.prop(domain, "sndparticle_life_min", text="Minimum") col.separator() col = flow.column(align=True) - col.prop(domain, "sndparticle_k_b", text="Bubble Buoyancy") - col.prop(domain, "sndparticle_k_d", text="Bubble Drag") + col.prop(domain, "sndparticle_bubble_buoyancy", text="Bubble Buoyancy") + col.prop(domain, "sndparticle_bubble_drag", text="Bubble Drag") col.separator() col = flow.column() @@ -887,8 +925,17 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): if domain.cache_type == 'MODULAR': col.separator() + # Deactivate bake operator if data has not been baked yet. + note_flag = True + if using_particles and not domain.has_cache_baked_data and domain.cache_type == 'MODULAR': + note = layout.split() + note_flag = False + note.enabled = note_flag + note.label(icon='INFO', text="Unbaked Data: Bake Data first") + split = layout.split() split.enabled = ( + note_flag and domain.has_cache_baked_data and (domain.use_spray_particles or domain.use_bubble_particles or @@ -913,7 +960,7 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): class PHYSICS_PT_diffusion(PhysicButtonsPanel, Panel): bl_label = "Diffusion" - bl_parent_id = 'PHYSICS_PT_fluid' + bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @@ -925,14 +972,23 @@ class PHYSICS_PT_diffusion(PhysicButtonsPanel, Panel): return (context.engine in cls.COMPAT_ENGINES) + def draw_header(self, context): + md = context.fluid.domain_settings + domain = context.fluid.domain_settings + is_baking_any = domain.is_cache_baking_any + has_baked_any = domain.has_cache_baked_any + self.layout.enabled = not is_baking_any and not has_baked_any + self.layout.prop(md, "use_diffusion", text="") + + def draw_header_preset(self, _context): + FLUID_PT_presets.draw_panel_header(self.layout) + def draw(self, context): layout = self.layout layout.use_property_split = True domain = context.fluid.domain_settings - - # Deactivate UI if guides are enabled but not baked yet. - layout.active = not self.check_domain_has_unbaked_guide(domain) + layout.active = domain.use_diffusion is_baking_any = domain.is_cache_baking_any has_baked_any = domain.has_cache_baked_any @@ -941,22 +997,11 @@ class PHYSICS_PT_diffusion(PhysicButtonsPanel, Panel): flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) flow.enabled = not is_baking_any and not has_baked_any and not has_baked_data - row = flow.row() - - col = row.column() - col.label(text="Viscosity Presets:") - col.menu("FLUID_MT_presets", text=bpy.types.FLUID_MT_presets.bl_label) - - col = row.column(align=True) - col.operator("fluid.preset_add", text="", icon='ADD') - col.operator("fluid.preset_add", text="", icon='REMOVE').remove_active = True - col = flow.column(align=True) col.prop(domain, "viscosity_base", text="Base") col.prop(domain, "viscosity_exponent", text="Exponent", slider=True) col = flow.column() - col.prop(domain, "domain_size", text="Real World Size") col.prop(domain, "surface_tension", text="Surface Tension") @@ -964,7 +1009,7 @@ class PHYSICS_PT_guide(PhysicButtonsPanel, Panel): bl_label = "Guides" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @classmethod def poll(cls, context): @@ -1018,7 +1063,8 @@ class PHYSICS_PT_guide(PhysicButtonsPanel, Panel): col = split.column() col.operator("fluid.free_guides", text="Free") elif not domain.has_cache_baked_guide and domain.is_cache_baking_guide: - split.operator("fluid.pause_bake", text="Pause Guides") + split.enabled = False + split.operator("fluid.pause_bake", text="Baking Guides - ESC to pause") elif not domain.has_cache_baked_guide and not domain.is_cache_baking_guide: split.operator("fluid.bake_guides", text="Bake Guides") else: @@ -1072,7 +1118,10 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings is_baking_any = domain.is_cache_baking_any - has_baked_any = domain.has_cache_baked_any + has_baked_data = domain.has_cache_baked_data + has_baked_noise = domain.has_cache_baked_noise + has_baked_mesh = domain.has_cache_baked_mesh + has_baked_particles = domain.has_cache_baked_particles col = layout.column() col.prop(domain, "cache_directory", text="") @@ -1086,29 +1135,37 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): col.prop(domain, "cache_type", expand=False) col.enabled = not is_baking_any - col = flow.column(align=True) col.separator() + row = col.row() + col = row.column(align=True) col.prop(domain, "cache_frame_start", text="Frame Start") col.prop(domain, "cache_frame_end", text="End") - col.enabled = not is_baking_any + row.enabled = not is_baking_any col.separator() col = flow.column() - col.enabled = not is_baking_any and not has_baked_any - col.prop(domain, "cache_data_format", text="Data File Format") + row = col.row() + row.enabled = not is_baking_any and not has_baked_data + row.prop(domain, "cache_data_format", text="Data File Format") if md.domain_settings.domain_type in {'GAS'}: if domain.use_noise: - col.prop(domain, "cache_noise_format", text="Noise File Format") + row = col.row() + row.enabled = not is_baking_any and not has_baked_noise + row.prop(domain, "cache_noise_format", text="Noise File Format") if md.domain_settings.domain_type in {'LIQUID'}: # File format for all particle systemes (FLIP and secondary) - col.prop(domain, "cache_particle_format", text="Particle File Format") + row = col.row() + row.enabled = not is_baking_any and not has_baked_particles and not has_baked_data + row.prop(domain, "cache_particle_format", text="Particle File Format") if domain.use_mesh: - col.prop(domain, "cache_mesh_format", text="Mesh File Format") + row = col.row() + row.enabled = not is_baking_any and not has_baked_mesh + row.prop(domain, "cache_mesh_format", text="Mesh File Format") if domain.cache_type == 'FINAL': @@ -1132,7 +1189,8 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): - if not PhysicButtonsPanel.poll_fluid_domain(context): + # Only show the advanced panel to advanced users who know Mantaflow's birthday :) + if not PhysicButtonsPanel.poll_fluid_domain(context) or bpy.app.debug_value != 3001: return False return (context.engine in cls.COMPAT_ENGINES) @@ -1186,35 +1244,31 @@ class PHYSICS_PT_viewport_display(PhysicButtonsPanel, Panel): flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) domain = context.fluid.domain_settings - - col = flow.column() - col.prop(domain, "display_thickness") - - col.separator() - - col.prop(domain, "slice_method", text="Slicing") - slice_method = domain.slice_method axis_slice_method = domain.axis_slice_method do_axis_slicing = (slice_method == 'AXIS_ALIGNED') do_full_slicing = (axis_slice_method == 'FULL') - col = col.column() - col.enabled = do_axis_slicing - col.prop(domain, "axis_slice_method") + col = flow.column(align=False) + col.prop(domain, "display_thickness") + col.prop(domain, "display_interpolation") + col.separator() col = flow.column() - sub = col.column() - sub.enabled = not do_full_slicing and do_axis_slicing - sub.prop(domain, "slice_axis") - sub.prop(domain, "slice_depth") + col.prop(domain, "slice_method", text="Slicing") - row = col.row() - row.enabled = do_full_slicing or not do_axis_slicing - row.prop(domain, "slice_per_voxel") + col = col.column() + col.active = do_axis_slicing + col.prop(domain, "axis_slice_method") - col.prop(domain, "display_interpolation") + if not do_full_slicing and do_axis_slicing: + col.prop(domain, "slice_axis") + col.prop(domain, "slice_depth") + + col = col.column() + col.active = do_full_slicing or not do_axis_slicing + col.prop(domain, "slice_per_voxel") class PHYSICS_PT_viewport_display_color(PhysicButtonsPanel, Panel): @@ -1237,8 +1291,7 @@ class PHYSICS_PT_viewport_display_color(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings col = layout.column() - col.enabled = domain.use_color_ramp - + col.active = domain.use_color_ramp col.prop(domain, "coba_field") col.use_property_split = False @@ -1269,33 +1322,33 @@ class PHYSICS_PT_viewport_display_debug(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings col = flow.column() - col.enabled = domain.show_velocity + col.active = domain.show_velocity col.prop(domain, "vector_display_type", text="Display As") col.prop(domain, "vector_scale") classes = ( - FLUID_MT_presets, + FLUID_PT_presets, PHYSICS_PT_fluid, PHYSICS_PT_settings, PHYSICS_PT_borders, + PHYSICS_PT_adaptive_domain, PHYSICS_PT_smoke, PHYSICS_PT_smoke_dissolve, + PHYSICS_PT_noise, PHYSICS_PT_fire, PHYSICS_PT_liquid, - PHYSICS_PT_flow_source, - PHYSICS_PT_flow_initial_velocity, - PHYSICS_PT_flow_texture, - PHYSICS_PT_adaptive_domain, - PHYSICS_PT_noise, - PHYSICS_PT_mesh, - PHYSICS_PT_particles, PHYSICS_PT_diffusion, + PHYSICS_PT_particles, + PHYSICS_PT_mesh, PHYSICS_PT_guide, PHYSICS_PT_collections, PHYSICS_PT_cache, PHYSICS_PT_export, PHYSICS_PT_field_weights, + PHYSICS_PT_flow_source, + PHYSICS_PT_flow_initial_velocity, + PHYSICS_PT_flow_texture, PHYSICS_PT_viewport_display, PHYSICS_PT_viewport_display_color, PHYSICS_PT_viewport_display_debug, diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 6a89fb007cf..c5c75f95937 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -297,7 +297,7 @@ class RENDER_PT_eevee_volumetric_shadows(RenderButtonsPanel, Panel): props = scene.eevee layout.active = props.use_volumetric_shadows - layout.prop(props, "volumetric_shadow_samples", text="Shadow Samples") + layout.prop(props, "volumetric_shadow_samples", text="Samples") class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel): @@ -478,39 +478,47 @@ class RENDER_PT_eevee_film(RenderButtonsPanel, Panel): scene = context.scene rd = scene.render + props = scene.eevee col = layout.column() col.prop(rd, "filter_size") col.prop(rd, "film_transparent", text="Transparent") + col = layout.column(align=False, heading="Overscan") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(props, "use_overscan", text="") + sub = sub.row(align=True) + sub.active = props.use_overscan + sub.prop(props, "overscan_size", text="") + row.prop_decorator(props, "overscan_size") + -class RENDER_PT_eevee_film_overscan(RenderButtonsPanel, Panel): - bl_label = "Overscan" - bl_parent_id = "RENDER_PT_eevee_film" +class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): + bl_label = "Hair" bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_EEVEE'} - def draw_header(self, context): - - scene = context.scene - props = scene.eevee - - self.layout.prop(props, "use_overscan", text="") + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout - layout.use_property_split = True scene = context.scene - props = scene.eevee + rd = scene.render - layout.active = props.use_overscan - layout.prop(props, "overscan_size", text="Size") + layout.use_property_split = True + layout.prop(rd, "hair_type", expand=True) + layout.prop(rd, "hair_subdiv") -class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): - bl_label = "Hair" + +class RENDER_PT_eevee_performance(RenderButtonsPanel, Panel): + bl_label = "Performance" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} @classmethod def poll(cls, context): @@ -523,8 +531,28 @@ class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): layout.use_property_split = True - layout.prop(rd, "hair_type", expand=True) - layout.prop(rd, "hair_subdiv") + layout.prop(rd, "use_high_quality_normals") + + +class RENDER_PT_gpencil(RenderButtonsPanel, Panel): + bl_label = "Grease Pencil" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + scene = context.scene + props = scene.grease_pencil_settings + + col = layout.column() + col.prop(props, "antialias_threshold") + class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): @@ -545,7 +573,7 @@ class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): col = layout.column() col.prop(props, "render_aa", text="Render") - col.prop(props, "viewport_aa", text="Viewport Render") + col.prop(props, "viewport_aa", text="Viewport") class RENDER_PT_opengl_film(RenderButtonsPanel, Panel): @@ -632,9 +660,6 @@ class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel): col = flow.column() col.prop(rd, "simplify_child_particles", text="Max Child Particles") - col = flow.column() - col.prop(rd, "use_simplify_smoke_highres", text="High-resolution Smoke") - class RENDER_PT_simplify_render(RenderButtonsPanel, Panel): bl_label = "Render" @@ -979,12 +1004,14 @@ classes = ( RENDER_PT_eevee_volumetric, RENDER_PT_eevee_volumetric_lighting, RENDER_PT_eevee_volumetric_shadows, + RENDER_PT_eevee_performance, RENDER_PT_eevee_hair, RENDER_PT_eevee_shadows, RENDER_PT_eevee_indirect_lighting, RENDER_PT_eevee_indirect_lighting_display, RENDER_PT_eevee_film, - RENDER_PT_eevee_film_overscan, + + RENDER_PT_gpencil, RENDER_PT_opengl_sampling, RENDER_PT_opengl_lighting, RENDER_PT_opengl_color, diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 40a630ff834..5af8bc2aaa7 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -163,6 +163,8 @@ class TEXTURE_PT_node(TextureButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + node = context.texture_node ntree = node.id_data layout.template_node_view(ntree, node, None) diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py index 121b8f2f401..3645f0dc2f2 100644 --- a/release/scripts/startup/bl_ui/properties_view_layer.py +++ b/release/scripts/startup/bl_ui/properties_view_layer.py @@ -40,17 +40,12 @@ class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - layout.use_property_split = True - scene = context.scene rd = scene.render layer = context.view_layer - col = flow.column() + col = layout.column() col.prop(layer, "use", text="Use for Rendering") - col = flow.column() col.prop(rd, "use_single_layer", text="Render Single Layer") @@ -59,33 +54,94 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel): COMPAT_ENGINES = {'BLENDER_EEVEE'} def draw(self, context): - layout = self.layout + pass - layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) +class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel): + bl_label = "Data" + bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes" + + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + scene = context.scene + rd = scene.render view_layer = context.view_layer - col = flow.column() + col = layout.column() col.prop(view_layer, "use_pass_combined") - col = flow.column() col.prop(view_layer, "use_pass_z") - col = flow.column() col.prop(view_layer, "use_pass_mist") - col = flow.column() col.prop(view_layer, "use_pass_normal") - col = flow.column() - col.prop(view_layer, "use_pass_ambient_occlusion") - col = flow.column() - col.prop(view_layer, "use_pass_subsurface_direct", text="Subsurface Direct") - col = flow.column() - col.prop(view_layer, "use_pass_subsurface_color", text="Subsurface Color") +class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel): + bl_label = "Light" + bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + + layout.use_property_split = True + layout.use_property_decorate = False + + view_layer = context.view_layer + view_layer_eevee = view_layer.eevee + scene = context.scene + scene_eevee = scene.eevee + + col = layout.column(heading="Diffuse", align=True) + col.prop(view_layer, "use_pass_diffuse_direct", text="Light") + col.prop(view_layer, "use_pass_diffuse_color", text="Color") + + col = layout.column(heading="Specular", align=True) + col.prop(view_layer, "use_pass_glossy_direct", text="Light") + col.prop(view_layer, "use_pass_glossy_color", text="Color") + + col = layout.column(heading="Volume", align=True) + col.prop(view_layer_eevee, "use_pass_volume_transmittance", text="Transmittance") + col.prop(view_layer_eevee, "use_pass_volume_scatter", text="Scatter") + + col = layout.column(heading="Other", align=True) + col.prop(view_layer, "use_pass_emit", text="Emission") + col.prop(view_layer, "use_pass_environment") + col.prop(view_layer, "use_pass_shadow") + row = col.row() + row.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion") + row.active = scene_eevee.use_gtao + + +class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel): + bl_label = "Effects" + bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + + layout.use_property_split = True + layout.use_property_decorate = False + + view_layer = context.view_layer + view_layer_eevee = view_layer.eevee + scene = context.scene + scene_eevee = scene.eevee + + col = layout.column() + col.prop(view_layer_eevee, "use_pass_bloom", text="Bloom") + col.active = scene_eevee.use_bloom + classes = ( VIEWLAYER_PT_layer, VIEWLAYER_PT_eevee_layer_passes, + VIEWLAYER_PT_eevee_layer_passes_data, + VIEWLAYER_PT_eevee_layer_passes_light, + VIEWLAYER_PT_eevee_layer_passes_effects, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_workspace.py b/release/scripts/startup/bl_ui/properties_workspace.py index 322cdee0922..8af30b5c002 100644 --- a/release/scripts/startup/bl_ui/properties_workspace.py +++ b/release/scripts/startup/bl_ui/properties_workspace.py @@ -77,8 +77,6 @@ class WORKSPACE_PT_addons(WorkSpaceButtonsPanel, Panel): if module is None: continue info = addon_utils.module_bl_info(module) - if not info["use_owner"]: - continue is_enabled = module_name in owner_ids row = col.row() row.alignment = 'LEFT' diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index a6a58ec4e2b..4a9f35ee59a 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -105,6 +105,8 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): layout.prop(world, "use_nodes", icon='NODETREE') layout.separator() + layout.use_property_split = True + if world.use_nodes: ntree = world.node_tree node = ntree.get_output_node('EEVEE') @@ -139,6 +141,8 @@ class EEVEE_WORLD_PT_volume(WorldButtonsPanel, Panel): ntree = world.node_tree node = ntree.get_output_node('EEVEE') + layout.use_property_split = True + if node: input = find_node_input(node, 'Volume') if input: diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index f93629a4f03..5b6cc6609e0 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -918,6 +918,10 @@ class CLIP_PT_tracking_lens(Panel): col = layout.column(align=True) col.prop(camera, "division_k1") col.prop(camera, "division_k2") + elif camera.distortion_model == 'NUKE': + col = layout.column(align=True) + col.prop(camera, "nuke_k1") + col.prop(camera, "nuke_k2") class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel): diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index a09e263fd87..3f8c41e4f21 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -26,6 +26,7 @@ from bpy.types import ( ) from bl_ui.properties_grease_pencil_common import ( + GreasePencilLayerMasksPanel, GreasePencilLayerAdjustmentsPanel, GreasePencilLayerRelationsPanel, GreasePencilLayerDisplayPanel, @@ -125,6 +126,12 @@ class DopesheetFilterPopoverBase: flow.prop(dopesheet, "show_lattices", text="Lattices") if bpy.data.metaballs: flow.prop(dopesheet, "show_metaballs", text="Metaballs") + if hasattr(bpy.data, "hairs") and bpy.data.hairs: + flow.prop(dopesheet, "show_hairs", text="Hairs") + if hasattr(bpy.data, "pointclouds") and bpy.data.pointclouds: + flow.prop(dopesheet, "show_pointclouds", text="Point Clouds") + if bpy.data.volumes: + flow.prop(dopesheet, "show_volumes", text="Volumes") # data types flow.prop(dopesheet, "show_worlds", text="Worlds") @@ -251,15 +258,25 @@ class DOPESHEET_HT_editor_buttons(Header): # Layer management if st.mode == 'GPENCIL': - row = layout.row(align=True) - row.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP' - row.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN' + ob = context.active_object + selected = st.dopesheet.show_only_selected + enable_but = selected and ob is not None and ob.type == 'GPENCIL' row = layout.row(align=True) + row.enabled = enable_but row.operator("gpencil.layer_add", icon='ADD', text="") row.operator("gpencil.layer_remove", icon='REMOVE', text="") + row.menu("GPENCIL_MT_layer_context_menu", icon='DOWNARROW_HLT', text="") - layout.separator_spacer() + row = layout.row(align=True) + row.enabled = enable_but + row.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP' + row.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN' + + row = layout.row(align=True) + row.enabled = enable_but + row.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_ON', text="").affect_visibility = True + row.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False layout.separator_spacer() @@ -269,15 +286,8 @@ class DOPESHEET_HT_editor_buttons(Header): dopesheet_filter(layout, context) elif st.mode == 'GPENCIL': row = layout.row(align=True) - row.prop(st.dopesheet, "show_gpencil_3d_only", text="Active Only") - - if st.dopesheet.show_gpencil_3d_only: - row = layout.row(align=True) - row.prop(st.dopesheet, "show_only_selected", text="") - row.prop(st.dopesheet, "show_hidden", text="") - - row = layout.row(align=True) - row.prop(st.dopesheet, "filter_text", text="") + row.prop(st.dopesheet, "show_only_selected", text="") + row.prop(st.dopesheet, "show_hidden", text="") layout.popover( panel="DOPESHEET_PT_filters", @@ -497,6 +507,7 @@ class DOPESHEET_MT_key(Menu): layout.operator_menu_enum("action.keyframe_type", "type", text="Keyframe Type") layout.operator_menu_enum("action.handle_type", "type", text="Handle Type") layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode") + layout.operator_menu_enum("action.easing_type", "type", text="Easing Mode") layout.separator() layout.operator("action.clean").channels = False @@ -599,6 +610,7 @@ class DOPESHEET_MT_context_menu(Menu): layout.operator_menu_enum("action.keyframe_type", "type", text="Keyframe Type") layout.operator_menu_enum("action.handle_type", "type", text="Handle Type") layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode") + layout.operator_menu_enum("action.easing_type", "type", text="Easing Mode") layout.separator() @@ -616,7 +628,7 @@ class DOPESHEET_MT_context_menu(Menu): class DOPESHEET_MT_channel_context_menu(Menu): bl_label = "Dope Sheet Channel Context Menu" - def draw(self, _context): + def draw(self, context): layout = self.layout layout.operator("anim.channels_setting_enable", text="Mute Channels").type = 'MUTE' @@ -631,7 +643,12 @@ class DOPESHEET_MT_channel_context_menu(Menu): layout.separator() layout.operator("anim.channels_editable_toggle") - layout.operator_menu_enum("action.extrapolation_type", "type", text="Extrapolation Mode") + + if bpy.ops.graph.extrapolation_type.poll(context.copy()): + operator = "graph.extrapolation_type" + else: + operator = "action.extrapolation_type" + layout.operator_menu_enum(operator, "type", text="Extrapolation Mode") layout.separator() layout.operator("anim.channels_expand") @@ -699,6 +716,15 @@ class DOPESHEET_PT_gpencil_mode(LayersDopeSheetPanel, Panel): row = layout.row(align=True) row.prop(gpl, "opacity", text="Opacity", slider=True) + row = layout.row(align=True) + row.prop(gpl, "use_lights") + + +class DOPESHEET_PT_gpencil_layer_masks(LayersDopeSheetPanel, GreasePencilLayerMasksPanel, Panel): + bl_label = "Masks" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + class DOPESHEET_PT_gpencil_layer_adjustments(LayersDopeSheetPanel, GreasePencilLayerAdjustmentsPanel, Panel): bl_label = "Adjustments" @@ -736,6 +762,7 @@ classes = ( DOPESHEET_MT_snap_pie, DOPESHEET_PT_filters, DOPESHEET_PT_gpencil_mode, + DOPESHEET_PT_gpencil_layer_masks, DOPESHEET_PT_gpencil_layer_adjustments, DOPESHEET_PT_gpencil_layer_relations, DOPESHEET_PT_gpencil_layer_display, diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 8dd0eaf5445..9a39d840149 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -20,6 +20,7 @@ from bpy.types import Header, Panel, Menu, UIList + class FILEBROWSER_HT_header(Header): bl_space_type = 'FILE_BROWSER' @@ -31,8 +32,7 @@ class FILEBROWSER_HT_header(Header): if st.active_operator is None: layout.template_header() - layout.menu("FILEBROWSER_MT_view") - layout.menu("FILEBROWSER_MT_select") + FILEBROWSER_MT_editor_menus.draw_collapsible(context, layout) # can be None when save/reload with a file selector open @@ -66,8 +66,9 @@ class FILEBROWSER_PT_display(Panel): if params.display_type == 'THUMBNAIL': layout.prop(params, "display_size", text="Size") else: - layout.prop(params, "show_details_size", text="Size") - layout.prop(params, "show_details_datetime", text="Date") + col = layout.column(heading="Columns", align=True) + col.prop(params, "show_details_size", text="Size") + col.prop(params, "show_details_datetime", text="Date") layout.prop(params, "recursion_level", text="Recursions") @@ -137,6 +138,9 @@ class FILEBROWSER_PT_filter(Panel): row = col.row() row.label(icon='FILE_TEXT') row.prop(params, "use_filter_text", text="Text Files", toggle=0) + row = col.row() + row.label(icon='FILE_VOLUME') + row.prop(params, "use_filter_volume", text="Volume Files", toggle=0) col.separator() @@ -148,7 +152,12 @@ class FILEBROWSER_PT_filter(Panel): if params.use_filter_blendid: row = col.row() row.label(icon='BLANK1') # Indentation - row.prop(params, "filter_id_category", text="") + + sub = row.column(align=True) + filter_id = params.filter_id + for identifier in dir(filter_id): + if identifier.startswith("category_"): + sub.prop(filter_id, identifier, toggle=True) col.separator() @@ -275,7 +284,7 @@ class FILEBROWSER_PT_bookmarks_recents(Panel): bl_space_type = 'FILE_BROWSER' bl_region_type = 'TOOLS' bl_category = "Bookmarks" - bl_label = "Recents" + bl_label = "Recent" @classmethod def poll(cls, context): @@ -314,8 +323,11 @@ class FILEBROWSER_PT_advanced_filter(Panel): layout.prop(params, "use_filter_blendid") if params.use_filter_blendid: layout.separator() - col = layout.column() - col.prop(params, "filter_id") + col = layout.column(align=True) + filter_id = params.filter_id + for identifier in dir(filter_id): + if identifier.startswith("filter_"): + col.prop(filter_id, identifier, toggle=True) class FILEBROWSER_PT_directory_path(Panel): @@ -399,6 +411,17 @@ class FILEBROWSER_PT_directory_path(Panel): ).region_type = 'TOOL_PROPS' +class FILEBROWSER_MT_editor_menus(Menu): + bl_idname = "FILEBROWSER_MT_editor_menus" + bl_label = "" + + def draw(self, _context): + layout = self.layout + + layout.menu("FILEBROWSER_MT_view") + layout.menu("FILEBROWSER_MT_select") + + class FILEBROWSER_MT_view(Menu): bl_label = "View" @@ -490,6 +513,7 @@ classes = ( FILEBROWSER_PT_bookmarks_recents, FILEBROWSER_PT_advanced_filter, FILEBROWSER_PT_directory_path, + FILEBROWSER_MT_editor_menus, FILEBROWSER_MT_view, FILEBROWSER_MT_select, FILEBROWSER_MT_context_menu, diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index 2e853a287ea..c251d55714f 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -171,14 +171,10 @@ class GRAPH_MT_select(Menu): layout.separator() - props = layout.operator("graph.select_box") - props.axis_range = False - props.include_handles = False + layout.operator("graph.select_box") props = layout.operator("graph.select_box", text="Box Select (Axis Range)") props.axis_range = True - props.include_handles = False props = layout.operator("graph.select_box", text="Box Select (Include Handles)") - props.axis_range = False props.include_handles = True layout.operator("graph.select_circle") diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index c6f490f9d26..bc4665209aa 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -116,7 +116,7 @@ class IMAGE_MT_view(Menu): if show_uvedit: layout.operator("image.view_selected", text="Frame Selected") - layout.operator("image.view_all", text="Frame All") + layout.operator("image.view_all") layout.operator("image.view_all", text="Frame All Fit").fit_view = True layout.operator("image.view_center_cursor", text="Center View to Cursor") @@ -238,6 +238,11 @@ class IMAGE_MT_image(Menu): layout.separator() layout.operator("image.pack", text="Pack") + if ima: + layout.separator() + layout.operator("palette.extract_from_image", text="Extract Palette") + layout.operator("gpencil.image_to_grease_pencil", text="Generate Grease Pencil") + class IMAGE_MT_image_invert(Menu): bl_label = "Invert" @@ -379,6 +384,10 @@ class IMAGE_MT_uvs(Menu): layout.separator() + layout.operator("uv.reset") + + layout.separator() + class IMAGE_MT_uvs_select_mode(Menu): bl_label = "UV Select Mode" @@ -698,7 +707,7 @@ class IMAGE_HT_header(Header): layout.prop(tool_settings, "uv_select_mode", text="", expand=True) layout.prop(uvedit, "sticky_select_mode", icon_only=True) - MASK_MT_editor_menus.draw_collapsible(context, layout) + IMAGE_MT_editor_menus.draw_collapsible(context, layout) layout.separator_spacer() @@ -744,8 +753,8 @@ class IMAGE_HT_header(Header): row.operator("image.play_composite", icon='PLAY') -class MASK_MT_editor_menus(Menu): - bl_idname = "MASK_MT_editor_menus" +class IMAGE_MT_editor_menus(Menu): + bl_idname = "IMAGE_MT_editor_menus" bl_label = "" def draw(self, context): @@ -950,6 +959,7 @@ class IMAGE_PT_view_display_uv_edit_overlays(Panel): col = layout.column() col.prop(uvedit, "show_smooth_edges", text="Smooth") col.prop(uvedit, "show_modified_edges", text="Modified") + col.prop(uvedit, "uv_opacity") class IMAGE_PT_view_display_uv_edit_overlays_stretch(Panel): @@ -1460,7 +1470,7 @@ classes = ( IMAGE_MT_uvs_snap_pie, IMAGE_HT_tool_header, IMAGE_HT_header, - MASK_MT_editor_menus, + IMAGE_MT_editor_menus, IMAGE_PT_active_tool, IMAGE_PT_mask, IMAGE_PT_mask_layers, diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 2ce81ba8359..b5926692324 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -76,7 +76,8 @@ class NODE_HT_header(Header): layout.separator_spacer() - types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'GPENCIL'} + types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', + 'GPENCIL', 'VOLUME', 'HAIR', 'POINTCLOUD'} # disable material slot buttons when pinned, cannot find correct slot within id_from (#36589) # disable also when the selected object does not support materials has_material_slots = not snode.pin and ob_type in types_that_support_material @@ -150,6 +151,14 @@ class NODE_HT_header(Header): if snode_id: layout.prop(snode_id, "use_nodes") + elif snode.tree_type == 'SimulationNodeTree': + row = layout.row(align=True) + row.prop(snode, "simulation", text="") + row.operator("simulation.new", text="", icon='ADD') + simulation = snode.simulation + if simulation: + row.prop(snode.simulation, "use_fake_user", text="") + else: # Custom node tree is edited as independent ID block NODE_MT_editor_menus.draw_collapsible(context, layout) @@ -530,7 +539,12 @@ class NODE_PT_active_node_properties(Panel): layout.label(text="Inputs:") for socket in value_inputs: row = layout.row() - socket.draw(context, row, node, iface_(socket.name, socket.bl_rna.translation_context)) + socket.draw( + context, + row, + node, + iface_(socket.label if socket.label else socket.name, socket.bl_rna.translation_context), + ) class NODE_PT_texture_mapping(Panel): diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 11fb20d8b38..ee8015df273 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -19,6 +19,10 @@ # <pep8 compliant> import bpy from bpy.types import Header, Menu, Panel +from bpy.app.translations import ( + contexts as i18n_contexts, + pgettext_iface as iface_, +) class OUTLINER_HT_header(Header): @@ -100,20 +104,26 @@ class OUTLINER_MT_editor_menus(Menu): layout.menu("OUTLINER_MT_edit_datablocks") -class OUTLINER_MT_context(Menu): - bl_label = "Outliner" +class OUTLINER_MT_context_menu(Menu): + bl_label = "Outliner Context Menu" + + def draw(self, context): + space = context.space_data - def draw(self, _context): layout = self.layout - layout.menu("OUTLINER_MT_context_view") + if space.display_mode == 'VIEW_LAYER': + OUTLINER_MT_collection_new.draw_without_context_menu(context, layout) + layout.separator() + + layout.menu("OUTLINER_MT_context_menu_view") layout.separator() layout.menu("INFO_MT_area") -class OUTLINER_MT_context_view(Menu): +class OUTLINER_MT_context_menu_view(Menu): bl_label = "View" def draw(self, _context): @@ -202,8 +212,8 @@ class OUTLINER_MT_collection(Menu): layout.separator() - layout.operator("outliner.collection_delete", text="Delete", icon='X').hierarchy = False - layout.operator("outliner.collection_delete", text="Delete Hierarchy").hierarchy = True + layout.operator("outliner.delete", text="Delete", icon='X') + layout.operator("outliner.collection_hierarchy_delete") layout.separator() @@ -232,21 +242,25 @@ class OUTLINER_MT_collection(Menu): layout.separator() - OUTLINER_MT_context.draw(self, context) + OUTLINER_MT_context_menu.draw(self, context) class OUTLINER_MT_collection_new(Menu): bl_label = "Collection" + @staticmethod + def draw_without_context_menu(context, layout): + layout.operator("outliner.collection_new", text="New Collection").nested = False + layout.operator("outliner.id_paste", text="Paste Data-Blocks", icon='PASTEDOWN') + def draw(self, context): layout = self.layout - layout.operator("outliner.collection_new", text="New").nested = False - layout.operator("outliner.id_paste", text="Paste", icon='PASTEDOWN') + self.draw_without_context_menu(context, layout) layout.separator() - OUTLINER_MT_context.draw(self, context) + OUTLINER_MT_context_menu.draw(self, context) class OUTLINER_MT_object(Menu): @@ -264,7 +278,7 @@ class OUTLINER_MT_object(Menu): layout.separator() - layout.operator("outliner.object_operation", text="Delete", icon='X').type = 'DELETE' + layout.operator("outliner.delete", text="Delete", icon='X') if space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection: layout.operator("outliner.object_operation", text="Delete Hierarchy").type = 'DELETE_HIERARCHY' @@ -279,8 +293,10 @@ class OUTLINER_MT_object(Menu): if object_mode in {'EDIT', 'POSE'}: name = bpy.types.Object.bl_rna.properties["mode"].enum_items[object_mode].name - layout.operator("outliner.object_operation", text=f"{name:s} Set").type = 'OBJECT_MODE_ENTER' - layout.operator("outliner.object_operation", text=f"{name:s} Clear").type = 'OBJECT_MODE_EXIT' + layout.operator("outliner.object_operation", + text=iface_("%s Set", i18n_contexts.operator_default) % name).type = 'OBJECT_MODE_ENTER' + layout.operator("outliner.object_operation", + text=iface_("%s Clear", i18n_contexts.operator_default) % name).type = 'OBJECT_MODE_EXIT' del name layout.separator() @@ -293,7 +309,7 @@ class OUTLINER_MT_object(Menu): layout.separator() - OUTLINER_MT_context.draw(self, context) + OUTLINER_MT_context_menu.draw(self, context) class OUTLINER_PT_filter(Panel): @@ -391,6 +407,9 @@ class OUTLINER_PT_filter(Panel): if ( bpy.data.curves or bpy.data.metaballs or + (hasattr(bpy.data, "hairs") and bpy.data.hairs) or + (hasattr(bpy.data, "pointclouds") and bpy.data.pointclouds) or + bpy.data.volumes or bpy.data.lightprobes or bpy.data.lattices or bpy.data.fonts or @@ -410,8 +429,8 @@ classes = ( OUTLINER_MT_collection_visibility, OUTLINER_MT_collection_view_layer, OUTLINER_MT_object, - OUTLINER_MT_context, - OUTLINER_MT_context_view, + OUTLINER_MT_context_menu, + OUTLINER_MT_context_menu_view, OUTLINER_PT_filter, ) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index af0c23e7892..ca25c29960c 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -29,6 +29,7 @@ from bpy.app.translations import ( ) from bl_ui.properties_grease_pencil_common import ( AnnotationDataPanel, + AnnotationOnionSkin, ) from bl_ui.space_toolsystem_common import ( ToolActivePanelHelper, @@ -275,7 +276,7 @@ class SEQUENCER_MT_view(Menu): if is_sequencer_view: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("sequencer.view_selected", text="Frame Selected") - layout.operator("sequencer.view_all", text="Frame All") + layout.operator("sequencer.view_all") layout.operator("view2d.zoom_border", text="Zoom") if is_preview: @@ -309,6 +310,7 @@ class SEQUENCER_MT_view(Menu): layout.prop(st, "show_seconds") layout.prop(st, "show_locked_time") layout.prop(st, "show_strip_offset") + layout.prop(st, "show_fcurves") layout.separator() layout.prop(st, "show_markers") @@ -404,6 +406,8 @@ class SEQUENCER_MT_select(Menu): layout.separator() layout.operator("sequencer.select_box", text="Box Select") + props = layout.operator("sequencer.select_box", text="Box Select (Include Handles)") + props.include_handles = True layout.separator() @@ -716,8 +720,8 @@ class SEQUENCER_MT_strip(Menu): layout.menu("SEQUENCER_MT_strip_transform") layout.separator() - layout.operator("sequencer.cut", text="Cut").type = 'SOFT' - layout.operator("sequencer.cut", text="Hold Cut").type = 'HARD' + layout.operator("sequencer.split", text="Split").type = 'SOFT' + layout.operator("sequencer.split", text="Hold Split").type = 'HARD' layout.separator() layout.operator("sequencer.copy", text="Copy") @@ -781,7 +785,7 @@ class SEQUENCER_MT_context_menu(Menu): layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("sequencer.cut", text="Cut").type = 'SOFT' + layout.operator("sequencer.split", text="Split").type = 'SOFT' layout.separator() @@ -842,7 +846,7 @@ class SEQUENCER_MT_context_menu(Menu): }: layout.separator() layout.menu("SEQUENCER_MT_strip_effect") - elif strip_type in 'MOVIE': + elif strip_type == 'MOVIE': layout.separator() layout.menu("SEQUENCER_MT_strip_movie") elif strip_type == 'IMAGE': @@ -1113,11 +1117,11 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): if i == strip.multicam_source: sub = row.row(align=True) sub.enabled = False - sub.operator("sequencer.cut_multicam", text=f"{i:d}").camera = i + sub.operator("sequencer.split_multicam", text="%d" % i).camera = i else: sub_1 = row.row(align=True) sub_1.enabled = True - sub_1.operator("sequencer.cut_multicam", text=f"{i:d}").camera = i + sub_1.operator("sequencer.split_multicam", text="%d" % i).camera = i if strip.channel > BT_ROW and (strip_channel - 1) % BT_ROW: for i in range(strip.channel, strip_channel + ((BT_ROW + 1 - strip_channel) % BT_ROW)): @@ -1135,6 +1139,8 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): col = layout.column(align=True) if strip_type == 'SPEED': col.prop(strip, "multiply_speed") + col.prop(strip, "frame_interpolation_mode") + elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}: col.prop(strip, "use_default_fade", text="Default fade") if not strip.use_default_fade: @@ -1684,18 +1690,15 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel): layout = self.layout strip = act_strip(context) - layout.active = not strip.mute - - split = layout.split() + layout.use_property_split = True + layout.use_property_decorate = False - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") + layout.active = not strip.mute - col = split.column() - row = col.row(align=True) - row.prop(strip, "use_flip_x", text="X", toggle=True) - row.prop(strip, "use_flip_y", text="Y", toggle=True) + row = layout.row(heading="Mirror") + sub = row.row(align=True) + sub.prop(strip, "use_flip_x", text="X", toggle=True) + sub.prop(strip, "use_flip_y", text="Y", toggle=True) class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): @@ -1799,12 +1802,12 @@ class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel): ed = context.scene.sequence_editor - col = layout.column() + col = layout.column(heading="Cache", align=True) - col.prop(ed, "use_cache_raw") - col.prop(ed, "use_cache_preprocessed") - col.prop(ed, "use_cache_composite") - col.prop(ed, "use_cache_final") + col.prop(ed, "use_cache_raw", text="Raw") + col.prop(ed, "use_cache_preprocessed", text="Pre-Processed") + col.prop(ed, "use_cache_composite", text="Composite") + col.prop(ed, "use_cache_final", text="Final") col.separator() col.prop(ed, "recycle_max_cost") @@ -1868,21 +1871,19 @@ class SEQUENCER_PT_strip_proxy(SequencerButtonsPanel, Panel): flow = layout.column_flow() if ed.proxy_storage == 'PER_STRIP': - flow.prop(proxy, "use_proxy_custom_directory") - flow.prop(proxy, "use_proxy_custom_file") - + col = layout.column(heading="Custom Proxy") + col.prop(proxy, "use_proxy_custom_directory", text="Directory") if proxy.use_proxy_custom_directory and not proxy.use_proxy_custom_file: - flow.prop(proxy, "directory") + col.prop(proxy, "directory") + col.prop(proxy, "use_proxy_custom_file", text="File") if proxy.use_proxy_custom_file: - flow.prop(proxy, "filepath") + col.prop(proxy, "filepath") - box = layout.box() - row = box.row(align=True) - row.prop(strip.proxy, "build_25") - row.prop(strip.proxy, "build_75") - row = box.row(align=True) - row.prop(strip.proxy, "build_50") - row.prop(strip.proxy, "build_100") + row = layout.row(heading="Resolutions", align=True) + row.prop(strip.proxy, "build_25", toggle=True) + row.prop(strip.proxy, "build_50", toggle=True) + row.prop(strip.proxy, "build_75", toggle=True) + row.prop(strip.proxy, "build_100", toggle=True) layout.use_property_split = True layout.use_property_decorate = False @@ -1923,10 +1924,10 @@ class SEQUENCER_PT_strip_cache(SequencerButtonsPanel, Panel): strip = act_strip(context) layout.active = strip.override_cache_settings - col = layout.column() - col.prop(strip, "use_cache_raw") - col.prop(strip, "use_cache_preprocessed") - col.prop(strip, "use_cache_composite") + col = layout.column(heading="Cache") + col.prop(strip, "use_cache_raw", text="Raw") + col.prop(strip, "use_cache_preprocessed", text="Pre-Processed") + col.prop(strip, "use_cache_composite", text="Composite") class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel): @@ -1972,7 +1973,9 @@ class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel): col.prop(st, "show_separate_color") col.prop(st, "proxy_render_size") - col.prop(ed, "use_prefetch") + + if ed: + col.prop(ed, "use_prefetch") class SEQUENCER_PT_frame_overlay(SequencerButtonsPanel_Output, Panel): @@ -1980,6 +1983,12 @@ class SEQUENCER_PT_frame_overlay(SequencerButtonsPanel_Output, Panel): bl_category = "View" bl_options = {'DEFAULT_CLOSED'} + @classmethod + def poll(cls, context): + if not context.scene.sequence_editor: + return False + return SequencerButtonsPanel_Output.poll(context) + def draw_header(self, context): scene = context.scene ed = scene.sequence_editor @@ -2084,10 +2093,12 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel): box = layout.box() row = box.row() + row.use_property_decorate = False row.prop(mod, "show_expanded", text="", emboss=False) row.prop(mod, "name", text="") row.prop(mod, "mute", text="") + row.use_property_decorate = True sub = row.row(align=True) props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_UP') @@ -2159,6 +2170,33 @@ class SEQUENCER_PT_annotation(AnnotationDataPanel, SequencerButtonsPanel_Output, # But, it should only show up when there are images in the preview region +class SEQUENCER_PT_annotation_onion(AnnotationOnionSkin, SequencerButtonsPanel_Output, Panel): + bl_space_type = 'SEQUENCE_EDITOR' + bl_region_type = 'UI' + bl_category = "View" + + @staticmethod + def has_preview(context): + st = context.space_data + return st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'} + + @classmethod + def poll(cls, context): + if context.annotation_data_owner is None: + return False + elif type(context.annotation_data_owner) is bpy.types.Object: + return False + else: + gpl = context.active_annotation_layer + if gpl is None: + return False + + return cls.has_preview(context) + + # NOTE: this is just a wrapper around the generic GP Panel + # But, it should only show up when there are images in the preview region + + class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} _context_path = "scene.sequence_editor.active_strip" @@ -2232,6 +2270,7 @@ classes = ( SEQUENCER_PT_view_safe_areas_center_cut, SEQUENCER_PT_annotation, + SEQUENCER_PT_annotation_onion, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index b7c5dcd5437..f6f22ad464f 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -129,18 +129,21 @@ class TEXT_PT_properties(Panel): layout.use_property_decorate = False st = context.space_data - flow = layout.column_flow() if not st.text: - flow.active = False - row = flow.row(align=True) + layout.active = False + st = context.space_data - row.prop(st, "show_margin", text="Margin") - rowsub = row.row() - rowsub.active = st.show_margin - rowsub.prop(st, "margin_column", text="") - flow.prop(st, "font_size") - flow.prop(st, "tab_width") + col = layout.column(align=False, heading="Margin") + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(st, "show_margin", text="") + sub = sub.row(align=True) + sub.active = st.show_margin + sub.prop(st, "margin_column", text="") + + layout.prop(st, "font_size") + layout.prop(st, "tab_width") text = st.text if text: diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index 629958a783e..257e0c26a5d 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -142,6 +142,7 @@ class TIME_MT_view(Menu): layout.separator() layout.prop(scene, "show_keys_from_selected_only") + layout.prop(st.dopesheet, "show_only_errors") layout.separator() diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 4dc724299f0..e0651dcac2b 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -68,8 +68,8 @@ ToolDef = namedtuple( "idname", # The name to display in the interface. "label", - # Description (for tooltip), when not set, use the description of 'operator', - # may be a string or a 'function(context, item, keymap) -> string'. + # Description (for tool-tip), when not set, use the description of 'operator', + # may be a string or a 'function(context, item, key-map) -> string'. "description", # The name of the icon to use (found in ``release/datafiles/icons``) or None for no icon. "icon", @@ -77,13 +77,34 @@ ToolDef = namedtuple( "cursor", # An optional gizmo group to activate when the tool is set or None for no gizmo. "widget", - # Optional keymap for tool, either: - # - A function that populates a keymaps passed in as an argument. + # Optional key-map for tool, possible values are: + # + # - ``None`` when the tool doesn't have a key-map. + # Also the default value when no key-map value is defined. + # + # - A string literal for the key-map name, the key-map items are located in the default key-map. + # + # - ``()`` an empty tuple for a default name. + # This is convenience functionality for generating a key-map name. + # So if a tool name is "Bone Size", in "Edit Armature" mode for the "3D View", + # All of these values are combined into an id, e.g: + # "3D View Tool: Edit Armature, Bone Envelope" + # + # Typically searching for a string ending with the tool name + # in the default key-map will lead you to the key-map for a tool. + # + # - A function that populates a key-maps passed in as an argument. + # # - A tuple filled with triple's of: # ``(operator_id, operator_properties, keymap_item_args)``. # + # Use this to define the key-map in-line. + # + # Note that this isn't used for Blender's built in tools which use the built-in key-map. + # Keep this functionality since it's likely useful for add-on key-maps. + # # Warning: currently 'from_dict' this is a list of one item, - # so internally we can swap the keymap function for the keymap it's self. + # so internally we can swap the key-map function for the key-map it's self. # This isn't very nice and may change, tool definitions shouldn't care about this. "keymap", # Optional data-block associated with this tool. @@ -216,29 +237,52 @@ class ToolSelectPanelHelper: else: return 0 + # tool flattening + # + # usually 'tools' is already expanded into ToolDef + # but when registering a tool, this can still be a function + # (_tools_flatten is usually called with cls.tools_from_context(context) + # [that already yields from the function]) + # so if item is still a function (e.g._defs_XXX.generate_from_brushes) + # seems like we cannot expand here (have no context yet) + # if we yield None here, this will risk running into duplicate tool bl_idname [in register_tool()] + # but still better than erroring out @staticmethod def _tools_flatten(tools): - for item in tools: - if type(item) is tuple: - yield from item - else: - # May be None. - yield item + for item_parent in tools: + if item_parent is None: + yield None + for item in item_parent if (type(item_parent) is tuple) else (item_parent,): + if item is None or _item_is_fn(item): + yield None + else: + yield item @staticmethod def _tools_flatten_with_tool_index(tools): - for item in tools: - if type(item) is tuple: - i = 0 - for sub_item in item: - if sub_item is None: - yield None, -1 - else: - yield sub_item, i - i += 1 - else: - # May be None. - yield item, -1 + for item_parent in tools: + if item_parent is None: + yield None, -1 + i = 0 + for item in item_parent if (type(item_parent) is tuple) else (item_parent,): + if item is None or _item_is_fn(item): + yield None, -1 + else: + yield item, i + i += 1 + + # Special internal function, gives use items that contain keymaps. + @staticmethod + def _tools_flatten_with_keymap(tools): + for item_parent in tools: + if item_parent is None: + continue + for item in item_parent if (type(item_parent) is tuple) else (item_parent,): + # skip None or generator function + if item is None or _item_is_fn(item): + continue + if item.keymap is not None: + yield item @classmethod def _tool_get_active(cls, context, space_type, mode, with_icon=False): @@ -405,32 +449,24 @@ class ToolSelectPanelHelper: return context.button_operator.name @classmethod - def _km_action_simple(cls, kc, context_descr, label, keymap_fn): + def _km_action_simple(cls, kc_default, kc, context_descr, label, keymap_fn): km_idname = f"{cls.keymap_prefix:s} {context_descr:s}, {label:s}" km = kc.keymaps.get(km_idname) + km_kwargs = dict(space_type=cls.bl_space_type, region_type='WINDOW', tool=True) if km is None: - km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW', tool=True) + km = kc.keymaps.new(km_idname, **km_kwargs) keymap_fn[0](km) keymap_fn[0] = km.name - # Special internal function, gives use items that contain keymaps. - @staticmethod - def _tools_flatten_with_keymap(tools): - for item_parent in tools: - if item_parent is None: - continue - for item in item_parent if (type(item_parent) is tuple) else (item_parent,): - # skip None or generator function - if item is None or _item_is_fn(item): - continue - if item.keymap is not None: - yield item + # Ensure we have a default key map, so the add-ons keymap is properly overlayed. + if kc_default is not kc: + kc_default.keymaps.new(km_idname, **km_kwargs) @classmethod def register(cls): wm = bpy.context.window_manager # Write into defaults, users may modify in preferences. - kc = wm.keyconfigs.default + kc_default = wm.keyconfigs.default # Track which tool-group was last used for non-active groups. # Blender stores the active tool-group index. @@ -439,7 +475,7 @@ class ToolSelectPanelHelper: cls._tool_group_active = {} # ignore in background mode - if kc is None: + if kc_default is None: return for context_mode, tools in cls.tools_all(): @@ -451,7 +487,7 @@ class ToolSelectPanelHelper: for item in cls._tools_flatten_with_keymap(tools): keymap_data = item.keymap if callable(keymap_data[0]): - cls._km_action_simple(kc, context_descr, item.label, keymap_data) + cls._km_action_simple(kc_default, kc_default, context_descr, item.label, keymap_data) @classmethod def keymap_ui_hierarchy(cls, context_mode): diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index c1ad196b555..e64a7c9731b 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -18,6 +18,9 @@ # <pep8 compliant> +# For documentation on tool definitions: see "bl_ui.space_toolsystem_common.ToolDef" +# where there are comments for each field and their use. + # For now group all tools together # we may want to move these into per space-type files. # @@ -125,7 +128,7 @@ class _defs_view3d_generic: "\u2022 Drag ruler segment to measure an angle.\n" "\u2022 {} to remove the active ruler.\n" "\u2022 Ctrl while dragging to snap.\n" - "\u2022 Shift while dragging to measure surface thickness." + "\u2022 Shift while dragging to measure surface thickness" ).format( kmi_to_string_or_none(kmi_add), kmi_to_string_or_none(kmi_remove), @@ -144,10 +147,8 @@ class _defs_view3d_generic: class _defs_annotate: def draw_settings_common(context, layout, tool): - if type(context.gpencil_data_owner) is bpy.types.Object: - gpd = context.scene.grease_pencil - else: - gpd = context.gpencil_data + gpd = context.annotation_data + region_type = context.region.type if gpd is not None: if gpd.layers.active_note is not None: @@ -158,20 +159,27 @@ class _defs_annotate: else: text = "" - gpl = context.active_gpencil_layer + gpl = context.active_annotation_layer if gpl is not None: layout.label(text="Annotation:") - sub = layout.row(align=True) - sub.ui_units_x = 8 - - sub.prop(gpl, "color", text="") - sub.popover( - panel="TOPBAR_PT_annotation_layers", - text=text, - ) + if context.space_data.type == 'VIEW_3D': + if region_type == 'TOOL_HEADER': + sub = layout.split(align=True, factor=0.5) + sub.ui_units_x = 6.5 + sub.prop(gpl, "color", text="") + else: + sub = layout.row(align=True) + sub.prop(gpl, "color", text="") + sub.popover( + panel="TOPBAR_PT_annotation_layers", + text=text, + ) + else: + layout.prop(gpl, "color", text="") - tool_settings = context.tool_settings space_type = tool.space_type + tool_settings = context.tool_settings + if space_type == 'VIEW_3D': layout.separator() @@ -182,6 +190,29 @@ class _defs_annotate: elif tool_settings.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}: row.prop(tool_settings, "use_gpencil_stroke_endpoints") + if tool.idname == "builtin.annotate_line": + layout.separator() + + props = tool.operator_properties("gpencil.annotate") + if region_type == 'TOOL_HEADER': + row = layout.row() + row.ui_units_x = 15 + row.prop(props, "arrowstyle_start", text="Start") + row.separator() + row.prop(props, "arrowstyle_end", text="End") + else: + col = layout.row().column(align=True) + col.prop(props, "arrowstyle_start", text="Style Start") + col.prop(props, "arrowstyle_end", text="End") + elif tool.idname == "builtin.annotate" and region_type != 'TOOL_HEADER': + layout.separator() + props = tool.operator_properties("gpencil.annotate") + layout.prop(props, "use_stabilizer", text="Stabilize Stroke") + col = layout.column(align=False) + col.active = props.use_stabilizer + col.prop(props, "stabilizer_radius", text="Radius", slider=True) + col.prop(props, "stabilizer_factor", text="Factor", slider=True) + @ToolDef.from_fn.with_args(draw_settings=draw_settings_common) def scribble(*, draw_settings): return dict( @@ -460,6 +491,7 @@ class _defs_edit_armature: return dict( idname="builtin.extrude_to_cursor", label="Extrude to Cursor", + cursor='CROSSHAIR', icon="ops.armature.extrude_cursor", widget=None, keymap=(), @@ -611,15 +643,6 @@ class _defs_edit_mesh: region_type = context.region.type if not extra: - if props.offset_type == 'PERCENT': - layout.prop(props, "offset_pct") - else: - offset_text = "Width" - if props.offset_type == 'DEPTH': - offset_text = "Depth" - elif props.offset_type == 'OFFSET': - offset_text = "Offset" - layout.prop(props, "offset", text=offset_text) if region_type == 'TOOL_HEADER': layout.prop(props, "offset_type", text="") else: @@ -637,9 +660,10 @@ class _defs_edit_mesh: layout.prop(props, "vertex_only") layout.prop(props, "clamp_overlap") layout.prop(props, "loop_slide") - layout.prop(props, "mark_seam") - layout.prop(props, "mark_sharp") layout.prop(props, "harden_normals") + col = layout.column(heading="Mark") + col.prop(props, "mark_seam", text="Seam") + col.prop(props, "mark_sharp", text="Sharp") layout.prop(props, "material") @@ -680,6 +704,19 @@ class _defs_edit_mesh: ) @ToolDef.from_fn + def extrude_dissolve_and_intersect(): + return dict( + idname="builtin.extrude_dissolve_and_intersect", + label="Extrude Dissolve and Intersect", + description=( + "Extrude, dissolves edges whose faces form a flat surface and intersect new edges" + ), + icon="none", + widget="VIEW3D_GGT_tool_generic_handle_normal", + keymap=(), + ) + + @ToolDef.from_fn def extrude_normals(): def draw_settings(_context, layout, tool): props = tool.operator_properties("mesh.extrude_region_shrink_fatten") @@ -714,6 +751,7 @@ class _defs_edit_mesh: return dict( idname="builtin.extrude_to_cursor", label="Extrude to Cursor", + cursor='CROSSHAIR', icon="ops.mesh.dupli_extrude_cursor", widget=None, keymap=(), @@ -853,23 +891,61 @@ class _defs_edit_curve: @ToolDef.from_fn def draw(): - def draw_settings(context, layout, _tool): + def draw_settings(context, layout, tool, *, extra=False): # Tool settings initialize operator options. tool_settings = context.tool_settings cps = tool_settings.curve_paint_settings + region_type = context.region.type - col = layout.column() + if region_type == 'TOOL_HEADER': + if not extra: + layout.prop(cps, "curve_type", text="") + layout.prop(cps, "depth_mode", expand=True) + layout.popover("TOPBAR_PT_tool_settings_extra", text="...") + return - col.prop(cps, "curve_type") + layout.use_property_split = True + layout.use_property_decorate = False + if region_type != 'TOOL_HEADER': + layout.prop(cps, "curve_type") + layout.separator() if cps.curve_type == 'BEZIER': - col.prop(cps, "error_threshold") - col.prop(cps, "fit_method") - col.prop(cps, "use_corners_detect") + layout.prop(cps, "fit_method") + layout.prop(cps, "error_threshold") + if region_type != 'TOOL_HEADER': + row = layout.row(heading="Detect Corners", align=True) + else: + row = layout.row(heading="Corners", align=True) + row.prop(cps, "use_corners_detect", text="") + sub = row.row(align=True) + sub.active = cps.use_corners_detect + sub.prop(cps, "corner_angle", text="") + layout.separator() + + + col = layout.column(align=True) + col.prop(cps, "radius_taper_start", text="Taper Start", slider=True) + col.prop(cps, "radius_taper_end", text="End", slider=True) + col = layout.column(align=True) + col.prop(cps, "radius_min", text="Radius Min") + col.prop(cps, "radius_max", text="Max") + col.prop(cps, "use_pressure_radius") + + layout.separator() + + if region_type != 'TOOL_HEADER': + row = layout.row() + row.prop(cps, "depth_mode", expand=True) + if cps.depth_mode == 'SURFACE': + col = layout.column() + col.prop(cps, "surface_offset") + col.prop(cps, "use_offset_absolute") + col.prop(cps, "use_stroke_endpoints") + if cps.use_stroke_endpoints: + colsub = layout.column(align=True) + colsub.prop(cps, "surface_plane") - col = layout.row() - col.active = cps.use_corners_detect - col.prop(cps, "corner_angle") return dict( idname="builtin.draw", @@ -896,7 +972,8 @@ class _defs_edit_curve: def extrude_cursor(): return dict( idname="builtin.extrude_cursor", - label="Extrude Cursor", + label="Extrude to Cursor", + cursor='CROSSHAIR', icon="ops.curve.extrude_cursor", widget=None, keymap=(), @@ -1037,6 +1114,12 @@ class _defs_sculpt: layout.prop(props, "type", expand=False) layout.prop(props, "strength") layout.prop(props, "deform_axis") + layout.prop(props, "use_face_sets") + if (props.type == "SURFACE_SMOOTH"): + layout.prop(props, "surface_smooth_shape_preservation", expand=False) + layout.prop(props, "surface_smooth_current_vertex", expand=False) + if (props.type == "SHARPEN"): + layout.prop(props, "sharpen_smooth_ratio", expand=False) return dict( idname="builtin.mesh_filter", @@ -1137,8 +1220,25 @@ class _defs_weight_paint: def draw_settings(context, layout, tool): brush = context.tool_settings.weight_paint.brush if brush is not None: - layout.prop(brush, "weight", slider=True) - layout.prop(brush, "strength", slider=True) + from bl_ui.properties_paint_common import UnifiedPaintPanel + UnifiedPaintPanel.prop_unified( + layout, + context, + brush, + "weight", + unified_name="use_unified_weight", + slider=True, + header=True + ) + UnifiedPaintPanel.prop_unified( + layout, + context, + brush, + "strength", + unified_name="use_unified_strength", + header=True + ) + props = tool.operator_properties("paint.weight_gradient") layout.prop(props, "type", expand=True) @@ -1444,6 +1544,11 @@ class _defs_gpencil_paint: @ToolDef.from_fn def eyedropper(): + def draw_settings(context, layout, tool): + props = tool.operator_properties("ui.eyedropper_gpencil_color") + row = layout.row() + row.use_property_split = False + row.prop(props, "mode", expand=True) return dict( idname="builtin.eyedropper", label="Eyedropper", @@ -1451,10 +1556,22 @@ class _defs_gpencil_paint: cursor='EYEDROPPER', widget=None, keymap=(), + draw_settings=draw_settings, ) class _defs_gpencil_edit: + def is_segment(context): + ts = context.scene.tool_settings + if context.mode == 'EDIT_GPENCIL': + return ts.gpencil_selectmode_edit == 'SEGMENT' + elif context.mode == 'SCULPT_GPENCIL': + return ts.use_gpencil_select_mask_segment + elif context.mode == 'VERTEX_GPENCIL': + return ts.use_gpencil_vertex_select_mask_segment + else: + return False + @ToolDef.from_fn def bend(): return dict( @@ -1468,7 +1585,8 @@ class _defs_gpencil_edit: @ToolDef.from_fn def select(): def draw_settings(context, layout, _tool): - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + if _defs_gpencil_edit.is_segment(context): + layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") return dict( idname="builtin.select", label="Tweak", @@ -1485,7 +1603,8 @@ class _defs_gpencil_edit: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + if _defs_gpencil_edit.is_segment(context): + layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") return dict( idname="builtin.select_box", label="Select Box", @@ -1502,7 +1621,8 @@ class _defs_gpencil_edit: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + if _defs_gpencil_edit.is_segment(context): + layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") return dict( idname="builtin.select_lasso", label="Select Lasso", @@ -1520,7 +1640,8 @@ class _defs_gpencil_edit: row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) layout.prop(props, "radius") - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + if _defs_gpencil_edit.is_segment(context): + layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") def draw_cursor(_context, tool, xy): from gpu_extras.presets import draw_circle_2d @@ -1583,6 +1704,23 @@ class _defs_gpencil_edit: draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings, ) + @ToolDef.from_fn + def transform_fill(): + def draw_settings(context, layout, tool): + props = tool.operator_properties("gpencil.transform_fill") + row = layout.row() + row.use_property_split = False + row.prop(props, "mode", expand=True) + + return dict( + idname="builtin.transform_fill", + label="Transform Fill", + icon="ops.gpencil.transform_fill", + cursor='DEFAULT', + widget=None, + keymap=(), + draw_settings=draw_settings, + ) class _defs_gpencil_sculpt: @@ -1602,11 +1740,10 @@ class _defs_gpencil_sculpt: context, idname_prefix="builtin_brush.", icon_prefix="ops.gpencil.sculpt_", - type=bpy.types.GPencilSculptSettings, - attr="sculpt_tool", + type=bpy.types.Brush, + attr="gpencil_sculpt_tool", tooldef_keywords=dict( operator="gpencil.sculpt_paint", - keymap="3D View Tool: Sculpt Gpencil, Paint", ), ) @@ -1619,11 +1756,37 @@ class _defs_gpencil_weight: context, idname_prefix="builtin_brush.", icon_prefix="ops.gpencil.sculpt_", - type=bpy.types.GPencilSculptSettings, - attr="weight_tool", + type=bpy.types.Brush, + attr="gpencil_weight_tool", tooldef_keywords=dict( - operator="gpencil.sculpt_paint", - keymap="3D View Tool: Sculpt Gpencil, Paint", + operator="gpencil.weight_paint", + ), + ) + + +class _defs_gpencil_vertex: + + @staticmethod + def poll_select_mask(context): + if context is None: + return True + ob = context.active_object + ts = context.scene.tool_settings + return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_vertex_select_mask_point or + ts.use_gpencil_vertex_select_mask_stroke or + ts.use_gpencil_vertex_select_mask_segment) + + @staticmethod + def generate_from_brushes(context): + return generate_from_enum_ex( + context, + idname_prefix="builtin_brush.", + icon_prefix="brush.paint_vertex.", + type=bpy.types.Brush, + attr="gpencil_vertex_tool", + cursor='DOT', + tooldef_keywords=dict( + operator="gpencil.vertex_paint", ), ) @@ -1710,24 +1873,42 @@ class _defs_node_edit: keymap="Node Tool: Links Cut", ) + class _defs_sequencer_generic: @ToolDef.from_fn - def cut(): + def blade(): def draw_settings(_context, layout, tool): - props = tool.operator_properties("sequencer.cut") + props = tool.operator_properties("sequencer.split") row = layout.row() row.use_property_split = False row.prop(props, "type", expand=True) return dict( - idname="builtin.cut", - label="Cut", - icon="ops.mesh.knife_tool", + idname="builtin.blade", + label="Blade", + icon="ops.sequencer.blade", + cursor='CROSSHAIR', widget=None, - keymap="Sequencer Tool: Cut", + keymap="Sequencer Tool: Blade", + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def sample(): + def draw_settings(_context, layout, tool): + props = tool.operator_properties("sequencer.sample") + return dict( + idname="builtin.sample", + label="Sample", + description=( + "Sample pixel values under the cursor" + ), + icon="ops.paint.weight_sample", # XXX, needs own icon. + keymap="Sequencer Tool: Sample", draw_settings=draw_settings, ) + class _defs_sequencer_select: @ToolDef.from_fn def select(): @@ -1839,6 +2020,8 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): ], 'PAINT': [ _defs_texture_paint.generate_from_brushes, + None, + *_tools_annotate, ], } @@ -2015,6 +2198,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, ( _defs_edit_mesh.extrude, + _defs_edit_mesh.extrude_dissolve_and_intersect, _defs_edit_mesh.extrude_normals, _defs_edit_mesh.extrude_individual, _defs_edit_mesh.extrude_cursor, @@ -2188,6 +2372,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_gpencil_edit.tosphere, ), None, + _defs_gpencil_edit.transform_fill, + None, *_tools_annotate, ], 'SCULPT_GPENCIL': [ @@ -2205,6 +2391,17 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, *_tools_annotate, ], + 'VERTEX_GPENCIL': [ + _defs_gpencil_vertex.generate_from_brushes, + None, + *_tools_annotate, + None, + lambda context: ( + VIEW3D_PT_tools_active._tools_gpencil_select + if _defs_gpencil_vertex.poll_select_mask(context) + else () + ), + ], } class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): bl_space_type = 'SEQUENCE_EDITOR' @@ -2253,19 +2450,22 @@ class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): None: [ ], 'PREVIEW': [ + _defs_sequencer_generic.sample, *_tools_annotate, ], 'SEQUENCER': [ *_tools_select, - _defs_sequencer_generic.cut, + _defs_sequencer_generic.blade, ], 'SEQUENCER_PREVIEW': [ + _defs_sequencer_generic.sample, *_tools_select, *_tools_annotate, - _defs_sequencer_generic.cut, + _defs_sequencer_generic.blade, ], } + classes = ( IMAGE_PT_tools_active, NODE_PT_tools_active, diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index fd46bd53cd2..9aedd7ef0b3 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -165,11 +165,11 @@ class TOPBAR_PT_gpencil_layers(Panel): srow = col.row(align=True) srow.prop(gpl, "opacity", text="Opacity", slider=True) - srow.prop(gpl, "mask_layer", text="", - icon='MOD_MASK' if gpl.mask_layer else 'LAYER_ACTIVE') + srow.prop(gpl, "use_mask_layer", text="", + icon='MOD_MASK' if gpl.use_mask_layer else 'LAYER_ACTIVE') srow = col.row(align=True) - srow.prop(gpl, "use_solo_mode", text="Show Only On Keyframed") + srow.prop(gpl, "use_lights") col = row.column() @@ -207,7 +207,8 @@ class TOPBAR_MT_editor_menus(Menu): def draw(self, context): layout = self.layout - if context.area.show_menus: + # Allow calling this menu directly (this might not be a header area). + if getattr(context.area, "show_menus", False): layout.menu("TOPBAR_MT_app", text="", icon='BLENDER') else: layout.menu("TOPBAR_MT_app", text="Blender") @@ -228,19 +229,16 @@ class TOPBAR_MT_app(Menu): layout = self.layout layout.operator("wm.splash") + layout.operator("wm.splash_about") layout.separator() - layout.menu("TOPBAR_MT_app_support") - - layout.separator() - - layout.menu("TOPBAR_MT_app_about") + layout.operator("preferences.app_template_install", + text="Install Application Template...") layout.separator() - layout.operator("preferences.app_template_install", - text="Install Application Template...") + layout.menu("TOPBAR_MT_app_system") class TOPBAR_MT_file_cleanup(Menu): @@ -402,43 +400,24 @@ class TOPBAR_MT_file_defaults(Menu): props.app_template = app_template -class TOPBAR_MT_app_about(Menu): - bl_label = "About" +# Include technical operators here which would otherwise have no way for users to access. +class TOPBAR_MT_app_system(Menu): + bl_label = "System" def draw(self, _context): layout = self.layout - layout.operator("wm.url_open_preset", text="Release Notes", - icon='URL').type = 'RELEASE_NOTES' + layout.operator("script.reload") layout.separator() - layout.operator("wm.url_open_preset", - text="Blender Website", icon='URL').type = 'BLENDER' - layout.operator("wm.url_open_preset", text="Credits", - icon='URL').type = 'CREDITS' + layout.operator("wm.memory_statistics") + layout.operator("wm.debug_menu") + layout.operator_menu_enum("wm.redraw_timer", "type") layout.separator() - layout.operator( - "wm.url_open", text="License", icon='URL', - ).url = "https://www.blender.org/about/license/" - - -class TOPBAR_MT_app_support(Menu): - bl_label = "Support Blender" - - def draw(self, _context): - layout = self.layout - - layout.operator("wm.url_open_preset", - text="Development Fund", icon='FUND').type = 'FUND' - - layout.separator() - - layout.operator( - "wm.url_open", text="Blender Store", icon='URL', - ).url = "https://store.blender.org" + layout.operator("screen.spacedata_cleanup") class TOPBAR_MT_templates_more(Menu): @@ -452,6 +431,7 @@ class TOPBAR_MT_templates_more(Menu): class TOPBAR_MT_file_import(Menu): bl_idname = "TOPBAR_MT_file_import" bl_label = "Import" + bl_owner_use_filter = False def draw(self, _context): if bpy.app.build_options.collada: @@ -464,6 +444,7 @@ class TOPBAR_MT_file_import(Menu): class TOPBAR_MT_file_export(Menu): bl_idname = "TOPBAR_MT_file_export" bl_label = "Export" + bl_owner_use_filter = False def draw(self, context): if bpy.app.build_options.collada: @@ -553,6 +534,8 @@ class TOPBAR_MT_edit(Menu): def draw(self, context): layout = self.layout + show_developer = context.preferences.view.show_developer_ui + layout.operator("ed.undo") layout.operator("ed.redo") @@ -571,8 +554,9 @@ class TOPBAR_MT_edit(Menu): layout.separator() - layout.operator("wm.search_menu", - text="Operator Search...", icon='VIEWZOOM') + layout.operator("wm.search_menu", text="Menu Search...", icon='VIEWZOOM') + if show_developer: + layout.operator("wm.search_operator", text="Operator Search...", icon='VIEWZOOM') layout.separator() @@ -824,8 +808,7 @@ classes = ( TOPBAR_MT_workspace_menu, TOPBAR_MT_editor_menus, TOPBAR_MT_app, - TOPBAR_MT_app_about, - TOPBAR_MT_app_support, + TOPBAR_MT_app_system, TOPBAR_MT_file, TOPBAR_MT_file_new, TOPBAR_MT_file_recover, diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index ad5e7b5442c..153533dbde6 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -37,18 +37,13 @@ class USERPREF_HT_header(Header): def draw_buttons(layout, context): prefs = context.preferences - layout.scale_x = 1.0 - layout.scale_y = 1.0 layout.operator_context = 'EXEC_AREA' - row = layout.row() - row.menu("USERPREF_MT_save_load", text="", icon='COLLAPSEMENU') - if prefs.use_preferences_save and (not bpy.app.use_userpref_skip_save_on_exit): pass else: # Show '*' to let users know the preferences have been modified. - row.operator( + layout.operator( "wm.save_userpref", text="Save Preferences{:s}".format(" *" if prefs.is_dirty else ""), ) @@ -59,7 +54,10 @@ class USERPREF_HT_header(Header): layout.template_header() + USERPREF_MT_editor_menus.draw_collapsible(context, layout) + layout.separator_spacer() + self.draw_buttons(layout, context) @@ -84,6 +82,25 @@ class USERPREF_PT_navigation_bar(Panel): col.prop(prefs, "active_section", expand=True) +class USERPREF_MT_editor_menus(Menu): + bl_idname = "USERPREF_MT_editor_menus" + bl_label = "" + + def draw(self, _context): + layout = self.layout + layout.menu("USERPREF_MT_view") + layout.menu("USERPREF_MT_save_load", text="Preferences") + + +class USERPREF_MT_view(Menu): + bl_label = "View" + + def draw(self, context): + layout = self.layout + + layout.menu("INFO_MT_area") + + class USERPREF_MT_save_load(Menu): bl_label = "Save & Load" @@ -125,11 +142,10 @@ class USERPREF_PT_save_preferences(Panel): return False def draw(self, context): - layout = self.layout + layout = self.layout.row() layout.operator_context = 'EXEC_AREA' - layout.scale_x = 1.3 - layout.scale_y = 1.3 + layout.menu("USERPREF_MT_save_load", text="", icon='COLLAPSEMENU') USERPREF_HT_header.draw_buttons(layout, context) @@ -184,20 +200,16 @@ class USERPREF_PT_interface_display(InterfacePanel, CenterAlignMixIn, Panel): prefs = context.preferences view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(view, "ui_scale", text="Resolution Scale") - flow.prop(view, "ui_line_width", text="Line Width") - - layout.separator() + col = layout.column() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col.prop(view, "ui_scale", text="Resolution Scale") + col.prop(view, "ui_line_width", text="Line Width") + col.prop(view, "show_splash", text="Splash Screen") + col.prop(view, "show_developer_ui") - flow.prop(view, "show_splash", text="Splash Screen") - flow.prop(view, "show_tooltips") - flow.prop(view, "show_tooltips_python") - flow.prop(view, "show_developer_ui") - flow.prop(view, "show_large_cursors") + col = layout.column(heading="Tooltips") + col.prop(view, "show_tooltips") + col.prop(view, "show_tooltips_python") class USERPREF_PT_interface_text(InterfacePanel, CenterAlignMixIn, Panel): @@ -227,25 +239,17 @@ class USERPREF_PT_interface_translation(InterfacePanel, CenterAlignMixIn, Panel) def poll(cls, context): return bpy.app.build_options.international - def draw_header(self, context): - prefs = context.preferences - view = prefs.view - - self.layout.prop(view, "use_international_fonts", text="") - def draw_centered(self, context, layout): prefs = context.preferences view = prefs.view - layout.active = view.use_international_fonts - layout.prop(view, "language") - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(view, "use_translate_tooltips", text="Tooltips") - flow.prop(view, "use_translate_interface", text="Interface") - flow.prop(view, "use_translate_new_dataname", text="New Data") + col = layout.column(heading="Affect") + col.active = (bpy.app.translations.locale != 'en_US') + col.prop(view, "use_translate_tooltips", text="Tooltips") + col.prop(view, "use_translate_interface", text="Interface") + col.prop(view, "use_translate_new_dataname", text="New Data") class USERPREF_PT_interface_editors(InterfacePanel, CenterAlignMixIn, Panel): @@ -256,14 +260,13 @@ class USERPREF_PT_interface_editors(InterfacePanel, CenterAlignMixIn, Panel): view = prefs.view system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(system, "use_region_overlap") - flow.prop(view, "show_layout_ui", text="Corner Splitting") - flow.prop(view, "show_navigate_ui") - flow.prop(view, "color_picker_type") - flow.row().prop(view, "header_align") - flow.prop(view, "factor_display_type") + col = layout.column() + col.prop(system, "use_region_overlap") + col.prop(view, "show_layout_ui", text="Corner Splitting") + col.prop(view, "show_navigate_ui") + col.prop(view, "color_picker_type") + col.row().prop(view, "header_align") + col.prop(view, "factor_display_type") class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn, Panel): @@ -275,10 +278,9 @@ class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn, prefs = context.preferences view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(view, "render_display_type", text="Render in") - flow.prop(view, "filebrowser_display_type", text="File Browser") + col = layout.column() + col.prop(view, "render_display_type", text="Render in") + col.prop(view, "filebrowser_display_type", text="File Browser") class USERPREF_PT_interface_menus(InterfacePanel, Panel): @@ -358,6 +360,7 @@ class USERPREF_PT_edit_objects_new(EditingPanel, CenterAlignMixIn, Panel): flow.prop(edit, "material_link", text="Link Materials to") flow.prop(edit, "object_align", text="Align to") flow.prop(edit, "use_enter_edit_mode", text="Enter Edit Mode") + flow.prop(edit, "collection_instance_empty_size", text="Instance Empty Size") class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Panel): @@ -368,6 +371,8 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa prefs = context.preferences edit = prefs.edit + layout.use_property_split = False + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) col = flow.column() @@ -375,18 +380,23 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa col.prop(edit, "use_duplicate_armature", text="Armature") col.prop(edit, "use_duplicate_curve", text="Curve") # col.prop(edit, "use_duplicate_fcurve", text="F-Curve") # Not implemented. + col.prop(edit, "use_duplicate_grease_pencil", text="Grease Pencil") + if hasattr(edit, "use_duplicate_hair"): + col.prop(edit, "use_duplicate_hair", text="Hair") col.prop(edit, "use_duplicate_light", text="Light") - col.prop(edit, "use_duplicate_lightprobe", text="Light Probe") col = flow.column() + col.prop(edit, "use_duplicate_lightprobe", text="Light Probe") col.prop(edit, "use_duplicate_material", text="Material") col.prop(edit, "use_duplicate_mesh", text="Mesh") col.prop(edit, "use_duplicate_metaball", text="Metaball") col.prop(edit, "use_duplicate_particle", text="Particle") col = flow.column() + if hasattr(edit, "use_duplicate_pointcloud"): + col.prop(edit, "use_duplicate_pointcloud", text="Point Cloud") col.prop(edit, "use_duplicate_surface", text="Surface") col.prop(edit, "use_duplicate_text", text="Text") # col.prop(edit, "use_duplicate_texture", text="Texture") # Not implemented. - col.prop(edit, "use_duplicate_grease_pencil", text="Grease Pencil") + col.prop(edit, "use_duplicate_volume", text="Volume") class USERPREF_PT_edit_cursor(EditingPanel, CenterAlignMixIn, Panel): @@ -396,10 +406,9 @@ class USERPREF_PT_edit_cursor(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "use_mouse_depth_cursor") - flow.prop(edit, "use_cursor_lock_adjust") + col = layout.column() + col.prop(edit, "use_mouse_depth_cursor") + col.prop(edit, "use_cursor_lock_adjust") class USERPREF_PT_edit_gpencil(EditingPanel, CenterAlignMixIn, Panel): @@ -410,10 +419,9 @@ class USERPREF_PT_edit_gpencil(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance") - flow.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance") + col = layout.column(heading="Distance") + col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan") + col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean") class USERPREF_PT_edit_annotations(EditingPanel, CenterAlignMixIn, Panel): @@ -423,10 +431,9 @@ class USERPREF_PT_edit_annotations(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "grease_pencil_default_color", text="Default Color") - flow.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius") + col = layout.column() + col.prop(edit, "grease_pencil_default_color", text="Default Color") + col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius") class USERPREF_PT_edit_weight_paint(EditingPanel, CenterAlignMixIn, Panel): @@ -437,6 +444,8 @@ class USERPREF_PT_edit_weight_paint(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences view = prefs.view + layout.use_property_split = False + layout.prop(view, "use_weight_color_range", text="Use Custom Colors") col = layout.column() @@ -452,10 +461,9 @@ class USERPREF_PT_edit_misc(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color") - flow.prop(edit, "node_margin", text="Node Auto-offset Margin") + col = layout.column() + col.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color") + col.prop(edit, "node_margin", text="Node Auto-offset Margin") # ----------------------------------------------------------------------------- @@ -475,20 +483,16 @@ class USERPREF_PT_animation_timeline(AnimationPanel, CenterAlignMixIn, Panel): view = prefs.view edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - flow.prop(edit, "use_negative_frames") - - layout.separator() - - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(edit, "use_negative_frames") - flow.prop(view, "view2d_grid_spacing_min", text="Minimum Grid Spacing") - flow.prop(view, "timecode_style") - flow.prop(view, "view_frame_type") + col.prop(view, "view2d_grid_spacing_min", text="Minimum Grid Spacing") + col.prop(view, "timecode_style") + col.prop(view, "view_frame_type") if view.view_frame_type == 'SECONDS': - flow.prop(view, "view_frame_seconds") + col.prop(view, "view_frame_seconds") elif view.view_frame_type == 'KEYFRAMES': - flow.prop(view, "view_frame_keyframes") + col.prop(view, "view_frame_keyframes") class USERPREF_PT_animation_keyframes(AnimationPanel, CenterAlignMixIn, Panel): @@ -498,25 +502,14 @@ class USERPREF_PT_animation_keyframes(AnimationPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "use_visual_keying") - flow.prop(edit, "use_keyframe_insert_needed", text="Only Insert Needed") - - -class USERPREF_PT_animation_autokey(AnimationPanel, CenterAlignMixIn, Panel): - bl_label = "Auto-Keyframing" - bl_parent_id = "USERPREF_PT_animation_keyframes" - - def draw_centered(self, context, layout): - prefs = context.preferences - edit = prefs.edit - - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(edit, "use_visual_keying") + col.prop(edit, "use_keyframe_insert_needed", text="Only Insert Needed") - flow.prop(edit, "use_auto_keying_warning", text="Show Warning") - flow.prop(edit, "use_keyframe_insert_available", text="Only Insert Available") - flow.prop(edit, "use_auto_keying", text="Enable in New Scenes") + col = layout.column(heading="Auto-Keyframing") + col.prop(edit, "use_auto_keying_warning", text="Show Warning") + col.prop(edit, "use_keyframe_insert_available", text="Only Insert Available") + col.prop(edit, "use_auto_keying", text="Enable in New Scenes") class USERPREF_PT_animation_fcurves(AnimationPanel, CenterAlignMixIn, Panel): @@ -546,6 +539,7 @@ class SystemPanel: class USERPREF_PT_system_sound(SystemPanel, CenterAlignMixIn, Panel): bl_label = "Sound" + bl_options = {'DEFAULT_CLOSED'} def draw_centered(self, context, layout): prefs = context.preferences @@ -591,32 +585,47 @@ class USERPREF_PT_system_memory(SystemPanel, CenterAlignMixIn, Panel): system = prefs.system edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "undo_steps", text="Undo Steps") - flow.prop(edit, "undo_memory_limit", text="Undo Memory Limit") - flow.prop(edit, "use_global_undo") + col = layout.column() + col.prop(edit, "undo_steps", text="Undo Steps") + col.prop(edit, "undo_memory_limit", text="Undo Memory Limit") + col.prop(edit, "use_global_undo") layout.separator() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(system, "scrollback", text="Console Scrollback Lines") - flow.prop(system, "memory_cache_limit", text="Sequencer Cache Limit") - flow.prop(system, "scrollback", text="Console Scrollback Lines") + layout.separator() + + col = layout.column() + col.prop(system, "texture_time_out", text="Texture Time Out") + col.prop(system, "texture_collection_rate", text="Garbage Collection Rate") layout.separator() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(system, "vbo_time_out", text="Vbo Time Out") + col.prop(system, "vbo_collection_rate", text="Garbage Collection Rate") - flow.prop(system, "texture_time_out", text="Texture Time Out") - flow.prop(system, "texture_collection_rate", text="Garbage Collection Rate") - layout.separator() +class USERPREF_PT_system_video_sequencer(SystemPanel, CenterAlignMixIn, Panel): + bl_label = "Video Sequencer" - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + def draw_centered(self, context, layout): + prefs = context.preferences + system = prefs.system + edit = prefs.edit + + layout.prop(system, "memory_cache_limit") + + layout.separator() - flow.prop(system, "vbo_time_out", text="Vbo Time Out") - flow.prop(system, "vbo_collection_rate", text="Garbage Collection Rate") + layout.prop(system, "use_sequencer_disk_cache") + col = layout.column() + col.active = system.use_sequencer_disk_cache + col.prop(system, "sequencer_disk_cache_dir", text="Directory") + col.prop(system, "sequencer_disk_cache_size_limit", text="Cache Limit") + col.prop(system, "sequencer_disk_cache_compression", text="Compression") # ----------------------------------------------------------------------------- @@ -635,23 +644,19 @@ class USERPREF_PT_viewport_display(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(view, "show_object_info", text="Object Info") - flow.prop(view, "show_view_name", text="View Name") - flow.prop(view, "show_playback_fps", text="Playback FPS") + col = layout.column(heading="Show") + col.prop(view, "show_object_info", text="Object Info") + col.prop(view, "show_view_name", text="View Name") + col.prop(view, "show_playback_fps", text="Playback FPS") layout.separator() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() + col = layout.column() col.prop(view, "gizmo_size") col.prop(view, "lookdev_sphere_size") - flow.separator() + col.separator() - col = flow.column() col.prop(view, "mini_axis_type", text="3D Viewport Axis") if view.mini_axis_type == 'MINIMAL': @@ -666,12 +671,12 @@ class USERPREF_PT_viewport_quality(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(system, "viewport_aa") - flow.prop(system, "viewport_aa") - flow.prop(system, "gpencil_multi_sample", text="Grease Pencil Multisampling") - flow.prop(system, "use_overlay_smooth_wire") - flow.prop(system, "use_edit_mode_smooth_wire") + col = layout.column(heading="Smooth Wires") + col.prop(system, "use_overlay_smooth_wire", text="Overlay") + col.prop(system, "use_edit_mode_smooth_wire", text="Edit Mode") class USERPREF_PT_viewport_textures(ViewportPanel, CenterAlignMixIn, Panel): @@ -681,12 +686,11 @@ class USERPREF_PT_viewport_textures(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(system, "gl_texture_limit", text="Limit Size") - flow.prop(system, "anisotropic_filter") - flow.prop(system, "gl_clip_alpha", slider=True) - flow.prop(system, "image_draw_method", text="Image Display Method") + col = layout.column() + col.prop(system, "gl_texture_limit", text="Limit Size") + col.prop(system, "anisotropic_filter") + col.prop(system, "gl_clip_alpha", slider=True) + col.prop(system, "image_draw_method", text="Image Display Method") class USERPREF_PT_viewport_selection(ViewportPanel, CenterAlignMixIn, Panel): @@ -697,9 +701,7 @@ class USERPREF_PT_viewport_selection(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(system, "use_select_pick_depth") + layout.prop(system, "use_select_pick_depth") # ----------------------------------------------------------------------------- @@ -861,14 +863,31 @@ class USERPREF_PT_theme_interface_styles(ThemePanel, CenterAlignMixIn, Panel): flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) flow.prop(ui, "menu_shadow_fac") + flow.prop(ui, "menu_shadow_width") flow.prop(ui, "icon_alpha") flow.prop(ui, "icon_saturation") flow.prop(ui, "editor_outline") flow.prop(ui, "widget_text_cursor") - flow.prop(ui, "menu_shadow_width") flow.prop(ui, "widget_emboss") +class USERPREF_PT_theme_interface_transparent_checker(ThemePanel, CenterAlignMixIn, Panel): + bl_label = "Transparent Checkerboard" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = "USERPREF_PT_theme_user_interface" + + def draw_centered(self, context, layout): + theme = context.preferences.themes[0] + ui = theme.user_interface + + flow = layout.grid_flow( + row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + + flow.prop(ui, "transparent_checker_primary") + flow.prop(ui, "transparent_checker_secondary") + flow.prop(ui, "transparent_checker_size") + + class USERPREF_PT_theme_interface_gizmos(ThemePanel, CenterAlignMixIn, Panel): bl_label = "Axis & Gizmo Colors" bl_options = {'DEFAULT_CLOSED'} @@ -888,6 +907,7 @@ class USERPREF_PT_theme_interface_gizmos(ThemePanel, CenterAlignMixIn, Panel): col = flow.column() col.prop(ui, "gizmo_primary") col.prop(ui, "gizmo_secondary") + col.prop(ui, "gizmo_view_align") col = flow.column() col.prop(ui, "gizmo_a") @@ -1289,37 +1309,40 @@ class USERPREF_PT_saveload_blend(SaveLoadPanel, CenterAlignMixIn, Panel): paths = prefs.filepaths view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column(heading="Save") + col.prop(view, "use_save_prompt") + col.prop(paths, "use_save_preview_images") - flow.prop(paths, "use_relative_paths") - flow.prop(paths, "use_file_compression") - flow.prop(paths, "use_load_ui") - flow.prop(paths, "use_save_preview_images") - flow.prop(paths, "use_tabs_as_spaces") - flow.prop(view, "use_save_prompt") + col = layout.column(heading="Default to") + col.prop(paths, "use_relative_paths") + col.prop(paths, "use_file_compression") + col.prop(paths, "use_load_ui") - layout.separator() - - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column(heading="Text Files") + col.prop(paths, "use_tabs_as_spaces") - flow.prop(paths, "save_version") - flow.prop(paths, "recent_files") + col = layout.column() + col.prop(paths, "save_version") + col.prop(paths, "recent_files") class USERPREF_PT_saveload_blend_autosave(SaveLoadPanel, CenterAlignMixIn, Panel): bl_label = "Auto Save" bl_parent_id = "USERPREF_PT_saveload_blend" - def draw_centered(self, context, layout): + def draw_header(self, context): prefs = context.preferences paths = prefs.filepaths - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + self.layout.prop(paths, "use_auto_save_temporary_files", text="") - flow.prop(paths, "use_auto_save_temporary_files") - sub = flow.column() - sub.active = paths.use_auto_save_temporary_files - sub.prop(paths, "auto_save_time", text="Timer (mins)") + def draw_centered(self, context, layout): + prefs = context.preferences + paths = prefs.filepaths + + col = layout.column() + col.active = paths.use_auto_save_temporary_files + col.prop(paths, "auto_save_time", text="Timer (mins)") class USERPREF_PT_saveload_file_browser(SaveLoadPanel, CenterAlignMixIn, Panel): @@ -1329,12 +1352,13 @@ class USERPREF_PT_saveload_file_browser(SaveLoadPanel, CenterAlignMixIn, Panel): prefs = context.preferences paths = prefs.filepaths - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(paths, "use_filter_files") - flow.prop(paths, "use_filter_files") - flow.prop(paths, "show_hidden_files_datablocks") - flow.prop(paths, "hide_recent_locations") - flow.prop(paths, "hide_system_bookmarks") + col = layout.column(heading="Hide") + col.prop(paths, "show_hidden_files_datablocks", text="Dot File & Datablocks") + col.prop(paths, "hide_recent_locations", text="Recent Locations") + col.prop(paths, "hide_system_bookmarks", text="System Bookmarks") # ----------------------------------------------------------------------------- @@ -1393,10 +1417,9 @@ class USERPREF_PT_input_tablet(InputPanel, CenterAlignMixIn, Panel): layout.prop(inputs, "tablet_api") layout.separator() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(inputs, "pressure_threshold_max") - flow.prop(inputs, "pressure_softness") + col = layout.column() + col.prop(inputs, "pressure_threshold_max") + col.prop(inputs, "pressure_softness") class USERPREF_PT_input_ndof(InputPanel, CenterAlignMixIn, Panel): @@ -1443,24 +1466,27 @@ class USERPREF_PT_navigation_orbit(NavigationPanel, CenterAlignMixIn, Panel): inputs = prefs.inputs view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() - flow.row().prop(inputs, "view_rotate_method", expand=True) + col.row().prop(inputs, "view_rotate_method", expand=True) if inputs.view_rotate_method == 'TURNTABLE': - flow.prop(inputs, "view_rotate_sensitivity_turntable") + col.prop(inputs, "view_rotate_sensitivity_turntable") else: - flow.prop(inputs, "view_rotate_sensitivity_trackball") + col.prop(inputs, "view_rotate_sensitivity_trackball") + col.prop(inputs, "use_rotate_around_active") + + col.separator() - flow.prop(inputs, "use_rotate_around_active") - flow.prop(inputs, "use_auto_perspective") - flow.prop(inputs, "use_mouse_depth_navigate") if sys.platform == "darwin": - flow.prop(inputs, "use_trackpad_natural", text="Natural Trackpad Direction") + col.prop(inputs, "use_trackpad_natural", text="Natural Trackpad Direction") - flow.separator() + col = layout.column(heading="Auto") + col.prop(inputs, "use_auto_perspective", text="Perspective") + col.prop(inputs, "use_mouse_depth_navigate", text="Depth") - flow.prop(view, "smooth_view") - flow.prop(view, "rotation_angle") + col = layout.column() + col.prop(view, "smooth_view") + col.prop(view, "rotation_angle") class USERPREF_PT_navigation_zoom(NavigationPanel, CenterAlignMixIn, Panel): @@ -1470,16 +1496,20 @@ class USERPREF_PT_navigation_zoom(NavigationPanel, CenterAlignMixIn, Panel): prefs = context.preferences inputs = prefs.inputs - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() - flow.row().prop(inputs, "view_zoom_method", text="Zoom Method", expand=True) + col.row().prop(inputs, "view_zoom_method", text="Zoom Method") if inputs.view_zoom_method in {'DOLLY', 'CONTINUE'}: - flow.row().prop(inputs, "view_zoom_axis", expand=True) - flow.prop(inputs, "invert_mouse_zoom", text="Invert Mouse Zoom Direction") + col.row().prop(inputs, "view_zoom_axis") + col.prop(inputs, "use_zoom_to_mouse") + col = layout.column(heading="Invert Zoom Direction", align=True) + col.prop(inputs, "invert_mouse_zoom", text="Mouse") + col.prop(inputs, "invert_zoom_wheel", text="Wheel") + else: + col.prop(inputs, "use_zoom_to_mouse") + col.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction") - flow.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction") # sub.prop(view, "wheel_scroll_lines", text="Scroll Lines") - flow.prop(inputs, "use_zoom_to_mouse") class USERPREF_PT_navigation_fly_walk(NavigationPanel, CenterAlignMixIn, Panel): @@ -1510,15 +1540,14 @@ class USERPREF_PT_navigation_fly_walk_navigation(NavigationPanel, CenterAlignMix inputs = prefs.inputs walk = inputs.walk_navigation - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(walk, "use_mouse_reverse") - flow.prop(walk, "mouse_speed") - flow.prop(walk, "teleport_time") + col = layout.column() + col.prop(walk, "use_mouse_reverse") + col.prop(walk, "mouse_speed") + col.prop(walk, "teleport_time") - sub = flow.column(align=True) - sub.prop(walk, "walk_speed") - sub.prop(walk, "walk_speed_factor") + col = layout.column(align=True) + col.prop(walk, "walk_speed") + col.prop(walk, "walk_speed_factor") class USERPREF_PT_navigation_fly_walk_gravity(NavigationPanel, CenterAlignMixIn, Panel): @@ -1545,10 +1574,9 @@ class USERPREF_PT_navigation_fly_walk_gravity(NavigationPanel, CenterAlignMixIn, layout.active = walk.use_gravity - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(walk, "view_height") - flow.prop(walk, "jump_height") + col = layout.column() + col.prop(walk, "view_height") + col.prop(walk, "jump_height") # Special case, this is only exposed as a popover. @@ -1837,7 +1865,7 @@ class USERPREF_PT_addons(AddOnPanel, Panel): # WARNING: 2.8x exception, may be removed # use disabled state for old add-ons, chances are they are broken. if is_addon_27x: - sub.label(text="upgrade to 2.8x required") + sub.label(text="Upgrade to 2.8x required") sub.label(icon='ERROR') # Remove code above after 2.8x migration is complete. elif info["warning"]: @@ -1874,16 +1902,16 @@ class USERPREF_PT_addons(AddOnPanel, Panel): split.label(text=" " + info["warning"], icon='ERROR') user_addon = USERPREF_PT_addons.is_user_addon(mod, user_addon_paths) - tot_row = bool(info["wiki_url"]) + bool(user_addon) + tot_row = bool(info["doc_url"]) + bool(user_addon) if tot_row: split = colsub.row().split(factor=0.15) split.label(text="Internet:") sub = split.row() - if info["wiki_url"]: + if info["doc_url"]: sub.operator( "wm.url_open", text="Documentation", icon='HELP', - ).url = info["wiki_url"] + ).url = info["doc_url"] # Only add "Report a Bug" button if tracker_url is set # or the add-on is bundled (use official tracker then). if info.get("tracker_url"): @@ -2088,6 +2116,21 @@ class ExperimentalPanel: url_prefix = "https://developer.blender.org/" + def _draw_items(self, context, items): + prefs = context.preferences + experimental = prefs.experimental + + layout = self.layout + layout.use_property_split = False + layout.use_property_decorate = False + + for prop_keywords, task in items: + split = layout.split(factor=0.66) + col = split.split() + col.prop(experimental, **prop_keywords) + col = split.split() + col.operator("wm.url_open", text=task, icon='URL').url = self.url_prefix + task + """ # Example panel, leave it here so we always have a template to follow even # after the features are gone from the experimental panel. @@ -2096,27 +2139,24 @@ class USERPREF_PT_experimental_virtual_reality(ExperimentalPanel, Panel): bl_label = "Virtual Reality" def draw(self, context): - prefs = context.preferences - experimental = prefs.experimental + self._draw_items( + context, ( + ({"property": "use_virtual_reality_scene_inspection"}, "T71347"), + ({"property": "use_virtual_reality_immersive_drawing"}, "T71348"), + ) + ) +""" - layout = self.layout - layout.use_property_split = True - layout.use_property_decorate = False - task = "T71347" - split = layout.split(factor=0.66) - col = split.split() - col.prop(experimental, "use_virtual_reality_scene_inspection", text="Scene Inspection") - col = split.split() - col.operator("wm.url_open", text=task, icon='URL').url = self.url_prefix + task - - task = "T71348" - split = layout.split(factor=0.66) - col = split.column() - col.prop(experimental, "use_virtual_reality_immersive_drawing", text="Continuous Immersive Drawing") - col = split.column() - col.operator("wm.url_open", text=task, icon='URL').url = self.url_prefix + task -""" +class USERPREF_PT_experimental_system(ExperimentalPanel, Panel): + bl_label = "System" + + def draw(self, context): + self._draw_items( + context, ( + ({"property": "use_undo_legacy"}, "T60695"), + ), + ) # ----------------------------------------------------------------------------- @@ -2130,6 +2170,8 @@ classes = ( USERPREF_HT_header, USERPREF_PT_navigation_bar, USERPREF_PT_save_preferences, + USERPREF_MT_editor_menus, + USERPREF_MT_view, USERPREF_MT_save_load, USERPREF_PT_interface_display, @@ -2157,11 +2199,11 @@ classes = ( USERPREF_PT_animation_timeline, USERPREF_PT_animation_keyframes, - USERPREF_PT_animation_autokey, USERPREF_PT_animation_fcurves, USERPREF_PT_system_cycles_devices, USERPREF_PT_system_memory, + USERPREF_PT_system_video_sequencer, USERPREF_PT_system_sound, USERPREF_MT_interface_theme_presets, @@ -2169,6 +2211,7 @@ classes = ( USERPREF_PT_theme_interface_state, USERPREF_PT_theme_interface_styles, USERPREF_PT_theme_interface_gizmos, + USERPREF_PT_theme_interface_transparent_checker, USERPREF_PT_theme_interface_icons, USERPREF_PT_theme_text_style, USERPREF_PT_theme_bone_color_sets, @@ -2206,6 +2249,8 @@ classes = ( # Popovers. USERPREF_PT_ndof_settings, + USERPREF_PT_experimental_system, + # Add dynamically generated editor theme panels last, # so they show up last in the theme section. *ThemeGenericClassGenerator.generate_panel_classes_from_theme_areas(), diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index aa8f343e1a0..61d5d79473f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -31,6 +31,7 @@ from bl_ui.properties_grease_pencil_common import ( AnnotationDataPanel, AnnotationOnionSkin, GreasePencilMaterialsPanel, + GreasePencilVertexcolorPanel, ) from bl_ui.space_toolsystem_common import ( ToolActivePanelHelper, @@ -119,21 +120,26 @@ class VIEW3D_HT_tool_header(Header): if is_valid_context: brush = context.tool_settings.gpencil_paint.brush if brush.gpencil_tool != 'ERASE': - layout.popover("VIEW3D_PT_tools_grease_pencil_brush_advanced") + if brush.gpencil_tool != 'TINT': + layout.popover("VIEW3D_PT_tools_grease_pencil_brush_advanced") - if brush.gpencil_tool != 'FILL': + if brush.gpencil_tool not in {'FILL', 'TINT'}: layout.popover("VIEW3D_PT_tools_grease_pencil_brush_stroke") - layout.popover("VIEW3D_PT_tools_grease_pencil_brushcurves") layout.popover("VIEW3D_PT_tools_grease_pencil_paint_appearance") elif tool_mode == 'SCULPT_GPENCIL': - settings = context.tool_settings.gpencil_sculpt - tool = settings.sculpt_tool - if tool in {'SMOOTH', 'RANDOMIZE', 'SMOOTH'}: - layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_options") - layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance") + if is_valid_context: + brush = context.tool_settings.gpencil_sculpt_paint.brush + tool = brush.gpencil_tool + if tool in ('SMOOTH', 'RANDOMIZE'): + layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_options") + layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance") elif tool_mode == 'WEIGHT_GPENCIL': - layout.popover("VIEW3D_PT_tools_grease_pencil_weight_appearance") + if is_valid_context: + layout.popover("VIEW3D_PT_tools_grease_pencil_weight_appearance") + elif tool_mode == 'VERTEX_GPENCIL': + if is_valid_context: + layout.popover("VIEW3D_PT_tools_grease_pencil_vertex_appearance") def draw_mode_settings(self, context): layout = self.layout @@ -386,7 +392,7 @@ class _draw_tool_settings_context_mode: }: # is_paint = False pass - elif tool.idname == "Cutter": + elif tool.idname == "builtin.cutter": row = layout.row(align=True) row.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") return False @@ -425,6 +431,15 @@ class _draw_tool_settings_context_mode: row.prop(gp_settings, "use_material_pin", text="") + if brush.gpencil_tool in {'DRAW', 'FILL'} and ma: + row.separator(factor=1.0) + subrow = row.row(align=True) + row.prop_enum(settings, "color_mode", 'MATERIAL', text="", icon='MATERIAL') + row.prop_enum(settings, "color_mode", 'VERTEXCOLOR', text="", icon='VPAINT_HLT') + sub_row = row.row(align=True) + sub_row.enabled = settings.color_mode == 'VERTEXCOLOR' + sub_row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor") + row = layout.row(align=True) tool_settings = context.scene.tool_settings settings = tool_settings.gpencil_paint @@ -433,6 +448,10 @@ class _draw_tool_settings_context_mode: if context.object and brush.gpencil_tool in {'FILL', 'DRAW'}: draw_color_selector() + if context.object and brush.gpencil_tool == 'TINT': + row.separator(factor=0.4) + row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor") + from bl_ui.properties_paint_common import ( brush_basic_gpencil_paint_settings, ) @@ -444,9 +463,8 @@ class _draw_tool_settings_context_mode: def SCULPT_GPENCIL(context, layout, tool): if (tool is None) or (not tool.has_datablock): return False - tool_settings = context.tool_settings - settings = tool_settings.gpencil_sculpt - brush = settings.brush + paint = context.tool_settings.gpencil_sculpt_paint + brush = paint.brush from bl_ui.properties_paint_common import ( brush_basic_gpencil_sculpt_settings, @@ -459,9 +477,8 @@ class _draw_tool_settings_context_mode: def WEIGHT_GPENCIL(context, layout, tool): if (tool is None) or (not tool.has_datablock): return False - tool_settings = context.tool_settings - settings = tool_settings.gpencil_sculpt - brush = settings.brush + paint = context.tool_settings.gpencil_weight_paint + brush = paint.brush from bl_ui.properties_paint_common import ( brush_basic_gpencil_weight_settings, @@ -471,6 +488,31 @@ class _draw_tool_settings_context_mode: return True @staticmethod + def VERTEX_GPENCIL(context, layout, tool): + if (tool is None) or (not tool.has_datablock): + return False + + paint = context.tool_settings.gpencil_vertex_paint + brush = paint.brush + + row = layout.row(align=True) + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_vertex_paint + row.template_ID_preview(settings, "brush", rows=3, cols=8, hide_buttons=True) + + if brush.gpencil_vertex_tool not in {'BLUR', 'AVERAGE', 'SMEAR'}: + row.separator(factor=0.4) + row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor") + + from bl_ui.properties_paint_common import ( + brush_basic_gpencil_vertex_settings, + ) + + brush_basic_gpencil_vertex_settings(layout, context, brush, compact=True) + + return True + + @staticmethod def PARTICLE(context, layout, tool): if (tool is None) or (not tool.has_datablock): return False @@ -550,7 +592,7 @@ class VIEW3D_HT_header(Header): else: if (object_mode not in { 'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT', - 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL' + 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL' }) or has_pose_mode: show_snap = True else: @@ -687,7 +729,14 @@ class VIEW3D_HT_header(Header): row.prop(tool_settings, "use_gpencil_select_mask_stroke", text="") row.prop(tool_settings, "use_gpencil_select_mask_segment", text="") - if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode: + # Select mode for Vertex Paint + if gpd.is_stroke_vertex_mode: + row = layout.row(align=True) + row.prop(tool_settings, "use_gpencil_vertex_select_mask_point", text="") + row.prop(tool_settings, "use_gpencil_vertex_select_mask_stroke", text="") + row.prop(tool_settings, "use_gpencil_vertex_select_mask_segment", text="") + + if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode or gpd.is_stroke_vertex_mode: row = layout.row(align=True) row.prop(gpd, "use_multiedit", text="", icon='GP_MULTIFRAME_EDITING') @@ -780,18 +829,17 @@ class VIEW3D_HT_header(Header): # While exposing 'shading.show_xray(_wireframe)' is correct. # this hides the key shortcut from users: T70433. + if has_pose_mode: + draw_depressed = overlay.show_xray_bone + elif shading.type == 'WIREFRAME': + draw_depressed = shading.show_xray_wireframe + else: + draw_depressed = shading.show_xray row.operator( "view3d.toggle_xray", text="", icon='XRAY', - depress=( - overlay.show_xray_bone if has_pose_mode else - getattr( - shading, - "show_xray_wireframe" if shading.type == 'WIREFRAME' else - "show_xray" - ) - ), + depress=draw_depressed, ) row = layout.row(align=True) @@ -812,7 +860,8 @@ class VIEW3D_MT_editor_menus(Menu): obj = context.active_object mode_string = context.mode edit_object = context.edit_object - gp_edit = obj and obj.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'} + gp_edit = obj and obj.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', + 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'} ts = context.scene.tool_settings layout.menu("VIEW3D_MT_view") @@ -827,6 +876,8 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_select_gpencil") elif mode_string == 'EDIT_GPENCIL': layout.menu("VIEW3D_MT_select_gpencil") + elif mode_string == 'VERTEX_GPENCIL': + layout.menu("VIEW3D_MT_select_gpencil") elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}: mesh = obj.data if mesh.use_paint_mask: @@ -878,6 +929,7 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_%s" % mode_string.lower()) if mode_string == 'SCULPT': layout.menu("VIEW3D_MT_mask") + layout.menu("VIEW3D_MT_face_sets") else: layout.menu("VIEW3D_MT_object") @@ -939,6 +991,7 @@ class VIEW3D_MT_transform(VIEW3D_MT_transform_base): layout = self.layout if context.mode == 'EDIT_MESH': layout.operator("transform.shrink_fatten", text="Shrink Fatten") + layout.operator("transform.skin_resize") elif context.mode == 'EDIT_CURVE': layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN' @@ -1110,7 +1163,7 @@ class VIEW3D_MT_view(Menu): if view.region_quadviews: layout.operator("view3d.view_selected", text="Frame Selected (Quad View)").use_all_regions = True - layout.operator("view3d.view_all", text="Frame All").center = False + layout.operator("view3d.view_all").center = False layout.operator("view3d.view_persportho", text="Perspective/Orthographic") layout.menu("VIEW3D_MT_view_local") @@ -1241,7 +1294,7 @@ class VIEW3D_MT_view_align(Menu): layout.separator() - layout.operator("view3d.view_all", text="Center Cursor and View All").center = True + layout.operator("view3d.view_all", text="Center Cursor and Frame All").center = True layout.operator("view3d.view_center_cursor") layout.separator() @@ -1443,7 +1496,7 @@ class VIEW3D_MT_select_particle(Menu): layout.separator() - layout.operator("particle.select_linked") + layout.operator("particle.select_linked", text="Select Linked") layout.separator() @@ -1652,60 +1705,33 @@ class VIEW3D_MT_select_edit_surface(Menu): layout.operator("curve.select_less") -class VIEW3D_MT_edit_text_context_menu(Menu): - bl_label = "Text Context Menu" - - def draw(self, _context): - layout = self.layout - - layout.operator_context = 'INVOKE_DEFAULT' - - layout.operator("font.text_cut", text="Cut") - layout.operator("font.text_copy", text="Copy", icon='COPYDOWN') - layout.operator("font.text_paste", text="Paste", icon='PASTEDOWN') - - layout.separator() - - layout.operator("font.select_all") - - layout.separator() - - layout.menu("VIEW3D_MT_edit_font") - - class VIEW3D_MT_select_edit_text(Menu): - # intentional name mismatch - # select menu for 3d-text doesn't make sense - bl_label = "Edit" + bl_label = "Select" def draw(self, _context): layout = self.layout - layout.operator("ed.undo") - layout.operator("ed.redo") - - layout.separator() - - layout.operator("font.text_cut", text="Cut") - layout.operator("font.text_copy", text="Copy", icon='COPYDOWN') - layout.operator("font.text_paste", text="Paste", icon='PASTEDOWN') + layout.operator("font.select_all", text="All") layout.separator() - layout.operator("font.text_paste_from_file") + layout.operator("font.move_select", text="Previous Block").type = 'PREVIOUS_PAGE' + layout.operator("font.move_select", text="Next Block").type = 'NEXT_PAGE' layout.separator() - layout.operator("font.select_all") + layout.operator("font.move_select", text="Line Begin").type = 'LINE_BEGIN' + layout.operator("font.move_select", text="Line End").type = 'LINE_END' layout.separator() - layout.operator("font.case_set", text="To Uppercase").case = 'UPPER' - layout.operator("font.case_set", text="To Lowercase").case = 'LOWER' + layout.operator("font.move_select", text="Previous Line").type = 'PREVIOUS_LINE' + layout.operator("font.move_select", text="Next Line").type = 'NEXT_LINE' layout.separator() - layout.menu("VIEW3D_MT_edit_text_chars") + layout.operator("font.move_select", text="Previous Word").type = 'PREVIOUS_WORD' + layout.operator("font.move_select", text="Next Word").type = 'NEXT_WORD' class VIEW3D_MT_select_edit_metaball(Menu): @@ -1805,6 +1831,10 @@ class VIEW3D_MT_select_edit_armature(Menu): layout.separator() + layout.operator("armature.select_linked", text="Linked") + + layout.separator() + props = layout.operator("armature.select_hierarchy", text="Parent") props.extend = False props.direction = 'PARENT' @@ -1848,6 +1878,9 @@ class VIEW3D_MT_select_gpencil(Menu): layout.operator("gpencil.select_alternate") layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped") + if _context.mode == 'VERTEX_GPENCIL': + layout.operator("gpencil.select_vertex_color", text="Vertex Color") + layout.separator() layout.operator("gpencil.select_first") @@ -2100,6 +2133,16 @@ class VIEW3D_MT_camera_add(Menu): layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA') +class VIEW3D_MT_volume_add(Menu): + bl_idname = "VIEW3D_MT_volume_add" + bl_label = "Volume" + + def draw(self, _context): + layout = self.layout + layout.operator("object.volume_import", text="Import OpenVDB...", icon='OUTLINER_DATA_VOLUME') + layout.operator("object.volume_add", text="Empty", icon='OUTLINER_DATA_VOLUME') + + class VIEW3D_MT_add(Menu): bl_label = "Add" bl_translation_context = i18n_contexts.operator_default @@ -2122,6 +2165,11 @@ class VIEW3D_MT_add(Menu): layout.menu("VIEW3D_MT_surface_add", icon='OUTLINER_OB_SURFACE') layout.menu("VIEW3D_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META') layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT') + if hasattr(bpy.data, "hairs"): + layout.operator("object.hair_add", text="Hair", icon='OUTLINER_OB_HAIR') + if hasattr(bpy.data, "pointclouds"): + layout.operator("object.pointcloud_add", text="Point Cloud", icon='OUTLINER_OB_POINTCLOUD') + layout.menu("VIEW3D_MT_volume_add", text="Volume", icon='OUTLINER_OB_VOLUME') layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL') layout.separator() @@ -2713,6 +2761,7 @@ class VIEW3D_MT_make_single_user(Menu): def draw(self, _context): layout = self.layout + layout.operator_context = 'EXEC_DEFAULT' props = layout.operator("object.make_single_user", text="Object") props.object = True @@ -2866,6 +2915,32 @@ class VIEW3D_MT_gpencil_vertex_group(Menu): layout.operator("gpencil.vertex_group_deselect", text="Deselect") +class VIEW3D_MT_paint_weight_lock(Menu): + bl_label = "Vertex Group Locks" + + def draw(self, _context): + layout = self.layout + + op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All") + op.action, op.mask = 'LOCK', 'ALL' + op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All") + op.action, op.mask = 'UNLOCK', 'ALL' + op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Selected") + op.action, op.mask = 'LOCK', 'SELECTED' + op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Selected") + op.action, op.mask = 'UNLOCK', 'SELECTED' + op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Unselected") + op.action, op.mask = 'LOCK', 'UNSELECTED' + op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Unselected") + op.action, op.mask = 'UNLOCK', 'UNSELECTED' + op = layout.operator("object.vertex_group_lock", text="Lock Only Selected") + op.action, op.mask = 'LOCK', 'INVERT_UNSELECTED' + op = layout.operator("object.vertex_group_lock", text="Lock Only Unselected") + op.action, op.mask = 'UNLOCK', 'INVERT_UNSELECTED' + op = layout.operator("object.vertex_group_lock", text="Invert Locks") + op.action, op.mask = 'INVERT', 'ALL' + + class VIEW3D_MT_paint_weight(Menu): bl_label = "Weights" @@ -2907,6 +2982,8 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("paint.weight_set") + layout.menu("VIEW3D_MT_paint_weight_lock", text="Locks") + def draw(self, _context): self.draw_generic(self.layout, is_editmode=False) @@ -2937,6 +3014,10 @@ class VIEW3D_MT_sculpt(Menu): layout.menu("VIEW3D_MT_sculpt_set_pivot", text="Set Pivot") + layout.separator() + + layout.operator("sculpt.optimize") + class VIEW3D_MT_mask(Menu): bl_label = "Mask" @@ -2991,12 +3072,14 @@ class VIEW3D_MT_mask(Menu): props.keep_previous_mask = False props.invert = True props.smooth_iterations = 2 + props.create_face_set = False props = layout.operator("sculpt.mask_expand", text="Expand Mask By Curvature") props.use_normals = True props.keep_previous_mask = True props.invert = False props.smooth_iterations = 0 + props.create_face_set = False layout.separator() @@ -3015,6 +3098,38 @@ class VIEW3D_MT_mask(Menu): props = layout.operator("sculpt.dirty_mask", text='Dirty Mask') +class VIEW3D_MT_face_sets(Menu): + bl_label = "Face Sets" + + def draw(self, _context): + layout = self.layout + + + op = layout.operator("sculpt.face_sets_create", text='Face Set From Masked') + op.mode = 'MASKED' + + op = layout.operator("sculpt.face_sets_create", text='Face Set From Visible') + op.mode = 'VISIBLE' + + op = layout.operator("sculpt.face_sets_create", text='Face Set From Edit Mode Selection') + op.mode = 'SELECTION' + + layout.separator() + + layout.menu("VIEW3D_MT_face_sets_init", text="Init Face Sets") + + layout.separator() + + op = layout.operator("sculpt.face_set_change_visibility", text='Invert Visible Face Sets') + op.mode = 'INVERT' + + op = layout.operator("sculpt.face_set_change_visibility", text='Show All Face Sets') + op.mode = 'SHOW_ALL' + + layout.separator() + + op = layout.operator("sculpt.face_sets_randomize_colors", text='Randomize Colors') + class VIEW3D_MT_sculpt_set_pivot(Menu): bl_label = "Sculpt Set Pivot" @@ -3037,6 +3152,37 @@ class VIEW3D_MT_sculpt_set_pivot(Menu): props = layout.operator("sculpt.set_pivot_position", text="Pivot to Surface Under Cursor") props.mode = 'SURFACE' +class VIEW3D_MT_face_sets_init(Menu): + bl_label = "Face Sets Init" + + def draw(self, _context): + layout = self.layout + + op = layout.operator("sculpt.face_sets_init", text='By Loose Parts') + op.mode = 'LOOSE_PARTS' + + op = layout.operator("sculpt.face_sets_init", text='By Materials') + op.mode = 'MATERIALS' + + op = layout.operator("sculpt.face_sets_init", text='By Normals') + op.mode = 'NORMALS' + + op = layout.operator("sculpt.face_sets_init", text='By UV Seams') + op.mode = 'UV_SEAMS' + + op = layout.operator("sculpt.face_sets_init", text='By Edge Creases') + op.mode = 'CREASES' + + op = layout.operator("sculpt.face_sets_init", text='By Edge Bevel Weight') + op.mode = 'BEVEL_WEIGHT' + + op = layout.operator("sculpt.face_sets_init", text='By Sharp Edges') + op.mode = 'SHARP_EDGES' + + op = layout.operator("sculpt.face_sets_init", text='By Face Maps') + op.mode = 'FACE_MAPS' + + class VIEW3D_MT_particle(Menu): bl_label = "Particle" @@ -3121,8 +3267,7 @@ class VIEW3D_MT_particle_context_menu(Menu): layout.separator() - layout.operator("particle.select_linked") - + layout.operator("particle.select_linked", text="Select Linked") class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu): _operator_name = "particle" @@ -3170,13 +3315,7 @@ class VIEW3D_MT_pose(Menu): layout.separator() - layout.operator_context = 'EXEC_AREA' - layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS' - layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS' - layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS' - - layout.operator("pose.flip_names") - + layout.menu("VIEW3D_MT_pose_names") layout.operator("pose.quaternions_flip") layout.separator() @@ -3313,6 +3452,19 @@ class VIEW3D_MT_pose_constraints(Menu): layout.operator("pose.constraints_clear") +class VIEW3D_MT_pose_names(Menu): + bl_label = "Names" + + def draw(self, _context): + layout = self.layout + + layout.operator_context = 'EXEC_REGION_WIN' + layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS' + layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS' + layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS' + layout.operator("pose.flip_names") + + class VIEW3D_MT_pose_showhide(ShowHideMenu, Menu): _operator_name = "pose" @@ -3385,7 +3537,6 @@ class BoneOptions: "use_deform", "use_envelope_multiply", "use_inherit_rotation", - "inherit_scale", ] if context.mode == 'EDIT_ARMATURE': @@ -3440,7 +3591,15 @@ class VIEW3D_MT_edit_mesh(Menu): layout.operator("mesh.duplicate_move", text="Duplicate") layout.menu("VIEW3D_MT_edit_mesh_extrude") - layout.operator("mesh.split") + + layout.separator() + + layout.menu("VIEW3D_MT_edit_mesh_merge", text="Merge") + layout.menu("VIEW3D_MT_edit_mesh_split", text="Split") + layout.operator_menu_enum("mesh.separate", "type") + + layout.separator() + layout.operator("mesh.bisect") layout.operator("mesh.knife_project") @@ -3462,7 +3621,6 @@ class VIEW3D_MT_edit_mesh(Menu): layout.separator() layout.menu("VIEW3D_MT_edit_mesh_showhide") - layout.operator_menu_enum("mesh.separate", "type") layout.menu("VIEW3D_MT_edit_mesh_clean") layout.separator() @@ -3580,7 +3738,8 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu): col.separator() - col.operator("mesh.loopcut_slide") + props = col.operator("mesh.loopcut_slide") + props.TRANSFORM_OT_edge_slide.release_confirm = False col.operator("mesh.offset_edge_loops_slide") col.separator() @@ -3603,11 +3762,6 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu): col.separator() - col.operator("mesh.mark_seam").clear = False - col.operator("mesh.mark_seam", text="Clear Seam").clear = True - - col.separator() - col.operator("mesh.mark_sharp") col.operator("mesh.mark_sharp", text="Clear Sharp").clear = True @@ -3719,12 +3873,19 @@ class VIEW3D_MT_edit_mesh_extrude(Menu): return menu def draw(self, context): + from math import pi + layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' for menu_id in self.extrude_options(context): self._extrude_funcs[menu_id](layout) + layout.separator() + + layout.operator("mesh.extrude_repeat") + layout.operator("mesh.spin").angle = pi * 2 + class VIEW3D_MT_edit_mesh_vertices(Menu): bl_label = "Vertex" @@ -3755,6 +3916,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.operator("transform.vert_slide", text="Slide Vertices") layout.operator_context = 'EXEC_DEFAULT' layout.operator("mesh.vertices_smooth", text="Smooth Vertices").factor = 0.5 + layout.operator("mesh.vertices_smooth_laplacian", text="Smooth Vertices (Laplacian)") layout.operator_context = 'INVOKE_REGION_WIN' layout.separator() @@ -3764,10 +3926,6 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.separator() - layout.menu("VIEW3D_MT_edit_mesh_merge", text="Merge Vertices") - - layout.separator() - layout.menu("VIEW3D_MT_vertex_group") layout.menu("VIEW3D_MT_hook") @@ -3823,6 +3981,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.operator("mesh.extrude_edges_move", text="Extrude Edges") layout.operator("mesh.bevel", text="Bevel Edges").vertex_only = False layout.operator("mesh.bridge_edge_loops") + layout.operator("mesh.screw") layout.separator() @@ -3838,7 +3997,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.separator() layout.operator("transform.edge_slide") - layout.operator("mesh.edge_split") + layout.operator("mesh.offset_edge_loops_slide") layout.separator() @@ -3847,11 +4006,6 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.separator() - layout.operator("mesh.mark_seam").clear = False - layout.operator("mesh.mark_seam", text="Clear Seam").clear = True - - layout.separator() - layout.operator("mesh.mark_sharp") layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True @@ -4017,7 +4171,7 @@ class VIEW3D_MT_edit_mesh_normals(Menu): layout.operator("mesh.normals_tools", text="Copy Vectors").mode = 'COPY' layout.operator("mesh.normals_tools", text="Paste Vectors").mode = 'PASTE' - layout.operator("mesh.smoothen_normals", text="Smoothen Vectors") + layout.operator("mesh.smooth_normals", text="Smooth Vectors") layout.operator("mesh.normals_tools", text="Reset Vectors").mode = 'RESET' layout.separator() @@ -4116,6 +4270,19 @@ class VIEW3D_MT_edit_mesh_merge(Menu): layout.operator("mesh.remove_doubles", text="By Distance") +class VIEW3D_MT_edit_mesh_split(Menu): + bl_label = "Split" + + def draw(self, _context): + layout = self.layout + + layout.operator("mesh.split", text="Selection") + + layout.separator() + + layout.operator_enum("mesh.edge_split", "type") + + class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu): _operator_name = "mesh" @@ -4157,6 +4324,9 @@ def draw_curve(self, _context): layout.operator("curve.split") layout.operator("curve.separate") + + layout.separator() + layout.operator("curve.cyclic_toggle") layout.operator_menu_enum("curve.spline_type_set", "type") @@ -4285,6 +4455,7 @@ class VIEW3D_MT_edit_curve_context_menu(Menu): # Remove layout.operator("curve.split") layout.operator("curve.decimate") + layout.operator("curve.separate") layout.operator("curve.dissolve_verts") layout.operator("curve.delete", text="Delete Segment").type = 'SEGMENT' layout.operator("curve.delete", text="Delete Point").type = 'VERT' @@ -4313,19 +4484,7 @@ class VIEW3D_MT_edit_surface(Menu): draw = draw_curve -class VIEW3D_MT_edit_font(Menu): - bl_label = "Font" - - def draw(self, _context): - layout = self.layout - - layout.operator("font.style_toggle", text="Toggle Bold", icon='BOLD').style = 'BOLD' - layout.operator("font.style_toggle", text="Toggle Italic", icon='ITALIC').style = 'ITALIC' - layout.operator("font.style_toggle", text="Toggle Underline", icon='UNDERLINE').style = 'UNDERLINE' - layout.operator("font.style_toggle", text="Toggle Small Caps", icon='SMALL_CAPS').style = 'SMALL_CAPS' - - -class VIEW3D_MT_edit_text_chars(Menu): +class VIEW3D_MT_edit_font_chars(Menu): bl_label = "Special Characters" def draw(self, _context): @@ -4365,6 +4524,91 @@ class VIEW3D_MT_edit_text_chars(Menu): layout.operator("font.text_insert", text="Spanish Exclamation Mark").text = "\u00A1" +class VIEW3D_MT_edit_font_kerning(Menu): + bl_label = "Kerning" + + def draw(self, context): + layout = self.layout + + ob = context.active_object + text = ob.data + kerning = text.edit_format.kerning + + layout.operator("font.change_spacing", text="Decrease Kerning").delta = -1 + layout.operator("font.change_spacing", text="Increase Kerning").delta = 1 + layout.operator("font.change_spacing", text="Reset Kerning").delta = -kerning + + +class VIEW3D_MT_edit_font_delete(Menu): + bl_label = "Delete" + + def draw(self, _context): + layout = self.layout + + layout.operator("font.delete", text="Previous Character").type = 'PREVIOUS_CHARACTER' + layout.operator("font.delete", text="Next Character").type = 'NEXT_CHARACTER' + layout.operator("font.delete", text="Previous Word").type = 'PREVIOUS_WORD' + layout.operator("font.delete", text="Next Word").type = 'NEXT_WORD' + + +class VIEW3D_MT_edit_font(Menu): + bl_label = "Text" + + def draw(self, _context): + layout = self.layout + + layout.operator("font.text_cut", text="Cut") + layout.operator("font.text_copy", text="Copy", icon='COPYDOWN') + layout.operator("font.text_paste", text="Paste", icon='PASTEDOWN') + + layout.separator() + + layout.operator("font.text_paste_from_file") + + layout.separator() + + layout.operator("font.case_set", text="To Uppercase").case = 'UPPER' + layout.operator("font.case_set", text="To Lowercase").case = 'LOWER' + + layout.separator() + + layout.menu("VIEW3D_MT_edit_font_chars") + + layout.separator() + + layout.operator("font.style_toggle", text="Toggle Bold", icon='BOLD').style = 'BOLD' + layout.operator("font.style_toggle", text="Toggle Italic", icon='ITALIC').style = 'ITALIC' + layout.operator("font.style_toggle", text="Toggle Underline", icon='UNDERLINE').style = 'UNDERLINE' + layout.operator("font.style_toggle", text="Toggle Small Caps", icon='SMALL_CAPS').style = 'SMALL_CAPS' + + layout.menu("VIEW3D_MT_edit_font_kerning") + + layout.separator() + + layout.menu("VIEW3D_MT_edit_font_delete") + + +class VIEW3D_MT_edit_font_context_menu(Menu): + bl_label = "Text Context Menu" + + def draw(self, _context): + layout = self.layout + + layout.operator_context = 'INVOKE_DEFAULT' + + layout.operator("font.text_cut", text="Cut") + layout.operator("font.text_copy", text="Copy", icon='COPYDOWN') + layout.operator("font.text_paste", text="Paste", icon='PASTEDOWN') + + layout.separator() + + layout.operator("font.select_all") + + layout.separator() + + layout.menu("VIEW3D_MT_edit_font") + + class VIEW3D_MT_edit_meta(Menu): bl_label = "Metaball" @@ -4442,8 +4686,10 @@ class VIEW3D_MT_edit_armature(Menu): layout.operator("armature.extrude_forked") layout.operator("armature.duplicate_move") - layout.operator("armature.merge") layout.operator("armature.fill") + + layout.separator() + layout.operator("armature.split") layout.operator("armature.separate") @@ -4515,7 +4761,7 @@ class VIEW3D_MT_armature_context_menu(Menu): # Remove layout.operator("armature.split") - layout.operator("armature.merge") + layout.operator("armature.separate") layout.operator("armature.dissolve") layout.operator("armature.delete") @@ -4598,6 +4844,10 @@ class VIEW3D_MT_paint_gpencil(Menu): layout = self.layout + layout.menu("GPENCIL_MT_layer_active", text="Active Layer") + + layout.separator() + layout.menu("VIEW3D_MT_gpencil_animation") layout.menu("VIEW3D_MT_edit_gpencil_interpolate") @@ -4656,6 +4906,10 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.separator() + layout.menu("GPENCIL_MT_layer_active", text="Active Layer") + + layout.separator() + layout.menu("VIEW3D_MT_gpencil_animation") layout.menu("VIEW3D_MT_edit_gpencil_interpolate") @@ -4690,6 +4944,7 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu): def draw(self, _context): layout = self.layout + settings = _context.tool_settings.gpencil_sculpt layout.operator("gpencil.stroke_subdivide", text="Subdivide").only_selected = False layout.menu("VIEW3D_MT_gpencil_simplify") @@ -4715,6 +4970,10 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu): layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE' layout.operator_menu_enum("gpencil.stroke_caps_set", text="Toggle Caps", property="type") layout.operator("gpencil.stroke_flip", text="Switch Direction") + layout.prop(settings, "use_scale_thickness") + + layout.separator() + layout.operator("gpencil.reset_transform_fill", text="Reset Fill Transform") class VIEW3D_MT_edit_gpencil_point(Menu): @@ -4759,6 +5018,22 @@ class VIEW3D_MT_weight_gpencil(Menu): layout.menu("VIEW3D_MT_gpencil_autoweights") +class VIEW3D_MT_vertex_gpencil(Menu): + bl_label = "Paint" + + def draw(self, _context): + layout = self.layout + layout.operator("gpencil.vertex_color_set", text="Set Vertex Colors") + layout.separator() + layout.operator("gpencil.vertex_color_invert", text="Invert") + layout.operator("gpencil.vertex_color_levels", text="Levels") + layout.operator("gpencil.vertex_color_hsv", text="Hue Saturation Value") + layout.operator("gpencil.vertex_color_brightness_contrast", text="Bright/Contrast") + + layout.separator() + layout.menu("VIEW3D_MT_join_palette") + + class VIEW3D_MT_gpencil_animation(Menu): bl_label = "Animation" @@ -5013,6 +5288,58 @@ class VIEW3D_MT_sculpt_mask_edit_pie(Menu): op.filter_type = 'CONTRAST_DECREASE' op.auto_iteration_count = False +class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu): + + bl_label = "Face Sets Edit" + + def draw(self, _context): + layout = self.layout + pie = layout.menu_pie() + + op = pie.operator("sculpt.face_sets_create", text='Face Set From Masked') + op.mode = 'MASKED' + + op = pie.operator("sculpt.face_sets_create", text='Face Set From Visible') + op.mode = 'VISIBLE' + + op = pie.operator("sculpt.face_set_change_visibility", text='Invert Visible') + op.mode = 'INVERT' + + op = pie.operator("sculpt.face_set_change_visibility", text='Show All') + op.mode = 'SHOW_ALL' + +class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu): + bl_label = "Vertex Group Locks" + + def draw(self, _context): + layout = self.layout + pie = layout.menu_pie() + + # 1: Left + op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All") + op.action, op.mask = 'LOCK', 'ALL' + # 2: Right + op = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All") + op.action, op.mask = 'UNLOCK', 'ALL' + # 3: Down + op = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Selected") + op.action, op.mask = 'UNLOCK', 'SELECTED' + # 4: Up + op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Selected") + op.action, op.mask = 'LOCK', 'SELECTED' + # 5: Up/Left + op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Unselected") + op.action, op.mask = 'LOCK', 'UNSELECTED' + # 6: Up/Right + op = pie.operator("object.vertex_group_lock", text="Lock Only Selected") + op.action, op.mask = 'LOCK', 'INVERT_UNSELECTED' + # 7: Down/Left + op = pie.operator("object.vertex_group_lock", text="Lock Only Unselected") + op.action, op.mask = 'UNLOCK', 'INVERT_UNSELECTED' + # 8: Down/Right + op = pie.operator("object.vertex_group_lock", text="Invert Locks") + op.action, op.mask = 'INVERT', 'ALL' + # ********** Panel ********** @@ -5058,8 +5385,8 @@ class VIEW3D_PT_view3d_properties(Panel): layout.use_property_split = True layout.use_property_decorate = False # No animation. - flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) - col = flow.column() + + col = layout.column() subcol = col.column() subcol.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews) @@ -5069,20 +5396,22 @@ class VIEW3D_PT_view3d_properties(Panel): subcol.prop(view, "clip_start", text="Clip Start") subcol.prop(view, "clip_end", text="End") - subcol.separator() - - col = flow.column() + layout.separator() - subcol = col.column() - subcol.prop(view, "use_local_camera") + col = layout.column(align=False, heading="Local Camera") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(view, "use_local_camera", text="") + sub = sub.row(align=True) + sub.enabled = view.use_local_camera + sub.prop(view, "camera", text="") - subcol = col.column() - subcol.enabled = view.use_local_camera - subcol.prop(view, "camera", text="Local Camera") + layout.separator() - subcol = col.column(align=True) - subcol.prop(view, "use_render_border") - subcol.active = view.region_3d.view_perspective != 'CAMERA' + col = layout.column(align=True) + col.prop(view, "use_render_border") + col.active = view.region_3d.view_perspective != 'CAMERA' class VIEW3D_PT_view3d_lock(Panel): @@ -5101,23 +5430,24 @@ class VIEW3D_PT_view3d_lock(Panel): view = context.space_data col = layout.column(align=True) - subcol = col.column() - subcol.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews) + sub = col.column() + sub.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews) - subcol.prop(view, "lock_object") + sub.prop(view, "lock_object") lock_object = view.lock_object if lock_object: if lock_object.type == 'ARMATURE': - subcol.prop_search( + sub.prop_search( view, "lock_bone", lock_object.data, "edit_bones" if lock_object.mode == 'EDIT' else "bones", text="", ) else: - subcol.prop(view, "lock_cursor", text="Lock to 3D Cursor") + subcol = sub.column(heading="Lock") + subcol.prop(view, "lock_cursor", text="To 3D Cursor") - col.prop(view, "lock_camera") + col.prop(view, "lock_camera", text="Camera to View") class VIEW3D_PT_view3d_cursor(Panel): @@ -5240,6 +5570,9 @@ class VIEW3D_PT_object_type_visibility(Panel): ("surf", "Surface"), ("meta", "Meta"), ("font", "Text"), + ("hair", "Hair"), + ("pointcloud", "Point Cloud"), + ("volume", "Volume"), ("grease_pencil", "Grease Pencil"), (None, None), # Other @@ -5257,6 +5590,11 @@ class VIEW3D_PT_object_type_visibility(Panel): col.separator() continue + if attr == "hair" and not hasattr(bpy.data, "hairs"): + continue + elif attr == "pointcloud" and not hasattr(bpy.data, "pointclouds"): + continue + attr_v = "show_object_viewport_" f"{attr:s}" attr_s = "show_object_select_" f"{attr:s}" @@ -5377,6 +5715,7 @@ class VIEW3D_PT_shading_lighting(Panel): col.prop(shading, "studiolight_rotate_z", text="Rotation") col.prop(shading, "studiolight_intensity") col.prop(shading, "studiolight_background_alpha") + col.prop(shading, "studiolight_background_blur") col = split.column() # to align properly with above elif shading.type == 'RENDERED': @@ -5400,6 +5739,7 @@ class VIEW3D_PT_shading_lighting(Panel): col.prop(shading, "studiolight_rotate_z", text="Rotation") col.prop(shading, "studiolight_intensity") col.prop(shading, "studiolight_background_alpha") + col.prop(shading, "studiolight_background_blur") col = split.column() # to align properly with above @@ -5697,13 +6037,16 @@ class VIEW3D_PT_overlay_guides(Panel): split = col.split() sub = split.column() sub.prop(overlay, "show_text", text="Text Info") + sub.prop(overlay, "show_stats", text="Statistics") + sub = split.column() sub.prop(overlay, "show_cursor", text="3D Cursor") + sub.prop(overlay, "show_annotation", text="Annotations") if shading.type == 'MATERIAL': - col.prop(overlay, "show_look_dev") - - col.prop(overlay, "show_annotation", text="Annotations") + row = col.row() + row.active = shading.render_pass == 'COMBINED' + row.prop(overlay, "show_look_dev") class VIEW3D_PT_overlay_object(Panel): @@ -6062,6 +6405,12 @@ class VIEW3D_PT_overlay_sculpt(Panel): sub.active = sculpt.show_mask sub.prop(overlay, "sculpt_mode_mask_opacity", text="Mask") + row = layout.row(align=True) + row.prop(sculpt, "show_face_sets", text="") + sub = row.row() + sub.active = sculpt.show_face_sets + row.prop(overlay, "sculpt_mode_face_sets_opacity", text="Face Sets") + class VIEW3D_PT_overlay_pose(Panel): bl_space_type = 'VIEW_3D' @@ -6362,6 +6711,7 @@ class VIEW3D_PT_overlay_gpencil_options(Panel): 'EDIT_GPENCIL': "Edit Grease Pencil", 'SCULPT_GPENCIL': "Sculpt Grease Pencil", 'WEIGHT_GPENCIL': "Weight Grease Pencil", + 'VERTEX_GPENCIL': "Vertex Grease Pencil", 'OBJECT': "Grease Pencil", }[context.mode]) @@ -6375,9 +6725,10 @@ class VIEW3D_PT_overlay_gpencil_options(Panel): col = layout.column() row = col.row() row.prop(overlay, "use_gpencil_grid", text="") - sub = row.row() + sub = row.row(align=True) sub.active = overlay.use_gpencil_grid sub.prop(overlay, "gpencil_grid_opacity", text="Canvas", slider=True) + sub.prop(overlay, "use_gpencil_canvas_xray", text="", icon='XRAY') row = col.row() row.prop(overlay, "use_gpencil_fade_layers", text="") @@ -6386,17 +6737,32 @@ class VIEW3D_PT_overlay_gpencil_options(Panel): sub.prop(overlay, "gpencil_fade_layer", text="Fade Layers", slider=True) row = col.row() - row.prop(overlay, "use_gpencil_paper", text="") + row.prop(overlay, "use_gpencil_fade_objects", text="") sub = row.row(align=True) - sub.active = overlay.use_gpencil_paper - sub.prop(overlay, "gpencil_paper_opacity", text="Fade Objects", slider=True) - sub.prop(overlay, "use_gpencil_fade_objects", text="", icon='OUTLINER_OB_GREASEPENCIL') + sub.active = overlay.use_gpencil_fade_objects + sub.prop(overlay, "gpencil_fade_objects", text="Fade Objects", slider=True) + sub.prop(overlay, "use_gpencil_fade_gp_objects", text="", icon='OUTLINER_OB_GREASEPENCIL') + + if context.object.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}: + split = layout.split() + col = split.column() + col.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines") + col = split.column() + col.prop(overlay, "use_gpencil_multiedit_line_only", text="Only in Multiframe") + + if context.object.mode == 'EDIT_GPENCIL': + split = layout.split() + col = split.column() + col.prop(overlay, "use_gpencil_show_directions") + col = split.column() + col.prop(overlay, "use_gpencil_show_material_name", text="Material Name") - if context.object.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - layout.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines") - layout.prop(overlay, "use_gpencil_multiedit_line_only", text="Show Edit Lines only in multiframe") layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True) + if context.object.mode in {'PAINT_GPENCIL', 'VERTEX_GPENCIL'}: + layout.label(text="Vertex Paint") + layout.prop(overlay, "gpencil_vertex_paint_opacity", text="Opacity", slider=True) + class VIEW3D_PT_quad_view(Panel): bl_space_type = 'VIEW_3D' @@ -6672,77 +7038,143 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu): col.operator("gpencil.reproject", text="Reproject Strokes") +def draw_gpencil_layer_active(context, layout): + gpl = context.active_gpencil_layer + if gpl: + layout.label(text="Active Layer") + row = layout.row(align=True) + row.operator_context = 'EXEC_REGION_WIN' + row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL') + row.prop(gpl, "info", text="") + row.operator("gpencil.layer_remove", text="", icon='X') + + +def draw_gpencil_material_active(context, layout): + ob = context.active_object + if ob and len(ob.material_slots) > 0 and ob.active_material_index >= 0: + ma = ob.material_slots[ob.active_material_index].material + if ma: + layout.label(text="Active Material") + row = layout.row(align=True) + row.operator_context = 'EXEC_REGION_WIN' + row.operator_menu_enum("gpencil.material_set", "slot", text="", icon='MATERIAL') + row.prop(ma, "name", text="") + + class VIEW3D_PT_gpencil_sculpt_context_menu(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' bl_label = "Sculpt Context Menu" + bl_ui_units_x = 12 def draw(self, context): - brush = context.tool_settings.gpencil_sculpt.brush + ts = context.tool_settings + settings = ts.gpencil_sculpt_paint + brush = settings.brush layout = self.layout - if context.mode == 'WEIGHT_GPENCIL': - layout.prop(brush, "weight") layout.prop(brush, "size", slider=True) layout.prop(brush, "strength") - layout.separator() - - # Frames - layout.label(text="Frames:") + # Layers + draw_gpencil_layer_active(context, layout) - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("gpencil.blank_frame_add", text="Insert Blank in Active Layer", icon='ADD') - layout.operator("gpencil.blank_frame_add", text="Insert Blank in All Layers", icon='ADD').all_layers = True +class VIEW3D_PT_gpencil_weight_context_menu(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_label = "Weight Paint Context Menu" + bl_ui_units_x = 12 - layout.separator() + def draw(self, context): + ts = context.tool_settings + settings = ts.gpencil_weight_paint + brush = settings.brush - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Layer", icon='DUPLICATE') - layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers", icon='DUPLICATE').mode = 'ALL' + layout = self.layout - layout.separator() + layout.prop(brush, "size", slider=True) + layout.prop(brush, "strength") + layout.prop(brush, "weight") - layout.operator("gpencil.delete", text="Delete Active Layer", icon='REMOVE').type = 'FRAME' - layout.operator("gpencil.active_frames_delete_all", text="Delete All Layers", icon='REMOVE') + # Layers + draw_gpencil_layer_active(context, layout) class VIEW3D_PT_gpencil_draw_context_menu(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' bl_label = "Draw Context Menu" + bl_ui_units_x = 12 def draw(self, context): - brush = context.tool_settings.gpencil_paint.brush + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush gp_settings = brush.gpencil_settings layout = self.layout + is_vertex = settings.color_mode == 'VERTEXCOLOR' or brush.gpencil_tool == 'TINT' + + if brush.gpencil_tool not in {'ERASE', 'CUTTER', 'EYEDROPPER'} and is_vertex: + split = layout.split(factor=0.1) + split.prop(brush, "color", text="") + split.template_color_picker(brush, "color", value_slider=True) + + col = layout.column() + col.separator() + col.prop_menu_enum(gp_settings, "vertex_mode", text="Mode") + col.separator() if brush.gpencil_tool not in {'FILL', 'CUTTER'}: layout.prop(brush, "size", slider=True) if brush.gpencil_tool not in {'ERASE', 'FILL', 'CUTTER'}: layout.prop(gp_settings, "pen_strength") - layout.separator() + # Layers + draw_gpencil_layer_active(context, layout) + # Material + if not is_vertex: + draw_gpencil_material_active(context, layout) - # Frames - layout.label(text="Frames:") - layout.operator_context = 'INVOKE_REGION_WIN' +class VIEW3D_PT_gpencil_vertex_context_menu(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_label = "Vertex Paint Context Menu" + bl_ui_units_x = 12 - layout.operator("gpencil.blank_frame_add", text="Insert Blank in Active Layer", icon='ADD') - layout.operator("gpencil.blank_frame_add", text="Insert Blank in All Layers", icon='ADD').all_layers = True + def draw(self, context): + layout = self.layout + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + gp_settings = brush.gpencil_settings - layout.separator() + col = layout.column() - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Layer", icon='DUPLICATE') - layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers", icon='DUPLICATE').mode = 'ALL' + if brush.gpencil_vertex_tool in {'DRAW', 'REPLACE'}: + split = layout.split(factor=0.1) + split.prop(brush, "color", text="") + split.template_color_picker(brush, "color", value_slider=True) - layout.separator() + col = layout.column() + col.separator() + col.prop_menu_enum(gp_settings, "vertex_mode", text="Mode") + col.separator() - layout.operator("gpencil.delete", text="Delete Active Layer", icon='REMOVE').type = 'FRAME' - layout.operator("gpencil.active_frames_delete_all", text="Delete All Layers", icon='REMOVE') + row = col.row(align=True) + row.prop(brush, "size", text="Radius") + row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') + + if brush.gpencil_vertex_tool in {'DRAW', 'BLUR', 'SMEAR'}: + row = layout.row(align=True) + row.prop(gp_settings, "pen_strength", slider=True) + row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + + # Layers + draw_gpencil_layer_active(context, layout) class VIEW3D_PT_paint_vertex_context_menu(Panel): @@ -6898,7 +7330,10 @@ class VIEW3D_PT_sculpt_context_menu(Panel): layout.prop(brush, "normal_weight", slider=True) if capabilities.has_pinch_factor: - layout.prop(brush, "crease_pinch_factor", slider=True, text="Pinch") + text = "Pinch" + if brush.sculpt_tool in {'BLOB', 'SNAKE_HOOK'}: + text = "Magnify" + layout.prop(brush, "crease_pinch_factor", slider=True, text=text) if capabilities.has_rake_factor: layout.prop(brush, "rake_factor", slider=True) @@ -6923,6 +7358,17 @@ class TOPBAR_PT_gpencil_materials(GreasePencilMaterialsPanel, Panel): return ob and ob.type == 'GPENCIL' +class TOPBAR_PT_gpencil_vertexcolor(GreasePencilVertexcolorPanel, Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_label = "Vertex Color" + bl_ui_units_x = 10 + + @classmethod + def poll(cls, context): + ob = context.object + return ob and ob.type == 'GPENCIL' + classes = ( VIEW3D_HT_header, VIEW3D_HT_tool_header, @@ -6954,7 +7400,6 @@ classes = ( VIEW3D_MT_select_edit_mesh, VIEW3D_MT_select_edit_curve, VIEW3D_MT_select_edit_surface, - VIEW3D_MT_edit_text_context_menu, VIEW3D_MT_select_edit_text, VIEW3D_MT_select_edit_metaball, VIEW3D_MT_edit_lattice_context_menu, @@ -6975,6 +7420,7 @@ classes = ( VIEW3D_MT_light_add, VIEW3D_MT_lightprobe_add, VIEW3D_MT_camera_add, + VIEW3D_MT_volume_add, VIEW3D_MT_add, VIEW3D_MT_image_add, VIEW3D_MT_object, @@ -6999,9 +7445,12 @@ classes = ( VIEW3D_MT_vertex_group, VIEW3D_MT_gpencil_vertex_group, VIEW3D_MT_paint_weight, + VIEW3D_MT_paint_weight_lock, VIEW3D_MT_sculpt, VIEW3D_MT_sculpt_set_pivot, VIEW3D_MT_mask, + VIEW3D_MT_face_sets, + VIEW3D_MT_face_sets_init, VIEW3D_MT_particle, VIEW3D_MT_particle_context_menu, VIEW3D_MT_particle_showhide, @@ -7014,6 +7463,7 @@ classes = ( VIEW3D_MT_pose_group, VIEW3D_MT_pose_ik, VIEW3D_MT_pose_constraints, + VIEW3D_MT_pose_names, VIEW3D_MT_pose_showhide, VIEW3D_MT_pose_apply, VIEW3D_MT_pose_context_menu, @@ -7039,6 +7489,7 @@ classes = ( VIEW3D_MT_edit_mesh_clean, VIEW3D_MT_edit_mesh_delete, VIEW3D_MT_edit_mesh_merge, + VIEW3D_MT_edit_mesh_split, VIEW3D_MT_edit_mesh_showhide, VIEW3D_MT_paint_gpencil, VIEW3D_MT_assign_material, @@ -7048,6 +7499,7 @@ classes = ( VIEW3D_MT_edit_gpencil_delete, VIEW3D_MT_edit_gpencil_showhide, VIEW3D_MT_weight_gpencil, + VIEW3D_MT_vertex_gpencil, VIEW3D_MT_gpencil_animation, VIEW3D_MT_gpencil_simplify, VIEW3D_MT_gpencil_copy_layer, @@ -7062,7 +7514,10 @@ classes = ( VIEW3D_MT_edit_curve_showhide, VIEW3D_MT_edit_surface, VIEW3D_MT_edit_font, - VIEW3D_MT_edit_text_chars, + VIEW3D_MT_edit_font_chars, + VIEW3D_MT_edit_font_kerning, + VIEW3D_MT_edit_font_delete, + VIEW3D_MT_edit_font_context_menu, VIEW3D_MT_edit_meta, VIEW3D_MT_edit_meta_showhide, VIEW3D_MT_edit_lattice, @@ -7084,6 +7539,8 @@ classes = ( VIEW3D_MT_orientations_pie, VIEW3D_MT_proportional_editing_falloff_pie, VIEW3D_MT_sculpt_mask_edit_pie, + VIEW3D_MT_wpaint_vgroup_lock_pie, + VIEW3D_MT_sculpt_face_sets_edit_pie, VIEW3D_PT_active_tool, VIEW3D_PT_active_tool_duplicate, VIEW3D_PT_view3d_properties, @@ -7131,10 +7588,13 @@ classes = ( VIEW3D_PT_paint_vertex_context_menu, VIEW3D_PT_paint_texture_context_menu, VIEW3D_PT_paint_weight_context_menu, + VIEW3D_PT_gpencil_vertex_context_menu, VIEW3D_PT_gpencil_sculpt_context_menu, + VIEW3D_PT_gpencil_weight_context_menu, VIEW3D_PT_gpencil_draw_context_menu, VIEW3D_PT_sculpt_context_menu, TOPBAR_PT_gpencil_materials, + TOPBAR_PT_gpencil_vertexcolor, TOPBAR_PT_annotation_layers, ) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 19d5e3da309..83144b33c67 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -21,6 +21,7 @@ from bpy.types import Menu, Panel, UIList from bl_ui.properties_grease_pencil_common import ( GreasePencilSculptOptionsPanel, GreasePencilDisplayPanel, + GreasePencilBrushFalloff, ) from bl_ui.properties_paint_common import ( UnifiedPaintPanel, @@ -71,6 +72,33 @@ class VIEW3D_MT_brush_context_menu(Menu): layout.operator("brush.reset") +class VIEW3D_MT_brush_gpencil_context_menu(Menu): + bl_label = "Brush Specials" + + def draw(self, context): + layout = self.layout + ts = context.tool_settings + + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint + + brush = getattr(settings, "brush", None) + # skip if no active brush + if not brush: + layout.label(text="No Brushes currently available", icon='INFO') + return + + layout.operator("gpencil.brush_reset") + layout.operator("gpencil.brush_reset_all") + + class VIEW3D_MT_brush_context_menu_paint_modes(Menu): bl_label = "Enabled Modes" @@ -97,21 +125,15 @@ class View3DPanel: # Used by vertex & weight paint def draw_vpaint_symmetry(layout, vpaint): - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") + col = layout.column() + col.use_property_split = True + col.use_property_decorate = False - col = split.column() - row = col.row(align=True) + row = col.row(heading="Mirror", align=True) row.prop(vpaint, "use_symmetry_x", text="X", toggle=True) row.prop(vpaint, "use_symmetry_y", text="Y", toggle=True) row.prop(vpaint, "use_symmetry_z", text="Z", toggle=True) - col = layout.column() - col.use_property_split = True - col.use_property_decorate = False col.prop(vpaint, "radial_symmetry", text="Radial") @@ -151,10 +173,10 @@ class VIEW3D_PT_tools_object_options_transform(View3DPanel, Panel): tool_settings = context.tool_settings - layout.label(text="Affect Only") - layout.prop(tool_settings, "use_transform_data_origin", text="Origins") - layout.prop(tool_settings, "use_transform_pivot_point_align", text="Locations") - layout.prop(tool_settings, "use_transform_skip_children", text="Parents") + col = layout.column(heading="Affect Only", align=True) + col.prop(tool_settings, "use_transform_data_origin", text="Origins") + col.prop(tool_settings, "use_transform_pivot_point_align", text="Locations") + col.prop(tool_settings, "use_transform_skip_children", text="Parents") # ********** default tools for editmode_mesh **************** @@ -181,16 +203,11 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): split = layout.split() - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") - - col = split.column() - - row = col.row(align=True) - row.prop(mesh, "use_mirror_x", text="X", toggle=True) - row.prop(mesh, "use_mirror_y", text="Y", toggle=True) - row.prop(mesh, "use_mirror_z", text="Z", toggle=True) + row = layout.row(heading="Mirror") + sub = row.row(align=True) + sub.prop(mesh, "use_mirror_x", text="X", toggle=True) + sub.prop(mesh, "use_mirror_y", text="Y", toggle=True) + sub.prop(mesh, "use_mirror_z", text="Z", toggle=True) row = layout.row(align=True) row.active = ob.data.use_mirror_x or ob.data.use_mirror_y or ob.data.use_mirror_z @@ -226,62 +243,6 @@ class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel): col.prop(tool_settings, "use_mesh_automerge_and_split", toggle=False) col.prop(tool_settings, "double_threshold", text="Threshold") -# ********** default tools for editmode_curve **************** - - -class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel): - bl_category = "Tool" - bl_context = ".curve_edit" # dot on purpose (access from topbar) - bl_label = "Curve Stroke" - - def draw(self, context): - layout = self.layout - - tool_settings = context.tool_settings - cps = tool_settings.curve_paint_settings - - col = layout.column() - - col.prop(cps, "curve_type") - - if cps.curve_type == 'BEZIER': - col.label(text="Bezier Options:") - col.prop(cps, "error_threshold") - col.prop(cps, "fit_method") - col.prop(cps, "use_corners_detect") - - col = layout.column() - col.active = cps.use_corners_detect - col.prop(cps, "corner_angle") - - col.label(text="Pressure Radius:") - row = layout.row(align=True) - rowsub = row.row(align=True) - rowsub.prop(cps, "radius_min", text="Min") - rowsub.prop(cps, "radius_max", text="Max") - - row.prop(cps, "use_pressure_radius", text="", icon_only=True) - - col = layout.column() - col.label(text="Taper Radius:") - row = layout.row(align=True) - row.prop(cps, "radius_taper_start", text="Start") - row.prop(cps, "radius_taper_end", text="End") - - col = layout.column() - col.label(text="Projection Depth:") - row = layout.row(align=True) - row.prop(cps, "depth_mode", expand=True) - - col = layout.column() - if cps.depth_mode == 'SURFACE': - col.prop(cps, "surface_offset") - col.prop(cps, "use_offset_absolute") - col.prop(cps, "use_stroke_endpoints") - if cps.use_stroke_endpoints: - colsub = layout.column(align=True) - colsub.prop(cps, "surface_plane", expand=True) - # ********** default tools for editmode_armature **************** @@ -706,7 +667,7 @@ class VIEW3D_PT_tools_brush_falloff(Panel, View3DPaintPanel, FalloffPanel): class VIEW3D_PT_tools_brush_falloff_frontface(View3DPaintPanel, Panel): bl_context = ".imagepaint" # dot on purpose (access from topbar) - bl_label = "Frontface Falloff" + bl_label = "Front-face Falloff" bl_parent_id = "VIEW3D_PT_tools_brush_falloff" bl_options = {'DEFAULT_CLOSED'} @@ -810,38 +771,14 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel): sub.prop(sculpt, "detail_refine_method", text="Refine Method") sub.prop(sculpt, "detail_type_method", text="Detailing") - col.prop(sculpt, "use_smooth_shading") - - -class VIEW3D_PT_sculpt_dyntopo_remesh(Panel, View3DPaintPanel): - bl_context = ".sculpt_mode" # dot on purpose (access from topbar) - bl_label = "Remesh" - bl_parent_id = "VIEW3D_PT_sculpt_dyntopo" - bl_options = {'DEFAULT_CLOSED'} - bl_ui_units_x = 12 - - def draw(self, context): - layout = self.layout - layout.use_property_split = True - layout.use_property_decorate = False + if sculpt.detail_type_method in {'CONSTANT', 'MANUAL'}: + col.operator("sculpt.detail_flood_fill") - tool_settings = context.tool_settings - sculpt = tool_settings.sculpt + col.prop(sculpt, "use_smooth_shading") - col = layout.column() - col.active = context.sculpt_object.use_dynamic_topology_sculpting - col.prop(sculpt, "symmetrize_direction") - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - col = flow.column() - col.operator("sculpt.symmetrize") - col = flow.column() - col.operator("sculpt.optimize") - if sculpt.detail_type_method in {'CONSTANT', 'MANUAL'}: - col = flow.column() - col.operator("sculpt.detail_flood_fill") class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel): @@ -868,9 +805,13 @@ class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel): col.prop(mesh, "remesh_voxel_adaptivity") col.prop(mesh, "use_remesh_fix_poles") col.prop(mesh, "use_remesh_smooth_normals") - col.prop(mesh, "use_remesh_preserve_volume") - col.prop(mesh, "use_remesh_preserve_paint_mask") - col.operator("object.voxel_remesh", text="Remesh") + + col = layout.column(heading="Preserve", align=True) + col.prop(mesh, "use_remesh_preserve_volume", text="Volume") + col.prop(mesh, "use_remesh_preserve_paint_mask", text="Paint Mask") + col.prop(mesh, "use_remesh_preserve_sculpt_face_sets", text="Face Sets") + + layout.operator("object.voxel_remesh", text="Remesh") # TODO, move to space_view3d.py @@ -891,15 +832,20 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel): tool_settings = context.tool_settings sculpt = tool_settings.sculpt - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() + col = layout.column(heading="Display", align=True) col.prop(sculpt, "use_threaded", text="Threaded Sculpt") - col = flow.column() col.prop(sculpt, "show_low_resolution") - col = flow.column() + col.prop(sculpt, "use_sculpt_delay_updates") col.prop(sculpt, "use_deform_only") + col.separator() + + col = layout.column(heading="Auto-Masking", align=True) + col.prop(sculpt, "use_automasking_topology", text="Topology") + col.prop(sculpt, "use_automasking_face_sets", text="Face Sets") + col.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary") + col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary") + class VIEW3D_PT_sculpt_options_gravity(Panel, View3DPaintPanel): bl_context = ".sculpt_mode" # dot on purpose (access from topbar) @@ -941,54 +887,34 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False sculpt = context.tool_settings.sculpt - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") - - col = split.column() - - row = col.row(align=True) + row = layout.row(align=True, heading="Mirror") row.prop(sculpt, "use_symmetry_x", text="X", toggle=True) row.prop(sculpt, "use_symmetry_y", text="Y", toggle=True) row.prop(sculpt, "use_symmetry_z", text="Z", toggle=True) - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Lock") - - col = split.column() - - row = col.row(align=True) + row = layout.row(align=True, heading="Lock") row.prop(sculpt, "lock_x", text="X", toggle=True) row.prop(sculpt, "lock_y", text="Y", toggle=True) row.prop(sculpt, "lock_z", text="Z", toggle=True) - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Tiling") - - col = split.column() - - row = col.row(align=True) + row = layout.row(align=True, heading="Tiling") row.prop(sculpt, "tile_x", text="X", toggle=True) row.prop(sculpt, "tile_y", text="Y", toggle=True) row.prop(sculpt, "tile_z", text="Z", toggle=True) - layout.use_property_split = True - layout.use_property_decorate = False - layout.prop(sculpt, "use_symmetry_feather", text="Feather") - layout.column().prop(sculpt, "radial_symmetry", text="Radial") - layout.column().prop(sculpt, "tile_offset", text="Tile Offset") + layout.prop(sculpt, "radial_symmetry", text="Radial") + layout.prop(sculpt, "tile_offset", text="Tile Offset") + + layout.separator() + + layout.prop(sculpt, "symmetrize_direction") + layout.operator("sculpt.symmetrize") class VIEW3D_PT_sculpt_symmetry_for_topbar(Panel): @@ -1046,6 +972,7 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): col = layout.column() col.prop(tool_settings, "use_auto_normalize", text="Auto Normalize") + col.prop(tool_settings, "use_lock_relative", text="Lock-Relative") col.prop(tool_settings, "use_multipaint", text="Multi-Paint") col.prop(wpaint, "use_group_restrict") @@ -1190,19 +1117,14 @@ class VIEW3D_PT_tools_imagepaint_options(View3DPaintPanel, Panel): layout.prop(ipaint, "seam_bleed") layout.prop(ipaint, "dither", slider=True) - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() + col = layout.column() col.prop(ipaint, "use_occlude") - - col = flow.column() col.prop(ipaint, "use_backface_culling", text="Backface Culling") class VIEW3D_PT_tools_imagepaint_options_cavity(View3DPaintPanel, Panel): bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Cavity Mask" - bl_parent_id = "VIEW3D_PT_tools_imagepaint_options" bl_parent_id = "VIEW3D_PT_mask" bl_options = {'DEFAULT_CLOSED'} @@ -1356,7 +1278,7 @@ class VIEW3D_PT_tools_particlemode_options_display(View3DPanel, Panel): # Grease Pencil drawing brushes -class GreasePencilPanel: +class GreasePencilPaintPanel: bl_context = ".greasepencil_paint" bl_category = "Tool" @@ -1372,7 +1294,7 @@ class GreasePencilPanel: return True -class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePencilPanel): +class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePencilPaintPanel): bl_label = "Brushes" def draw(self, context): @@ -1387,7 +1309,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePenci row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) col = row.column() - col.operator("gpencil.brush_presets_create", icon='PRESET_NEW', text="") + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") if context.mode == 'PAINT_GPENCIL': brush = tool_settings.gpencil_paint.brush @@ -1400,8 +1322,9 @@ class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePenci layout.row().prop(brush, "icon_filepath", text="") -class VIEW3D_PT_tools_grease_pencil_brush_settings(Panel, View3DPanel, GreasePencilPanel): +class VIEW3D_PT_tools_grease_pencil_brush_settings(Panel, View3DPanel, GreasePencilPaintPanel): bl_label = "Brush Settings" + bl_options = {'DEFAULT_CLOSED'} # What is the point of brush presets? Seems to serve the exact same purpose as brushes themselves?? def draw_header_preset(self, _context): @@ -1448,7 +1371,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): @classmethod def poll(cls, context): brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool != 'ERASE' + return brush is not None and brush.gpencil_tool not in {'ERASE', 'TINT'} def draw(self, context): layout = self.layout @@ -1480,11 +1403,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): ma = brush.gpencil_settings.material col.separator() + col.prop(gp_settings, "hardness", slider=True) subcol = col.column(align=True) if ma and ma.grease_pencil.mode == 'LINE': subcol.enabled = False - subcol.prop(gp_settings, "gradient_factor", slider=True) - subcol.prop(gp_settings, "gradient_shape") + subcol.prop(gp_settings, "aspect") elif brush.gpencil_tool == 'FILL': row = col.row(align=True) @@ -1496,6 +1419,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): col.prop(gp_settings, "show_fill", text="Ignore Transparent Strokes") col.prop(gp_settings, "fill_threshold", text="Threshold") + class VIEW3D_PT_tools_grease_pencil_brush_stroke(Panel, View3DPanel): bl_context = ".greasepencil_paint" bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_settings' @@ -1562,7 +1486,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel): @classmethod def poll(cls, context): brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'} + return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'} def draw_header(self, context): if self.is_popover: @@ -1593,12 +1517,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel): col1.prop(gp_settings, "pen_smooth_steps") col1 = col.column(align=True) - col1.prop(gp_settings, "pen_thick_smooth_factor") - col1.prop(gp_settings, "pen_thick_smooth_steps", text="Iterations") - - col1 = col.column(align=True) col1.prop(gp_settings, "pen_subdivision_steps") - col1.prop(gp_settings, "random_subdiv", text="Randomness", slider=True) col1 = col.column(align=True) col1.prop(gp_settings, "simplify_factor") @@ -1617,7 +1536,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): @classmethod def poll(cls, context): brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'} + return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'} def draw_header(self, context): if self.is_popover: @@ -1632,7 +1551,9 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): layout.use_property_split = True layout.use_property_decorate = False - brush = context.tool_settings.gpencil_paint.brush + tool_settings = context.tool_settings + brush = tool_settings.gpencil_paint.brush + mode = tool_settings.gpencil_paint.color_mode gp_settings = brush.gpencil_settings if self.is_popover: @@ -1641,83 +1562,86 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): row.label(text=self.bl_label) col = layout.column() - col.active = gp_settings.use_settings_random - - col.prop(gp_settings, "random_pressure", text="Pressure", slider=True) - col.prop(gp_settings, "random_strength", text="Strength", slider=True) - col.prop(gp_settings, "uv_random", text="UV", slider=True) + col.enabled = gp_settings.use_settings_random row = col.row(align=True) - row.prop(gp_settings, "pen_jitter", slider=True) - row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') - - -# Grease Pencil drawingcurves -class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel): - bl_context = ".greasepencil_paint" - bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_settings' - bl_label = "Curves" - bl_category = "Tool" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'} - - def draw(self, context): - pass - - -class VIEW3D_PT_tools_grease_pencil_brushcurves_sensitivity(View3DPanel, Panel): - bl_context = ".greasepencil_paint" - bl_label = "Sensitivity" - bl_category = "Tool" - bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves" - - def draw(self, context): - layout = self.layout - layout.use_property_split = True + row.prop(gp_settings, "random_pressure", text="Radius", slider=True) + row.prop(gp_settings, "use_stroke_random_radius", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_radius", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_radius and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_random_pressure", brush=True, + use_negative_slope=True) - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings - - layout.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True, - use_negative_slope=True) + row = col.row(align=True) + row.prop(gp_settings, "random_strength", text="Strength", slider=True) + row.prop(gp_settings, "use_stroke_random_strength", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_strength", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_strength and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_random_strength", brush=True, + use_negative_slope=True) + row = col.row(align=True) + row.prop(gp_settings, "uv_random", text="UV", slider=True) + row.prop(gp_settings, "use_stroke_random_uv", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_uv", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_uv and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_random_uv", brush=True, + use_negative_slope=True) -class VIEW3D_PT_tools_grease_pencil_brushcurves_strength(View3DPanel, Panel): - bl_context = ".greasepencil_paint" - bl_label = "Strength" - bl_category = "Tool" - bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves" + col.separator() - def draw(self, context): - layout = self.layout - layout.use_property_split = True + col1 = col.column(align=True) + col1.enabled = mode == 'VERTEXCOLOR' and gp_settings.use_settings_random + row = col1.row(align=True) + row.prop(gp_settings, "random_hue_factor", slider=True) + row.prop(gp_settings, "use_stroke_random_hue", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_hue", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_hue and self.is_popover is False: + col1.template_curve_mapping(gp_settings, "curve_random_hue", brush=True, + use_negative_slope=True) + + row = col1.row(align=True) + row.prop(gp_settings, "random_saturation_factor", slider=True) + row.prop(gp_settings, "use_stroke_random_sat", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_sat", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_sat and self.is_popover is False: + col1.template_curve_mapping(gp_settings, "curve_random_saturation", brush=True, + use_negative_slope=True) + + row = col1.row(align=True) + row.prop(gp_settings, "random_value_factor", slider=True) + row.prop(gp_settings, "use_stroke_random_val", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_val", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_val and self.is_popover is False: + col1.template_curve_mapping(gp_settings, "curve_random_value", brush=True, + use_negative_slope=True) - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings + col.separator() - layout.template_curve_mapping(gp_settings, "curve_strength", brush=True, - use_negative_slope=True) + row = col.row(align=True) + row.prop(gp_settings, "pen_jitter", slider=True) + row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_jitter_pressure and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_jitter", brush=True, + use_negative_slope=True) -class VIEW3D_PT_tools_grease_pencil_brushcurves_jitter(View3DPanel, Panel): +class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): bl_context = ".greasepencil_paint" - bl_label = "Jitter" - bl_category = "Tool" - bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} - def draw(self, context): - layout = self.layout - layout.use_property_split = True + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + if brush is None: + return False - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings + tool = brush.gpencil_tool - layout.template_curve_mapping(gp_settings, "curve_jitter", brush=True, - use_negative_slope=True) + return (settings and settings.brush and settings.brush.curve and tool == 'TINT') # Grease Pencil stroke interpolation tools @@ -1768,25 +1692,49 @@ class VIEW3D_PT_tools_grease_pencil_interpolate(Panel): # Grease Pencil stroke sculpting tools - -class VIEW3D_PT_tools_grease_pencil_sculpt_select(Panel, View3DPanel): +class GreasePencilSculptPanel: bl_context = ".greasepencil_sculpt" - bl_label = "Brushes" bl_category = "Tool" + @classmethod + def poll(cls, context): + if context.space_data.type in ('VIEW_3D', 'PROPERTIES'): + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(gpd.is_stroke_sculpt_mode) + else: + return True + + +class VIEW3D_PT_tools_grease_pencil_sculpt_select(Panel, View3DPanel, GreasePencilSculptPanel): + bl_label = "Brushes" + def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False - settings = context.tool_settings.gpencil_sculpt + tool_settings = context.scene.tool_settings + gpencil_paint = tool_settings.gpencil_sculpt_paint - layout.template_icon_view(settings, "sculpt_tool", show_labels=True) + row = layout.row() + row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) + col = row.column() + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") -class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel): - bl_context = ".greasepencil_sculpt" - bl_category = "Tool" + if context.mode == 'SCULPT_GPENCIL': + brush = tool_settings.gpencil_sculpt_paint.brush + if brush is not None: + col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="") + + if(brush.use_custom_icon): + layout.row().prop(brush, "icon_filepath", text="") + + +class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel, GreasePencilSculptPanel): bl_label = "Brush Settings" def draw(self, context): @@ -1794,7 +1742,8 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel): layout.use_property_split = True layout.use_property_decorate = False - settings = context.tool_settings.gpencil_sculpt + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_sculpt_paint brush = settings.brush if not self.is_popover: @@ -1803,27 +1752,63 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel): ) brush_basic_gpencil_sculpt_settings(layout, context, brush) -# Grease Pencil weight painting tools +class VIEW3D_PT_tools_grease_pencil_brush_sculpt_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): + bl_context = ".greasepencil_sculpt" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_sculpt_paint + return (settings and settings.brush and settings.brush.curve) -class VIEW3D_PT_tools_grease_pencil_weight_paint_select(View3DPanel, Panel): + +# Grease Pencil weight painting tools +class GreasePencilWeightPanel: bl_context = ".greasepencil_weight" - bl_label = "Brushes" bl_category = "Tool" + @classmethod + def poll(cls, context): + if context.space_data.type in ('VIEW_3D', 'PROPERTIES'): + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(gpd.is_stroke_weight_mode) + else: + return True + + +class VIEW3D_PT_tools_grease_pencil_weight_paint_select(View3DPanel, Panel, GreasePencilWeightPanel): + bl_label = "Brushes" + def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False - settings = context.tool_settings.gpencil_sculpt + tool_settings = context.scene.tool_settings + gpencil_paint = tool_settings.gpencil_weight_paint - layout.template_icon_view(settings, "weight_tool", show_labels=True) + row = layout.row() + row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) + col = row.column() + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") -class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel): - bl_context = ".greasepencil_weight" - bl_category = "Tool" + if context.mode == 'WEIGHT_GPENCIL': + brush = tool_settings.gpencil_weight_paint.brush + if brush is not None: + col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="") + + if(brush.use_custom_icon): + layout.row().prop(brush, "icon_filepath", text="") + + +class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel, GreasePencilWeightPanel): bl_label = "Brush Settings" def draw(self, context): @@ -1831,7 +1816,8 @@ class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel): layout.use_property_split = True layout.use_property_decorate = False - settings = context.tool_settings.gpencil_sculpt + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_weight_paint brush = settings.brush if not self.is_popover: @@ -1841,6 +1827,268 @@ class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel): brush_basic_gpencil_weight_settings(layout, context, brush) +class VIEW3D_PT_tools_grease_pencil_brush_weight_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): + bl_context = ".greasepencil_weight" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_weight_paint + brush = settings.brush + return (settings and settings.brush and settings.brush.curve) + + +# Grease Pencil vertex painting tools +class GreasePencilVertexPanel: + bl_context = ".greasepencil_vertex" + bl_category = "Tool" + + @classmethod + def poll(cls, context): + if context.space_data.type in ('VIEW_3D', 'PROPERTIES'): + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(gpd.is_stroke_vertex_mode) + else: + return True + + +class VIEW3D_PT_tools_grease_pencil_vertex_paint_select(View3DPanel, Panel, GreasePencilVertexPanel): + bl_label = "Brushes" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + tool_settings = context.scene.tool_settings + gpencil_paint = tool_settings.gpencil_vertex_paint + + row = layout.row() + row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) + + col = row.column() + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") + + if context.mode == 'VERTEX_GPENCIL': + brush = tool_settings.gpencil_vertex_paint.brush + if brush is not None: + col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="") + + if(brush.use_custom_icon): + layout.row().prop(brush, "icon_filepath", text="") + + +class VIEW3D_PT_tools_grease_pencil_vertex_paint_settings(Panel, View3DPanel, GreasePencilVertexPanel): + bl_label = "Brush Settings" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_vertex_paint + brush = settings.brush + + if not self.is_popover: + from bl_ui.properties_paint_common import ( + brush_basic_gpencil_vertex_settings, + ) + brush_basic_gpencil_vertex_settings(layout, context, brush) + + +class VIEW3D_PT_tools_grease_pencil_brush_vertex_color(View3DPanel, Panel): + bl_context = ".greasepencil_vertex" + bl_label = "Color" + bl_category = "Tool" + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if context.region.type == 'TOOL_HEADER' or brush.gpencil_vertex_tool in {'BLUR', 'AVERAGE', 'SMEAR'}: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + gp_settings = brush.gpencil_settings + + col = layout.column() + + col.template_color_picker(brush, "color", value_slider=True) + + sub_row = col.row(align=True) + sub_row.prop(brush, "color", text="") + sub_row.prop(brush, "secondary_color", text="") + + sub_row.operator("gpencil.tint_flip", icon='FILE_REFRESH', text="") + + +class VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): + bl_context = ".greasepencil_vertex" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + return (settings and settings.brush and settings.brush.curve) + + +class VIEW3D_PT_tools_grease_pencil_brush_vertex_palette(View3DPanel, Panel): + bl_context = ".greasepencil_vertex" + bl_label = "Palette" + bl_category = "Tool" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_vertex_color' + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if brush.gpencil_vertex_tool in {'BLUR', 'AVERAGE', 'SMEAR'}: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + + col = layout.column() + + row = col.row(align=True) + row.template_ID(settings, "palette", new="palette.new") + if settings.palette: + col.template_palette(settings, "palette", color=True) + + +class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Color" + bl_category = "Tool" + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if context.region.type == 'TOOL_HEADER': + return False + + if brush.gpencil_tool == 'TINT': + return True + + if brush.gpencil_tool not in {'DRAW', 'FILL'}: + return False + + return True + + def draw(self, context): + layout = self.layout + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + gp_settings = brush.gpencil_settings + + if brush.gpencil_tool != 'TINT': + row = layout.row() + row.prop(settings, "color_mode", expand=True) + + layout.use_property_split = True + layout.use_property_decorate = False + col = layout.column() + col.enabled = settings.color_mode == 'VERTEXCOLOR' or brush.gpencil_tool == 'TINT' + + col.template_color_picker(brush, "color", value_slider=True) + + sub_row = col.row(align=True) + sub_row.prop(brush, "color", text="") + sub_row.prop(brush, "secondary_color", text="") + + sub_row.operator("gpencil.tint_flip", icon='FILE_REFRESH', text="") + + if brush.gpencil_tool in {'DRAW', 'FILL'}: + col.prop(gp_settings, "vertex_mode", text="Mode") + col.prop(gp_settings, "vertex_color_factor", slider=True, text="Mix Factor") + + if brush.gpencil_tool == 'TINT': + col.prop(gp_settings, "vertex_mode", text="Mode") + + +class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Palette" + bl_category = "Tool" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_mixcolor' + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if brush.gpencil_tool == 'TINT': + return True + + if brush.gpencil_tool not in {'DRAW', 'FILL'}: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + + col = layout.column() + col.enabled = settings.color_mode == 'VERTEXCOLOR' or brush.gpencil_tool == 'TINT' + + row = col.row(align=True) + row.template_ID(settings, "palette", new="palette.new") + if settings.palette: + col.template_palette(settings, "palette", color=True) + + class VIEW3D_PT_tools_grease_pencil_sculpt_options(GreasePencilSculptOptionsPanel, Panel, View3DPanel): bl_context = ".greasepencil_sculpt" bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_sculpt_settings' @@ -1870,6 +2118,13 @@ class VIEW3D_PT_tools_grease_pencil_weight_appearance(GreasePencilDisplayPanel, bl_label = "Cursor" +class VIEW3D_PT_tools_grease_pencil_vertex_appearance(GreasePencilDisplayPanel, Panel, View3DPanel): + bl_context = ".greasepencil_vertex" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_vertex_paint_settings' + bl_category = "Tool" + bl_label = "Cursor" + + class VIEW3D_PT_gpencil_brush_presets(Panel, PresetPanel): """Brush settings""" bl_label = "Brush Presets" @@ -1880,15 +2135,15 @@ class VIEW3D_PT_gpencil_brush_presets(Panel, PresetPanel): classes = ( VIEW3D_MT_brush_context_menu, + VIEW3D_MT_brush_gpencil_context_menu, VIEW3D_MT_brush_context_menu_paint_modes, VIEW3D_PT_tools_object_options, VIEW3D_PT_tools_object_options_transform, VIEW3D_PT_tools_meshedit_options, VIEW3D_PT_tools_meshedit_options_automerge, - VIEW3D_PT_tools_curveedit_options_stroke, VIEW3D_PT_tools_armatureedit_options, VIEW3D_PT_tools_posemode_options, - + VIEW3D_PT_slots_projectpaint, VIEW3D_PT_tools_brush_select, VIEW3D_PT_tools_brush_settings, @@ -1908,7 +2163,6 @@ classes = ( VIEW3D_PT_tools_brush_display, VIEW3D_PT_sculpt_dyntopo, - VIEW3D_PT_sculpt_dyntopo_remesh, VIEW3D_PT_sculpt_voxel_remesh, VIEW3D_PT_sculpt_symmetry, VIEW3D_PT_sculpt_symmetry_for_topbar, @@ -1929,7 +2183,7 @@ classes = ( VIEW3D_PT_tools_imagepaint_symmetry, VIEW3D_PT_tools_imagepaint_options, - + VIEW3D_PT_tools_imagepaint_options_external, VIEW3D_MT_tools_projectpaint_stencil, @@ -1946,10 +2200,6 @@ classes = ( VIEW3D_PT_tools_grease_pencil_brush_post_processing, VIEW3D_PT_tools_grease_pencil_brush_random, VIEW3D_PT_tools_grease_pencil_brush_stabilizer, - VIEW3D_PT_tools_grease_pencil_brushcurves, - VIEW3D_PT_tools_grease_pencil_brushcurves_sensitivity, - VIEW3D_PT_tools_grease_pencil_brushcurves_strength, - VIEW3D_PT_tools_grease_pencil_brushcurves_jitter, VIEW3D_PT_tools_grease_pencil_paint_appearance, VIEW3D_PT_tools_grease_pencil_sculpt_select, VIEW3D_PT_tools_grease_pencil_sculpt_settings, @@ -1958,7 +2208,19 @@ classes = ( VIEW3D_PT_tools_grease_pencil_weight_paint_select, VIEW3D_PT_tools_grease_pencil_weight_paint_settings, VIEW3D_PT_tools_grease_pencil_weight_appearance, + VIEW3D_PT_tools_grease_pencil_vertex_paint_select, + VIEW3D_PT_tools_grease_pencil_vertex_paint_settings, + VIEW3D_PT_tools_grease_pencil_vertex_appearance, VIEW3D_PT_tools_grease_pencil_interpolate, + VIEW3D_PT_tools_grease_pencil_brush_mixcolor, + VIEW3D_PT_tools_grease_pencil_brush_mix_palette, + + VIEW3D_PT_tools_grease_pencil_brush_paint_falloff, + VIEW3D_PT_tools_grease_pencil_brush_sculpt_falloff, + VIEW3D_PT_tools_grease_pencil_brush_weight_falloff, + VIEW3D_PT_tools_grease_pencil_brush_vertex_color, + VIEW3D_PT_tools_grease_pencil_brush_vertex_palette, + VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index d9a374503b3..2dc6c6cd409 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -58,6 +58,13 @@ class TextureNodeCategory(SortedNodeCategory): context.space_data.tree_type == 'TextureNodeTree') +class SimulationNodeCategory(SortedNodeCategory): + @classmethod + def poll(cls, context): + return (context.space_data.type == 'NODE_EDITOR' and + context.space_data.tree_type == 'SimulationNodeTree') + + # menu entry for node group tools def group_tools_draw(self, layout, context): layout.operator("node.group_make") @@ -70,10 +77,11 @@ node_tree_group_type = { 'CompositorNodeTree': 'CompositorNodeGroup', 'ShaderNodeTree': 'ShaderNodeGroup', 'TextureNodeTree': 'TextureNodeGroup', + 'SimulationNodeTree': 'SimulationNodeGroup', } -# generic node group items generator for shader, compositor and texture node groups +# generic node group items generator for shader, compositor, simulation and texture node groups def node_group_items(context): if context is None: return @@ -264,6 +272,7 @@ shader_node_categories = [ NodeItem("ShaderNodeNormalMap"), NodeItem("ShaderNodeNormal"), NodeItem("ShaderNodeVectorCurve"), + NodeItem("ShaderNodeVectorRotate"), NodeItem("ShaderNodeVectorTransform"), ]), ShaderNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[ @@ -466,17 +475,81 @@ texture_node_categories = [ ]), ] +simulation_node_categories = [ + # Simulation Nodes + SimulationNodeCategory("SIM_OUTPUT", "Output", items=[ + NodeItem("SimulationNodeParticleSimulation"), + ]), + SimulationNodeCategory("SIM_INPUTS", "Input", items=[ + NodeItem("SimulationNodeTime"), + NodeItem("SimulationNodeParticleAttribute"), + NodeItem("FunctionNodeGroupInstanceID"), + ]), + SimulationNodeCategory("SIM_EMITTERS", "Emitters", items=[ + NodeItem("SimulationNodeParticleMeshEmitter"), + NodeItem("SimulationNodeEmitParticles"), + ]), + SimulationNodeCategory("SIM_EVENTS", "Events", items=[ + NodeItem("SimulationNodeParticleBirthEvent"), + NodeItem("SimulationNodeParticleTimeStepEvent"), + NodeItem("SimulationNodeParticleMeshCollisionEvent"), + ]), + SimulationNodeCategory("SIM_FORCES", "Forces", items=[ + NodeItem("SimulationNodeForce"), + ]), + SimulationNodeCategory("SIM_EXECUTE", "Execute", items=[ + NodeItem("SimulationNodeSetParticleAttribute"), + NodeItem("SimulationNodeExecuteCondition"), + NodeItem("SimulationNodeMultiExecute"), + ]), + SimulationNodeCategory("SIM_NOISE", "Noise", items=[ + NodeItem("ShaderNodeTexNoise"), + NodeItem("ShaderNodeTexWhiteNoise"), + ]), + SimulationNodeCategory("SIM_COLOR", "Color", items=[ + NodeItem("ShaderNodeMixRGB"), + NodeItem("ShaderNodeInvert"), + NodeItem("ShaderNodeHueSaturation"), + NodeItem("ShaderNodeGamma"), + NodeItem("ShaderNodeBrightContrast"), + ]), + SimulationNodeCategory("SIM_CONVERTER", "Converter", items=[ + NodeItem("ShaderNodeMapRange"), + NodeItem("ShaderNodeClamp"), + NodeItem("ShaderNodeMath"), + NodeItem("ShaderNodeValToRGB"), + NodeItem("ShaderNodeVectorMath"), + NodeItem("ShaderNodeSeparateRGB"), + NodeItem("ShaderNodeCombineRGB"), + NodeItem("ShaderNodeSeparateXYZ"), + NodeItem("ShaderNodeCombineXYZ"), + NodeItem("ShaderNodeSeparateHSV"), + NodeItem("ShaderNodeCombineHSV"), + NodeItem("FunctionNodeBooleanMath"), + NodeItem("FunctionNodeFloatCompare"), + NodeItem("FunctionNodeSwitch"), + NodeItem("FunctionNodeCombineStrings"), + ]), + SimulationNodeCategory("SIM_GROUP", "Group", items=node_group_items), + SimulationNodeCategory("SIM_LAYOUT", "Layout", items=[ + NodeItem("NodeFrame"), + NodeItem("NodeReroute"), + ]), +] + def register(): nodeitems_utils.register_node_categories('SHADER', shader_node_categories) nodeitems_utils.register_node_categories('COMPOSITING', compositor_node_categories) nodeitems_utils.register_node_categories('TEXTURE', texture_node_categories) + nodeitems_utils.register_node_categories('SIMULATION', simulation_node_categories) def unregister(): nodeitems_utils.unregister_node_categories('SHADER') nodeitems_utils.unregister_node_categories('COMPOSITING') nodeitems_utils.unregister_node_categories('TEXTURE') + nodeitems_utils.unregister_node_categories('SIMULATION') if __name__ == "__main__": diff --git a/release/scripts/templates_py/addon_add_object.py b/release/scripts/templates_py/addon_add_object.py index 47997069cbb..05a713b76b0 100644 --- a/release/scripts/templates_py/addon_add_object.py +++ b/release/scripts/templates_py/addon_add_object.py @@ -6,7 +6,7 @@ bl_info = { "location": "View3D > Add > Mesh > New Object", "description": "Adds a new Mesh Object", "warning": "", - "wiki_url": "", + "doc_url": "", "category": "Add Mesh", } |