Geometry Nodes: Matrix socket type, attribute type, and initial nodes #116166

Merged
Hans Goudey merged 47 commits from HooglyBoogly/blender:nodes-matrix-socket into main 2024-02-13 18:59:46 +01:00
395 changed files with 4462 additions and 1807 deletions
Showing only changes of commit 6c65267f79 - Show all commits

30
AUTHORS
View File

@ -20,7 +20,9 @@
# python ./tools/utils/authors_git_gen.py
# BEGIN individuals section.
20kdc <asdd2808@gmail.com>
Aaron Carlisle <carlisle.aaron00@gmail.com>
Aaron Franke <arnfranke@yahoo.com>
Adam Nydahl <Loginer>
Adi Sage <adisage.connect@gmail.com>
Aditya Y Jeppu <quantimoney>
@ -48,6 +50,7 @@ Alexander Kuznetsov <kuzsasha@gmail.com>
Alexander Pinzon <apinzonf@gmail.com>
Alexander Revkov <arevkov>
Alexander Romanov <a.romanov@blend4web.com>
Alexander Wilms <alexanderwilms@noreply.localhost>
Alexandr Kuznetsov <ak3636@nyu.edu>
Aleš Jelovčan <frogstomp>
Alfredo de Greef <eeshlo@yahoo.com>
@ -63,6 +66,7 @@ Andrea Beconcini <beco>
Andrea Weikert <elubie@gmx.net>
Andreas Bergmeier <abergmeier>
Andrej730 <azhilenkov@gmail.com>
Andres Stephens <ondraise15@hotmail.com>
Andrew Buttery <axb2035@gmail.com>
Andrew Hale <TrumanBlending@gmail.com>
Andrew Oates <aoates>
@ -139,6 +143,7 @@ Christoph Lendenfeld <chris.lenden@gmail.com>
Christophe Hery <chery>
Christopher Peerman <chris_82>
Cian Jinks <cjinks99@gmail.com>
Clément Busschaert <clement.busschaert@gmail.com>
Clément Foucault <foucault.clem@gmail.com>
Cody Winchester <CodyWinch>
Colby Klein <shakesoda>
@ -150,6 +155,7 @@ Cyrax <cyrax.iiit@gmail.com>
Cédric Paille <cedricp>
D. O <Likkez>
D.J. Capelis <blender@capelis.dj>
Daiki Hashimoto <daisea3e1203@gmail.com>
Daisuke Takahashi <noreply@blender.org>
Dalai Felinto <dalai@blender.org>
Damien Dh <damdhe>
@ -190,6 +196,7 @@ Dontsov Valentin <@blend4web.com>
Dorian <BD3D>
Doug Hammond <doughammond@hamsterfight.co.uk>
Douglas Paul <douglas.w.paul@gmail.com>
Dyvine57 <dulana57@gmail.com>
Ed Halley <ed@halley.cc>
Edgar Roman Cervantes <redvant>
Edmund Kapusniak <edmundmk>
@ -206,6 +213,7 @@ Erik Abrahamsson <ecke101@gmail.com>
Ervin Weber <ervin.weber@gmail.com>
Erwin Coumans <blender@erwincoumans.com>
Ethan Hall <Ethan1080>
Eugene Kuznetsov <eugene.kuznetsov@amd.com>
Evan Wilson <EAW>
Fabian Schempp <fabianschempp@googlemail.com>
Fabrício Luis <ce3po>
@ -314,6 +322,7 @@ Johannes Meng <info@jmeng.de>
John Quillan <jquillan>
Johnny Matthews <johnny.matthews@gmail.com>
Joilnen Leite <joilnen.leite@gmail.com>
Jonas Holzman <jonas@holzman.fr>
Jonathan Williamson <jonathan@cgcookie.com>
Jorge Bernal <jbernalmartinez@gmail.com>
Jorijn de Graaf <bonj@noreply.localhost>
@ -333,10 +342,12 @@ Juanfran Matheu <jfmatheu>
Juha Mäki-Kanto <ih5235252@gmail.com>
Juho Vepsalainen <bebraw@gmail.com>
Julian Eisel <julian@blender.org>
Julian Plak <julian.plak@live.nl>
Julian Squires <julian@cipht.net>
Julien Kaspar <julien@blender.org>
Jun Mizutani <jmztn@noreply.localhost>
Jung Jaeyun <cube-c>
Jure Triglav <juretriglav@gmail.com>
Justin Dailey <dail8859@yahoo.com>
Justin Jones <jjones780>
Jörg Müller <nexyon@gmail.com>
@ -352,6 +363,7 @@ Keith Boshoff <wahooney>
Ken Hughes <khughes@pacific.edu>
Kenneth Perry <thothonegan>
Kent Mein <mein@cs.umn.edu>
Kenzie <kenziemac130@noreply.localhost>
Kester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Kevin Buhr <buhr>
Kevin C. Burke <kevincburke@noreply.localhost>
@ -365,7 +377,6 @@ Kris <Metricity>
Krzysztof Recko <yetioszek@gmail.com>
Kévin Dietrich <kevin.dietrich@mailoo.org>
L. E. Segovia <leonardo.segovia@cs.uns.edu.ar>
Laurynas Duburas <laurynas>
Lawrence D'Oliveiro <from-blender@geek-central.gen.nz>
Leha <leha>
Leon Schittek <leon.schittek@gmx.net>
@ -399,6 +410,7 @@ Manuel Castilla <manzanillawork@gmail.com>
Marc Chehab <marcchehab@protonmail.ch>
Marc Freixas <mfreixas@lsi.upc.edu>
Marcelo Demian Gómez <mdemiang>
Marcelo Mutzbauer <1xundoredo@gmail.com>
Marco <nacioss>
Marcos Perez <pistolario>
Marino Toscano <marino.toscano@gmail.com>
@ -455,7 +467,7 @@ Mikkel Gjoel <mikkelgjoel>
Milan Davidović <milan.davidovic@protonmail.com>
Milan Jaros <jar091>
Mitchell Stokes <mogurijin@gmail.com>
Monique Dewanchand <m.dewanchand@atmind.nl>
Monique Dewanchand <mdewanchand@atmind.nl>
Moritz Röhrich <ildefons>
Morten Mikkelsen <mikkelsen7@gmail.com>
Myles Walcott <myles_walcott>
@ -484,9 +496,11 @@ Olivier Jolly <zeograd>
Olivier Maury <omaury>
Omar Emara <mail@OmarEmara.dev>
Ove Murberg Henriksen <sorayasilvermoon@hotmail.com>
Pablo Delgado Krämer <private@pablode.com>
Pablo Dobarro <pablodp606@gmail.com>
Pablo Vazquez <pablo@blender.org>
Paolo Acampora <pkrime>
Paolo Amadini <paolo.blender.dev@amadzone.org>
Pascal Schoen <pascal.schoen@adidas-group.com>
Patrick Bender <ichbinkeinreh>
Patrick Busch <xylvier@noreply.localhost>
@ -521,11 +535,11 @@ Pierre Risch <prisch>
Piotr Makal <pmakal>
Piotr Ostrowski <postrowski>
Pratik Borhade <pratikborhade302@gmail.com>
Prikshit singh <prikshitsingh79@gmail.com>
Quentin Wenger <matpi@protonmail.ch>
RUben <KUbo_0>
Rahul Chaudhary <RC12>
Raimund Klink <raimund58@noreply.localhost>
Rajesh Advani <rajeshja>
Ralf Hölzemer <r.hoelzemer@googlemail.com>
Ramil Roosileht <Limarest>
Rateeb Riyasat <bmollusc>
@ -591,6 +605,7 @@ Sonny Campbell <sonny.campbell@unity3d.com>
Sriharsha Kotcharlakot <k.venkatsriharsha@gmail.com>
Stanislav Blinov <radcapricorn>
Stefan Gartner <stefang@aon.at>
Stefan Heinz <stefanh@noreply.localhost>
Stefan Werner <stefan.werner@intel.com>
Stefano Bonicatti <smjert>
Stephan Seitz <theHamsta>
@ -599,7 +614,7 @@ Stephen Seo <seodisparate>
Stephen Swaney <sswaney@centurytel.net>
Stuart Broadfoot <gbroadfoot@hotmail.com>
Sukhitha Prabhath Jayathilake <pr.jayathilake@gmail.com>
Sun Kim <persun@noreply.localhost>
Sun Kim <perplexing.sun@gmail.com>
Sv. Lockal <lockalsash@gmail.com>
Sybren A. Stüvel <sybren@blender.org>
Szymon Ulatowski <szulat>
@ -649,7 +664,7 @@ Vitor Boschi <vitorboschi@gmail.com>
Vuk Gardašević <lijenstina>
Wael El Oraiby <wael.eloraiby@gmail.com>
Walid Shouman <eng.walidshouman@gmail.com>
Wannes Malfait <Wannes>
Wannes Malfait <wannes.malfait@gmail.com>
Wayde Moss <wbmoss_dev@yahoo.com>
Weikang Qiu <qiuweikang1999@gmail.com>
Weizhen Huang <weizhen@blender.org>
@ -674,19 +689,23 @@ Yonatan Maor <yon.maor@gmail.com>
Yuki Hashimoto <hzuika>
Yuki Shirakawa <shirakawa>
Yuntoko <yuntokon@gmail.com>
Z-Map <blendfan@gmail.com>
Zev Eisenberg <ZevEisenberg>
Zijun Zhou <eary@noreply.localhost>
andreas atteneder <atti>
ariva00 <ariva00.it@gmail.com>
b-init <b-init>
bird_d <bird_d>
brunoT <drehuwann@gmail.com>
cgtinker <Denys.Hsu@gmail.com>
coyo_t <constachugga@gmail.com>
dupoxy <dupoxy@noreply.localhost>
fiord <hyoga_quasar@yahoo.co.jp>
himisa <himisa@noreply.localhost>
jim man <jimman2003>
jon denning <gfxcoder@gmail.com>
kiki <charles@skeletalstudios.com>
laurynas <laduem@gmail.com>
listout <listout@protonmail.com>
lolloz98 <lorenzocarpaneto@yahoo.it>
luzpaz <luzpaz>
@ -697,6 +716,7 @@ nBurn <nbwashburn@gmail.com>
nutti <nutti.metro@gmail.com>
ok_what <ip1149a@gmail.com>
persun <perplexing.sun@gmail.com>
rajveermalviya <rajveer0malviya@gmail.com>
swann <slumber>
unclezeiv <davide.vercelli@gmail.com>
yves <valfeur>

View File

@ -199,11 +199,6 @@ ifndef DEPS_INSTALL_DIR
endif
endif
# Allow to use alternative binary (pypy3, etc)
ifndef PYTHON
PYTHON:=python3
endif
# Set the LIBDIR, an empty string when not found.
LIBDIR:=$(wildcard ../lib/${OS_NCASE}_${CPU})
ifeq (, $(LIBDIR))
@ -215,24 +210,29 @@ endif
# Find the newest Python version bundled in `LIBDIR`.
PY_LIB_VERSION:=3.15
ifeq (, $(wildcard $(LIBDIR)/python/lib/python$(PY_LIB_VERSION)))
ifeq (, $(wildcard $(LIBDIR)/python/bin/python$(PY_LIB_VERSION)))
PY_LIB_VERSION:=3.14
ifeq (, $(wildcard $(LIBDIR)/python/lib/python$(PY_LIB_VERSION)))
ifeq (, $(wildcard $(LIBDIR)/python/bin/python$(PY_LIB_VERSION)))
PY_LIB_VERSION:=3.13
ifeq (, $(wildcard $(LIBDIR)/python/lib/python$(PY_LIB_VERSION)))
ifeq (, $(wildcard $(LIBDIR)/python/bin/python$(PY_LIB_VERSION)))
PY_LIB_VERSION:=3.12
ifeq (, $(wildcard $(LIBDIR)/python/lib/python$(PY_LIB_VERSION)))
ifeq (, $(wildcard $(LIBDIR)/python/bin/python$(PY_LIB_VERSION)))
PY_LIB_VERSION:=3.11
ifeq (, $(wildcard $(LIBDIR)/python/bin/python$(PY_LIB_VERSION)))
PY_LIB_VERSION:=3.10
endif
endif
endif
endif
endif
# For macOS python3 is not installed by default, so fallback to python binary
# in libraries, or python 2 for running make update to get it.
ifeq ($(OS_NCASE),darwin)
ifeq (, $(shell command -v $(PYTHON)))
PYTHON:=$(LIBDIR)/python/bin/python$(PY_LIB_VERSION)
# Allow to use alternative binary (pypy3, etc)
ifndef PYTHON
# If not overriden, first try using Python from LIBDIR.
PYTHON:=$(LIBDIR)/python/bin/python$(PY_LIB_VERSION)
ifeq (, $(PYTHON))
# If not available, use system python3 or python command.
PYTHON:=python3
ifeq (, $(shell command -v $(PYTHON)))
PYTHON:=python
endif

View File

@ -158,12 +158,13 @@ def build_info(
del args_orig
# join args incase they are not.
args = ' '.join(args)
args = args.replace(" -isystem", " -I")
args = args.replace(" -D ", " -D")
args = args.replace(" -I ", " -I")
args_str = " ".join(args)
args_str = args_str.replace(" -isystem", " -I")
args_str = args_str.replace(" -D ", " -D")
args_str = args_str.replace(" -I ", " -I")
args = shlex.split(args)
args = shlex.split(args_str)
del args_str
# end
# remove compiler

View File

@ -16,7 +16,7 @@ from bpy.props import (
)
from bpy.app.translations import (
contexts as i18n_contexts,
pgettext_iface as iface_
pgettext_rpt as rpt_
)
from math import pi
@ -1602,50 +1602,62 @@ class CyclesPreferences(bpy.types.AddonPreferences):
if not found_device:
col = box.column(align=True)
col.label(text="No compatible GPUs found for Cycles", icon='INFO')
col.label(text=rpt_("No compatible GPUs found for Cycles"), icon='INFO', translate=False)
if device_type == 'CUDA':
compute_capability = "3.0"
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
col.label(text=rpt_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
icon='BLANK1', translate=False)
elif device_type == 'OPTIX':
compute_capability = "5.0"
driver_version = "470"
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
col.label(text=rpt_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
icon='BLANK1', translate=False)
col.label(text=iface_("and NVIDIA driver version %s or newer") % driver_version,
col.label(text=rpt_("and NVIDIA driver version %s or newer") % driver_version,
icon='BLANK1', translate=False)
elif device_type == 'HIP':
import sys
if sys.platform[:3] == "win":
driver_version = "21.Q4"
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
col.label(
text=rpt_("Requires AMD GPU with Vega or RDNA architecture"),
icon='BLANK1',
translate=False)
col.label(text=rpt_("and AMD Radeon Pro %s driver or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
driver_version = "22.10"
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
col.label(
text=rpt_("Requires AMD GPU with Vega or RDNA architecture"),
icon='BLANK1',
translate=False)
col.label(text=rpt_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
translate=False)
elif device_type == 'ONEAPI':
import sys
if sys.platform.startswith("win"):
driver_version = "XX.X.101.4824"
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
col.label(text=iface_("and Windows driver version %s or newer") % driver_version,
col.label(text=rpt_("Requires Intel GPU with Xe-HPG architecture"), icon='BLANK1', translate=False)
col.label(text=rpt_("and Windows driver version %s or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
driver_version = "XX.XX.25812.14"
col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1')
col.label(text=" - intel-level-zero-gpu or intel-compute-runtime version", icon='BLANK1')
col.label(text=iface_(" %s or newer") % driver_version, icon='BLANK1', translate=False)
col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1')
col.label(
text=rpt_("Requires Intel GPU with Xe-HPG architecture and"),
icon='BLANK1',
translate=False)
col.label(
text=rpt_(" - intel-level-zero-gpu or intel-compute-runtime version"),
icon='BLANK1',
translate=False)
col.label(text=rpt_(" %s or newer") % driver_version, icon='BLANK1', translate=False)
col.label(text=rpt_(" - oneAPI Level-Zero Loader"), icon='BLANK1', translate=False)
elif device_type == 'METAL':
silicon_mac_version = "12.2"
amd_mac_version = "12.3"
col.label(text=iface_("Requires Apple Silicon with macOS %s or newer") % silicon_mac_version,
col.label(text=rpt_("Requires Apple Silicon with macOS %s or newer") % silicon_mac_version,
icon='BLANK1', translate=False)
col.label(text=iface_("or AMD with macOS %s or newer") % amd_mac_version, icon='BLANK1',
col.label(text=rpt_("or AMD with macOS %s or newer") % amd_mac_version, icon='BLANK1',
translate=False)
return

View File

@ -90,40 +90,44 @@ def get_device_type(context):
return context.preferences.addons[__package__].preferences.compute_device_type
def backend_has_active_gpu(context):
return context.preferences.addons[__package__].preferences.has_active_device()
def use_cpu(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'NONE' or cscene.device == 'CPU')
return (get_device_type(context) == 'NONE' or cscene.device == 'CPU' or not backend_has_active_gpu(context))
def use_metal(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'METAL' and cscene.device == 'GPU')
return (get_device_type(context) == 'METAL' and cscene.device == 'GPU' and backend_has_active_gpu(context))
def use_cuda(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU')
return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU' and backend_has_active_gpu(context))
def use_hip(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'HIP' and cscene.device == 'GPU')
return (get_device_type(context) == 'HIP' and cscene.device == 'GPU' and backend_has_active_gpu(context))
def use_optix(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU')
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU' and backend_has_active_gpu(context))
def use_oneapi(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'ONEAPI' and cscene.device == 'GPU')
return (get_device_type(context) == 'ONEAPI' and cscene.device == 'GPU' and backend_has_active_gpu(context))
def use_multi_device(context):
@ -137,7 +141,7 @@ def show_device_active(context):
cscene = context.scene.cycles
if cscene.device != 'GPU':
return True
return context.preferences.addons[__package__].preferences.has_active_device()
return backend_has_active_gpu(context)
def get_effective_preview_denoiser(context):
@ -2441,10 +2445,11 @@ def draw_device(self, context):
from . import engine
if engine.with_osl() and (
use_cpu(context) or
(use_optix(context) and (engine.osl_version()[1] >= 13 or engine.osl_version()[0] > 1))
):
col.prop(cscene, "shading_system")
use_cpu(context) or (
use_optix(context) and (
engine.osl_version()[1] >= 13 or engine.osl_version()[0] > 1))):
osl_col = layout.column()
osl_col.prop(cscene, "shading_system")
def draw_pause(self, context):

View File

@ -683,12 +683,15 @@ static void fill_generic_attribute(const int num_curves,
}
}
static void attr_create_motion(Hair *hair,
const blender::Span<blender::float3> src,
const float motion_scale)
static void attr_create_motion_from_velocity(Hair *hair,
const blender::Span<blender::float3> src,
const float motion_scale)
{
const int num_curve_keys = hair->get_curve_keys().size();
/* Override motion steps to fixed number. */
hair->set_motion_steps(3);
/* Find or add attribute */
float3 *P = &hair->get_curve_keys()[0];
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@ -732,7 +735,7 @@ static void attr_create_generic(Scene *scene,
if (need_motion && name == u_velocity) {
const blender::VArraySpan b_attr = *b_attributes.lookup<blender::float3>(
id, blender::bke::AttrDomain::Point);
attr_create_motion(hair, b_attr, motion_scale);
attr_create_motion_from_velocity(hair, b_attr, motion_scale);
return true;
}

View File

@ -237,12 +237,15 @@ static void mikk_compute_tangents(
}
}
static void attr_create_motion(Mesh *mesh,
const blender::Span<blender::float3> b_attr,
const float motion_scale)
static void attr_create_motion_from_velocity(Mesh *mesh,
const blender::Span<blender::float3> b_attr,
const float motion_scale)
{
const int numverts = mesh->get_verts().size();
/* Override motion steps to fixed number. */
mesh->set_motion_steps(3);
/* Find or add attribute */
float3 *P = &mesh->get_verts()[0];
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@ -289,7 +292,7 @@ static void attr_create_generic(Scene *scene,
if (need_motion && name == u_velocity) {
const blender::VArraySpan b_attribute = *b_attributes.lookup<blender::float3>(
id, blender::bke::AttrDomain::Point);
attr_create_motion(mesh, b_attribute, motion_scale);
attr_create_motion_from_velocity(mesh, b_attribute, motion_scale);
}
if (!(mesh->need_attribute(scene, name) ||

View File

@ -133,7 +133,12 @@ void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob
}
geom->set_use_motion_blur(use_motion_blur);
geom->set_motion_steps(motion_steps);
if (!geom->has_motion_blur()) {
/* Only set motion steps if geometry doesn't already have
* motion blur from a velocity attribute. */
geom->set_motion_steps(motion_steps);
}
motion.resize(motion_steps, transform_empty());

View File

@ -18,16 +18,19 @@
#include "BKE_attribute.hh"
#include "BKE_attribute_math.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
CCL_NAMESPACE_BEGIN
static void attr_create_motion(PointCloud *pointcloud,
const blender::Span<blender::float3> b_attribute,
const float motion_scale)
static void attr_create_motion_from_velocity(PointCloud *pointcloud,
const blender::Span<blender::float3> b_attribute,
const float motion_scale)
{
const int num_points = pointcloud->get_points().size();
/* Override motion steps to fixed number. */
pointcloud->set_motion_steps(3);
/* Find or add attribute */
float3 *P = pointcloud->get_points().data();
float *radius = pointcloud->get_radius().data();
@ -69,7 +72,7 @@ static void copy_attributes(PointCloud *pointcloud,
if (need_motion && name == u_velocity) {
const blender::VArraySpan b_attr = *b_attributes.lookup<blender::float3>(id);
attr_create_motion(pointcloud, b_attr, motion_scale);
attr_create_motion_from_velocity(pointcloud, b_attr, motion_scale);
}
if (attributes.find(name)) {

View File

@ -159,12 +159,6 @@ void device_hip_info(vector<DeviceInfo> &devices)
info.has_nanovdb = true;
info.has_light_tree = true;
info.has_mnee = true;
info.denoisers = 0;
# if defined(WITH_OPENIMAGEDENOISE)
if (OIDNDenoiserGPU::is_device_supported(info)) {
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
info.has_gpu_queue = true;
/* Check if the device has P2P access to any other device in the system. */
@ -188,6 +182,13 @@ void device_hip_info(vector<DeviceInfo> &devices)
(unsigned int)pci_location[1],
(unsigned int)pci_location[2]);
info.denoisers = 0;
# if defined(WITH_OPENIMAGEDENOISE)
if (OIDNDenoiserGPU::is_device_supported(info)) {
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
/* If device has a kernel timeout and no compute preemption, we assume
* it is connected to a display and will freeze the display while doing
* computations. */

View File

@ -425,7 +425,7 @@ struct GWL_Cursor {
* The size of the cursor (when looking up a cursor theme).
* This must be scaled by the maximum output scale when passing to wl_cursor_theme_load.
* See #update_cursor_scale.
* */
*/
int theme_size = 0;
int custom_scale = 1;
};
@ -1327,7 +1327,7 @@ struct GWL_Display {
};
/**
* Free the #GWL_Display and it's related members.
* Free the #GWL_Display and its related members.
*
* \note This may run on a partially initialized struct,
* so it can't be assumed all members are set.
@ -2086,6 +2086,13 @@ static int memfd_create_sealed(const char *name)
#endif /* !HAVE_MEMFD_CREATE */
}
#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_VULKAN_BACKEND)
int memfd_create_sealed_for_vulkan_hack(const char *name)
{
return memfd_create_sealed(name);
}
#endif
enum {
GWL_IOR_READ = 1 << 0,
GWL_IOR_WRITE = 1 << 1,

View File

@ -88,6 +88,13 @@ bool ghost_wl_dynload_libraries_init();
void ghost_wl_dynload_libraries_exit();
#endif
#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_VULKAN_BACKEND)
/**
* Needed for temporary buffer creation.
*/
int memfd_create_sealed_for_vulkan_hack(const char *name);
#endif
struct GWL_Output {
/** Wayland core types. */

View File

@ -38,6 +38,10 @@
# include <wayland_dynload_libdecor.h>
# endif
# include <libdecor.h>
# ifdef WITH_VULKAN_BACKEND
# include <unistd.h> /* For `ftruncate`. */
# endif
#endif
/* Generated by `wayland-scanner`. */
@ -1769,11 +1773,47 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
/* NOTE: LIBDECOR requires the window to be created & configured before the state can be set.
* Workaround this by using the underlying `xdg_toplevel` */
# ifdef WITH_VULKAN_BACKEND
/* A dummy buffer is needed for VULKAN & LIBDECOR,
* otherwise `decor.initial_configure_seen` and startup locks up. */
wl_buffer *dummy_buffer = nullptr;
if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
const uint32_t format = WL_SHM_FORMAT_ARGB8888;
const int format_size = 4;
const int buffer_size = (window_->frame.size[0] * window_->frame.size[1]) * format_size;
const int fd = memfd_create_sealed_for_vulkan_hack("ghost-wl-dummy-buffer");
ftruncate(fd, buffer_size);
wl_shm *shm = system_->wl_shm_get();
wl_shm_pool *pool = wl_shm_create_pool(shm, fd, buffer_size);
dummy_buffer = wl_shm_pool_create_buffer(pool,
0,
window_->frame.size[0],
window_->frame.size[1],
window_->frame.size[0] * format_size,
format);
wl_shm_pool_destroy(pool);
wl_surface_attach(window_->wl.surface, dummy_buffer, 0, 0);
wl_surface_damage(window_->wl.surface, 0, 0, window_->frame.size[0], window_->frame.size[1]);
wl_surface_commit(window_->wl.surface);
::close(fd);
}
# endif /* WITH_GHOST_WAYLAND_LIBDECOR */
while (!decor.initial_configure_seen) {
wl_display_flush(system->wl_display_get());
wl_display_dispatch(system->wl_display_get());
}
# ifdef WITH_VULKAN_BACKEND
if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
wl_surface_attach(window_->wl.surface, nullptr, 0, 0);
wl_surface_commit(window_->wl.surface);
wl_buffer_destroy(dummy_buffer);
}
# endif /* WITH_GHOST_WAYLAND_LIBDECOR */
xdg_toplevel *toplevel = libdecor_frame_get_xdg_toplevel(decor.frame);
gwl_window_state_set_for_xdg(toplevel, state, gwl_window_state_get(window_));
}

View File

@ -593,7 +593,7 @@ MANTA::~MANTA()
* with some differences:
* - Doesn't touch `sys.modules`, use #manta_python_main_module_activate instead.
* - Returns the module instead of the modules `dict`.
* */
*/
static PyObject *manta_python_main_module_create(const char *filename)
{
PyObject *builtins = PyEval_GetBuiltins();

View File

@ -573,6 +573,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
("pgettext", ("_",)),
("pgettext_iface", ("iface_",)),
("pgettext_tip", ("tip_",)),
("pgettext_rpt", ("rpt_",)),
("pgettext_data", ("data_",)),
)
pgettext_variants_args = {"msgid": (0, {"msgctxt": 1})}

View File

@ -243,14 +243,15 @@ _ctxt_re = _ctxt_re_gen("")
_msg_re = r"(?P<msg_raw>" + _str_whole_re.format(_="_msg") + r")"
PYGETTEXT_KEYWORDS = (() +
tuple((r"{}\(\s*" + _msg_re + r"\s*\)").format(it)
for it in ("IFACE_", "TIP_", "DATA_", "N_")) +
for it in ("IFACE_", "TIP_", "RPT_", "DATA_", "N_")) +
tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*" + _msg_re + r"\s*\)").format(it)
for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_DATA_", "CTX_N_")) +
for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_RPT_", "CTX_DATA_", "CTX_N_")) +
tuple(("{}\\((?:[^\"',]+,){{1,2}}\\s*" + _msg_re + r"\s*(?:\)|,)").format(it)
for it in ("BKE_report", "BKE_reportf", "BKE_reports_prepend", "BKE_reports_prependf",
"CTX_wm_operator_poll_msg_set", "WM_report", "WM_reportf")) +
"CTX_wm_operator_poll_msg_set", "WM_report", "WM_reportf",
"UI_but_disable")) +
# bmesh operator errors
tuple(("{}\\((?:[^\"',]+,){{3}}\\s*" + _msg_re + r"\s*\)").format(it)

View File

@ -4586,6 +4586,8 @@ def km_grease_pencil_paint(_params):
# Show/hide
*_template_items_hide_reveal_actions("grease_pencil.layer_hide", "grease_pencil.layer_reveal"),
("paint.sample_color", {"type": 'X', "value": 'PRESS', "shift": True}, None),
])
return keymap

View File

@ -14,7 +14,7 @@ from bpy.props import (
StringProperty,
)
from bpy.app.translations import (
pgettext_tip as tip_,
pgettext_rpt as rpt_,
contexts as i18n_contexts,
)
@ -114,7 +114,7 @@ class ANIM_OT_keying_set_export(Operator):
if not found:
self.report(
{'WARN'},
tip_("Could not find material or light using Shader Node Tree - %s") %
rpt_("Could not find material or light using Shader Node Tree - %s") %
(ksp.id))
elif ksp.id.bl_rna.identifier.startswith("CompositorNodeTree"):
# Find compositor node-tree using this node tree.
@ -123,7 +123,7 @@ class ANIM_OT_keying_set_export(Operator):
id_bpy_path = "bpy.data.scenes[\"%s\"].node_tree" % (scene.name)
break
else:
self.report({'WARN'}, tip_("Could not find scene using Compositor Node Tree - %s") % (ksp.id))
self.report({'WARN'}, rpt_("Could not find scene using Compositor Node Tree - %s") % (ksp.id))
elif ksp.id.bl_rna.name == "Key":
# "keys" conflicts with a Python keyword, hence the simple solution won't work
id_bpy_path = "bpy.data.shape_keys[\"%s\"]" % (ksp.id.name)
@ -358,7 +358,7 @@ class ClearUselessActions(Operator):
action.user_clear()
removed += 1
self.report({'INFO'}, tip_("Removed %d empty and/or fake-user only Actions")
self.report({'INFO'}, rpt_("Removed %d empty and/or fake-user only Actions")
% removed)
return {'FINISHED'}
@ -443,7 +443,7 @@ class UpdateAnimatedTransformConstraint(Operator):
print(log)
text = bpy.data.texts.new("UpdateAnimatedTransformConstraint Report")
text.from_string(log)
self.report({'INFO'}, tip_("Complete report available on '%s' text datablock") % text.name)
self.report({'INFO'}, rpt_("Complete report available on '%s' text datablock") % text.name)
return {'FINISHED'}

View File

@ -8,7 +8,7 @@ import bpy
from bpy.types import Operator
from bpy.app.translations import (
pgettext_data as data_,
pgettext_tip as tip_,
pgettext_rpt as rpt_,
)
@ -125,7 +125,7 @@ class ASSET_OT_open_containing_blend_file(Operator):
return {'RUNNING_MODAL'}
if returncode:
self.report({'WARNING'}, tip_("Blender sub-process exited with error code %d") % returncode)
self.report({'WARNING'}, rpt_("Blender sub-process exited with error code %d") % returncode)
if bpy.ops.asset.library_refresh.poll():
bpy.ops.asset.library_refresh()

View File

@ -9,7 +9,7 @@ from mathutils import (
Vector,
Matrix,
)
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import pgettext_rpt as rpt_
def CLIP_spaces_walk(context, all_screens, tarea, tspace, callback, *args):
@ -197,7 +197,7 @@ class CLIP_OT_filter_tracks(Operator):
def execute(self, context):
num_tracks = self._filter_values(context, self.track_threshold)
self.report({'INFO'}, tip_("Identified %d problematic tracks") % num_tracks)
self.report({'INFO'}, rpt_("Identified %d problematic tracks") % num_tracks)
return {'FINISHED'}

View File

@ -12,7 +12,7 @@ from bpy.props import (
CollectionProperty,
StringProperty,
)
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import pgettext_rpt as rpt_
# ########## Datablock previews... ##########
@ -126,7 +126,7 @@ class WM_OT_previews_batch_generate(Operator):
if not self.use_backups:
cmd.append("--no_backups")
if subprocess.call(cmd):
self.report({'ERROR'}, tip_("Previews generation process failed for file '%s'!") % blen_path)
self.report({'ERROR'}, rpt_("Previews generation process failed for file '%s'!") % blen_path)
context.window_manager.progress_end()
return {'CANCELLED'}
context.window_manager.progress_update(i + 1)
@ -237,7 +237,7 @@ class WM_OT_previews_batch_clear(Operator):
if not self.use_backups:
cmd.append("--no_backups")
if subprocess.call(cmd):
self.report({'ERROR'}, tip_("Previews clear process failed for file '%s'!") % blen_path)
self.report({'ERROR'}, rpt_("Previews clear process failed for file '%s'!") % blen_path)
context.window_manager.progress_end()
return {'CANCELLED'}
context.window_manager.progress_update(i + 1)

View File

@ -5,7 +5,7 @@
import bpy
from bpy.types import Operator
from bpy.props import StringProperty
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import pgettext_rpt as rpt_
class EditExternally(Operator):
@ -55,7 +55,7 @@ class EditExternally(Operator):
if not os.path.exists(filepath) or not os.path.isfile(filepath):
self.report({'ERROR'},
tip_("Image path %r not found, image may be packed or "
rpt_("Image path %r not found, image may be packed or "
"unsaved") % filepath)
return {'CANCELLED'}
@ -182,7 +182,7 @@ class ProjectApply(Operator):
image_name = ProjectEdit._proj_hack[0] # TODO, deal with this nicer
image = bpy.data.images.get((image_name, None))
if image is None:
self.report({'ERROR'}, tip_("Could not find image '%s'") % image_name)
self.report({'ERROR'}, rpt_("Could not find image '%s'") % image_name)
return {'CANCELLED'}
image.reload()

View File

@ -9,7 +9,7 @@ from bpy.props import (
EnumProperty,
IntProperty,
)
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import pgettext_rpt as rpt_
class MeshMirrorUV(Operator):
@ -169,18 +169,18 @@ class MeshMirrorUV(Operator):
if total_duplicates and total_no_active_UV:
self.report({'WARNING'},
tip_("%d mesh(es) with no active UV layer, "
rpt_("%d mesh(es) with no active UV layer, "
"%d duplicates found in %d mesh(es), mirror may be incomplete")
% (total_no_active_UV,
total_duplicates,
meshes_with_duplicates))
elif total_no_active_UV:
self.report({'WARNING'},
tip_("%d mesh(es) with no active UV layer")
rpt_("%d mesh(es) with no active UV layer")
% (total_no_active_UV,))
elif total_duplicates:
self.report({'WARNING'},
tip_("%d duplicates found in %d mesh(es), mirror may be incomplete")
rpt_("%d duplicates found in %d mesh(es), mirror may be incomplete")
% (total_duplicates, meshes_with_duplicates))
return {'FINISHED'}

View File

@ -20,7 +20,10 @@ from mathutils import (
Vector,
)
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import (
pgettext_tip as tip_,
pgettext_rpt as rpt_,
)
class NodeSetting(PropertyGroup):
@ -94,7 +97,7 @@ class NodeAddOperator:
except AttributeError as ex:
self.report(
{'ERROR_INVALID_INPUT'},
tip_("Node has no attribute %s") % setting.name)
rpt_("Node has no attribute %s") % setting.name)
print(str(ex))
# Continue despite invalid attribute

View File

@ -10,7 +10,7 @@ from bpy.props import (
IntProperty,
StringProperty,
)
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import pgettext_rpt as rpt_
class SelectPattern(Operator):
@ -367,12 +367,12 @@ class ShapeTransfer(Operator):
for ob_other in objects:
if ob_other.type != 'MESH':
self.report({'WARNING'},
tip_("Skipping '%s', not a mesh") % ob_other.name)
rpt_("Skipping '%s', not a mesh") % ob_other.name)
continue
me_other = ob_other.data
if len(me_other.vertices) != len(me.vertices):
self.report({'WARNING'},
tip_("Skipping '%s', vertex count differs") % ob_other.name)
rpt_("Skipping '%s', vertex count differs") % ob_other.name)
continue
target_normals = me_nos(me_other.vertices)
@ -511,7 +511,7 @@ class JoinUVs(Operator):
if not mesh.uv_layers:
self.report({'WARNING'},
tip_("Object: %s, Mesh: '%s' has no UVs")
rpt_("Object: %s, Mesh: '%s' has no UVs")
% (obj.name, mesh.name))
else:
nbr_loops = len(mesh.loops)
@ -535,7 +535,7 @@ class JoinUVs(Operator):
if len(mesh_other.loops) != nbr_loops:
self.report({'WARNING'},
tip_("Object: %s, Mesh: "
rpt_("Object: %s, Mesh: "
"'%s' has %d loops (for %d faces),"
" expected %d\n")
% (obj_other.name,
@ -552,7 +552,7 @@ class JoinUVs(Operator):
uv_other = mesh_other.uv_layers.active
if not uv_other:
self.report({'ERROR'},
tip_("Could not add "
rpt_("Could not add "
"a new UV map to object "
"'%s' (Mesh '%s')\n")
% (obj_other.name,
@ -795,7 +795,7 @@ class TransformsToDeltasAnim(Operator):
adt = obj.animation_data
if (adt is None) or (adt.action is None):
self.report({'WARNING'},
tip_("No animation data to convert on object: %r")
rpt_("No animation data to convert on object: %r")
% obj.name)
continue
@ -822,7 +822,7 @@ class TransformsToDeltasAnim(Operator):
if fcu.array_index in existingFCurves[dpath]:
# conflict
self.report({'ERROR'},
tip_("Object '%r' already has '%r' F-Curve(s). "
rpt_("Object '%r' already has '%r' F-Curve(s). "
"Remove these before trying again") %
(obj.name, dpath))
return {'CANCELLED'}

View File

@ -12,7 +12,7 @@ from bpy.props import (
IntProperty,
)
from bpy.app.translations import (
pgettext_tip as tip_,
pgettext_rpt as rpt_,
pgettext_data as data_,
)
@ -282,7 +282,7 @@ class QuickExplode(ObjectModeOperator, Operator):
for obj in mesh_objects:
if obj.particle_systems:
self.report({'ERROR'},
tip_("Object %r already has a "
rpt_("Object %r already has a "
"particle system") % obj.name)
return {'CANCELLED'}

View File

@ -13,7 +13,7 @@ from bpy.props import (
StringProperty,
)
from bpy.app.translations import (
pgettext_tip as tip_,
pgettext_rpt as rpt_,
pgettext_data as data_,
)
@ -191,7 +191,7 @@ class AddPresetBase:
else:
os.remove(filepath)
except BaseException as ex:
self.report({'ERROR'}, tip_("Unable to remove preset: %r") % ex)
self.report({'ERROR'}, rpt_("Unable to remove preset: %r") % ex)
import traceback
traceback.print_exc()
return {'CANCELLED'}
@ -241,7 +241,7 @@ class ExecutePreset(Operator):
ext = splitext(filepath)[1].lower()
if ext not in {".py", ".xml"}:
self.report({'ERROR'}, tip_("Unknown file type: %r") % ext)
self.report({'ERROR'}, rpt_("Unknown file type: %r") % ext)
return {'CANCELLED'}
if hasattr(preset_class, "reset_cb"):

View File

@ -6,7 +6,7 @@
import bpy
from bpy.types import Operator
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import pgettext_rpt as rpt_
def guess_player_path(preset):
@ -119,7 +119,7 @@ class PlayRenderedAnim(Operator):
file = rd.frame_path(frame=scene.frame_start, preview=scene.use_preview_range, view=view_suffix)
file = bpy.path.abspath(file) # expand '//'
if not os.path.exists(file):
err_msg = tip_("File %r not found") % file
err_msg = rpt_("File %r not found") % file
self.report({'WARNING'}, err_msg)
path_valid = False
@ -127,7 +127,7 @@ class PlayRenderedAnim(Operator):
if scene.use_preview_range and not path_valid:
file = rd.frame_path(frame=scene.frame_start, preview=False, view=view_suffix)
file = bpy.path.abspath(file) # expand '//'
err_msg = tip_("File %r not found") % file
err_msg = rpt_("File %r not found") % file
if not os.path.exists(file):
self.report({'WARNING'}, err_msg)
@ -195,7 +195,7 @@ class PlayRenderedAnim(Operator):
try:
subprocess.Popen(cmd)
except BaseException as ex:
err_msg = tip_("Couldn't run external animation player with command %r\n%s") % (cmd, ex)
err_msg = rpt_("Couldn't run external animation player with command %r\n%s") % (cmd, ex)
self.report(
{'ERROR'},
err_msg,

View File

@ -10,7 +10,7 @@ from bpy.props import (
FloatProperty,
IntProperty,
)
from bpy.app.translations import pgettext_tip as tip_
from bpy.app.translations import pgettext_rpt as rpt_
class SequencerCrossfadeSounds(Operator):
@ -236,7 +236,7 @@ class SequencerFadesAdd(Operator):
sequence.invalidate_cache('COMPOSITE')
sequence_string = "sequence" if len(faded_sequences) == 1 else "sequences"
self.report({'INFO'}, tip_("Added fade animation to %d %s") % (len(faded_sequences), sequence_string))
self.report({'INFO'}, rpt_("Added fade animation to %d %s") % (len(faded_sequences), sequence_string))
return {'FINISHED'}
def calculate_fade_duration(self, context, sequence):

View File

@ -16,7 +16,7 @@ from bpy.props import (
)
from bpy.app.translations import (
pgettext_iface as iface_,
pgettext_tip as tip_,
pgettext_tip as rpt_,
)
@ -229,7 +229,7 @@ class PREFERENCES_OT_keyconfig_import(Operator):
else:
shutil.move(self.filepath, path)
except BaseException as ex:
self.report({'ERROR'}, tip_("Installing keymap failed: %s") % ex)
self.report({'ERROR'}, rpt_("Installing keymap failed: %s") % ex)
return {'CANCELLED'}
# sneaky way to check we're actually running the code.
@ -455,7 +455,7 @@ class PREFERENCES_OT_addon_enable(Operator):
if info_ver > bpy.app.version:
self.report(
{'WARNING'},
tip_("This script was written Blender "
rpt_("This script was written Blender "
"version %d.%d.%d and might not "
"function (correctly), "
"though it is enabled")
@ -543,7 +543,7 @@ class PREFERENCES_OT_theme_install(Operator):
if not self.overwrite:
if os.path.exists(path_dest):
self.report({'WARNING'}, tip_("File already installed to %r\n") % path_dest)
self.report({'WARNING'}, rpt_("File already installed to %r\n") % path_dest)
return {'CANCELLED'}
try:
@ -657,7 +657,7 @@ class PREFERENCES_OT_addon_install(Operator):
pyfile_dir = os.path.dirname(pyfile)
for addon_path in addon_utils.paths():
if os.path.samefile(pyfile_dir, addon_path):
self.report({'ERROR'}, tip_("Source file is in the add-on search path: %r") % addon_path)
self.report({'ERROR'}, rpt_("Source file is in the add-on search path: %r") % addon_path)
return {'CANCELLED'}
del addon_path
del pyfile_dir
@ -681,7 +681,7 @@ class PREFERENCES_OT_addon_install(Operator):
for f in file_to_extract_root:
path_dest = os.path.join(path_addons, os.path.basename(f))
if os.path.exists(path_dest):
self.report({'WARNING'}, tip_("File already installed to %r\n") % path_dest)
self.report({'WARNING'}, rpt_("File already installed to %r\n") % path_dest)
return {'CANCELLED'}
try: # extract the file to "addons"
@ -696,7 +696,7 @@ class PREFERENCES_OT_addon_install(Operator):
if self.overwrite:
_module_filesystem_remove(path_addons, os.path.basename(pyfile))
elif os.path.exists(path_dest):
self.report({'WARNING'}, tip_("File already installed to %r\n") % path_dest)
self.report({'WARNING'}, rpt_("File already installed to %r\n") % path_dest)
return {'CANCELLED'}
# if not compressed file just copy into the addon path
@ -731,7 +731,7 @@ class PREFERENCES_OT_addon_install(Operator):
# print message
msg = (
tip_("Modules Installed (%s) from %r into %r") %
rpt_("Modules Installed (%s) from %r into %r") %
(", ".join(sorted(addons_new)), pyfile, path_addons)
)
print(msg)
@ -776,7 +776,7 @@ class PREFERENCES_OT_addon_remove(Operator):
path, isdir = PREFERENCES_OT_addon_remove.path_from_addon(self.module)
if path is None:
self.report({'WARNING'}, tip_("Add-on path %r could not be found") % path)
self.report({'WARNING'}, rpt_("Add-on path %r could not be found") % path)
return {'CANCELLED'}
# in case its enabled
@ -926,7 +926,7 @@ class PREFERENCES_OT_app_template_install(Operator):
for f in file_to_extract_root:
path_dest = os.path.join(path_app_templates, os.path.basename(f))
if os.path.exists(path_dest):
self.report({'WARNING'}, tip_("File already installed to %r\n") % path_dest)
self.report({'WARNING'}, rpt_("File already installed to %r\n") % path_dest)
return {'CANCELLED'}
try: # extract the file to "bl_app_templates_user"
@ -937,7 +937,7 @@ class PREFERENCES_OT_app_template_install(Operator):
else:
# Only support installing zip-files.
self.report({'WARNING'}, tip_("Expected a zip-file %r\n") % filepath)
self.report({'WARNING'}, rpt_("Expected a zip-file %r\n") % filepath)
return {'CANCELLED'}
app_templates_new = set(os.listdir(path_app_templates)) - app_templates_old
@ -947,7 +947,7 @@ class PREFERENCES_OT_app_template_install(Operator):
# print message
msg = (
tip_("Template Installed (%s) from %r into %r") %
rpt_("Template Installed (%s) from %r into %r") %
(", ".join(sorted(app_templates_new)), filepath, path_app_templates)
)
print(msg)
@ -1011,7 +1011,7 @@ class PREFERENCES_OT_studiolight_install(Operator):
# print message
msg = (
tip_("StudioLight Installed %r into %r") %
rpt_("StudioLight Installed %r into %r") %
(", ".join(e.name for e in self.files), path_studiolights)
)
print(msg)
@ -1069,7 +1069,7 @@ class PREFERENCES_OT_studiolight_new(Operator):
# print message
msg = (
tip_("StudioLight Installed %r into %r") %
rpt_("StudioLight Installed %r into %r") %
(self.filename, str(path_studiolights))
)
print(msg)

View File

@ -113,9 +113,15 @@ class prettyface:
# ngons work different, we store projected result
# in UVs to avoid having to re-project later.
for i, co in enumerate(cos_2d):
self.uv[i][:] = ((co.x - xmin) / xspan,
(co.y - ymin) / yspan)
if xspan < 0.0000001 or yspan < 0.0000001:
for i in range(len(cos_2d)):
self.uv[i][:] = (0.0, 0.0)
else:
for i, co in enumerate(cos_2d):
self.uv[i][:] = (
(co.x - xmin) / xspan,
(co.y - ymin) / yspan,
)
self.children = []
@ -296,28 +302,52 @@ def lightmap_uvpack(
tri_lengths = [trylens(f) for f in face_sel if f.loop_total == 3]
del trylens
def trilensdiff(t1, t2):
return (abs(t1[1][t1[2][0]] - t2[1][t2[2][0]]) +
abs(t1[1][t1[2][1]] - t2[1][t2[2][1]]) +
abs(t1[1][t1[2][2]] - t2[1][t2[2][2]]))
# To add triangles into the light-map pack triangles are grouped in pairs to fill rectangular areas.
# In the following for each triangle we add the sorted triangle edge lengths (3d point) into a KD-Tree
# then iterate over all triangles and search for pairs of triangles by looking for the closest
# sorted triangle point.
# Additionally clusters of similar/equal triangles are parsed by searching for ranges in a second step.
kd = mathutils.kdtree.KDTree(len(tri_lengths))
for i, (f, lens, o) in enumerate(tri_lengths):
vector = (lens[o[0]], lens[o[1]], lens[o[2]])
kd.insert(vector, i)
kd.balance()
while tri_lengths:
tri1 = tri_lengths.pop()
added_ids = [False] * len(tri_lengths)
pairs_added = 0
tri_equality_threshold = 0.00001 # Add multiple pairs at once that are within this threshold.
for i in range(len(tri_lengths)):
if added_ids[i]:
continue
tri1 = tri_lengths[i]
f1, lens1, lo1 = tri1
if not tri_lengths:
sorted_l = (lens1[lo1[0]], lens1[lo1[1]], lens1[lo1[2]])
added_ids[i] = True
vec, nearest, dist = kd.find(sorted_l, filter=lambda idx: not added_ids[idx])
if not nearest or nearest < 0:
pretty_faces.append(prettyface((tri1, None)))
break
tri2 = tri_lengths[nearest]
pretty_faces.append(prettyface((tri1, tri2)))
pairs_added = pairs_added + 1
added_ids[nearest] = True
best_tri_index = -1
best_tri_diff = 100000000.0
# Look in threshold proximity to add all similar/equal triangles in one go.
# This code is not necessary but acts as a shortcut (~9% performance improvement).
if dist < tri_equality_threshold:
cluster_tri_ids = [
idx for _, idx, _ in kd.find_range(sorted_l, tri_equality_threshold)
if not added_ids[idx]
]
for i, tri2 in enumerate(tri_lengths):
diff = trilensdiff(tri1, tri2)
if diff < best_tri_diff:
best_tri_index = i
best_tri_diff = diff
pretty_faces.append(prettyface((tri1, tri_lengths.pop(best_tri_index))))
if len(cluster_tri_ids) > 1:
for ci in range(0, len(cluster_tri_ids) - (len(cluster_tri_ids) % 2), 2):
pretty_faces.append(
prettyface((tri_lengths[cluster_tri_ids[ci]], tri_lengths[cluster_tri_ids[ci + 1]]))
)
added_ids[cluster_tri_ids[ci]] = added_ids[cluster_tri_ids[ci + 1]] = True
pairs_added = pairs_added + 1
# Get the min, max and total areas
max_area = 0.0

View File

@ -23,6 +23,7 @@ from bpy.props import (
from bpy.app.translations import (
pgettext_iface as iface_,
pgettext_tip as tip_,
pgettext_rpt as rpt_,
contexts as i18n_contexts,
)
@ -778,7 +779,7 @@ class WM_OT_operator_pie_enum(Operator):
try:
op_rna = op.get_rna_type()
except KeyError:
self.report({'ERROR'}, tip_("Operator not found: bpy.ops.%s") % data_path)
self.report({'ERROR'}, rpt_("Operator not found: bpy.ops.%s") % data_path)
return {'CANCELLED'}
def draw_cb(self, context):
@ -878,7 +879,7 @@ class WM_OT_context_collection_boolean_set(Operator):
elif value_orig is False:
pass
else:
self.report({'WARNING'}, tip_("Non boolean value found: %s[ ].%s") %
self.report({'WARNING'}, rpt_("Non boolean value found: %s[ ].%s") %
(data_path_iter, data_path_item))
return {'CANCELLED'}
@ -981,7 +982,7 @@ class WM_OT_context_modal_mouse(Operator):
(item, ) = self._values.keys()
header_text = header_text % eval("item.%s" % self.data_path_item)
else:
header_text = (self.header_text % delta) + tip_(" (delta)")
header_text = (self.header_text % delta) + rpt_(" (delta)")
context.area.header_text_set(header_text)
elif 'LEFTMOUSE' == event_type:
@ -1001,7 +1002,7 @@ class WM_OT_context_modal_mouse(Operator):
self._values_store(context)
if not self._values:
self.report({'WARNING'}, tip_("Nothing to operate on: %s[ ].%s") %
self.report({'WARNING'}, rpt_("Nothing to operate on: %s[ ].%s") %
(self.data_path_iter, self.data_path_item))
return {'CANCELLED'}
@ -1168,7 +1169,7 @@ class WM_OT_path_open(Operator):
filepath = os.path.normpath(filepath)
if not os.path.exists(filepath):
self.report({'ERROR'}, tip_("File '%s' not found") % filepath)
self.report({'ERROR'}, rpt_("File '%s' not found") % filepath)
return {'CANCELLED'}
if sys.platform[:3] == "win":
@ -1239,7 +1240,7 @@ def _wm_doc_get_id(doc_id, *, do_url=True, url_prefix="", report=None):
if rna_class is None:
if report is not None:
report({'ERROR'}, tip_("Type \"%s\" can not be found") % class_name)
report({'ERROR'}, rpt_("Type \"%s\" can not be found") % class_name)
return None
# Detect if this is a inherited member and use that name instead.
@ -1334,7 +1335,7 @@ class WM_OT_doc_view_manual(Operator):
if url is None:
self.report(
{'WARNING'},
tip_("No reference available %r, "
rpt_("No reference available %r, "
"Update info in 'rna_manual_reference.py' "
"or callback to bpy.utils.manual_map()") %
self.doc_id
@ -2317,7 +2318,7 @@ class WM_OT_tool_set_by_id(Operator):
tool_settings.workspace_tool_type = 'FALLBACK'
return {'FINISHED'}
else:
self.report({'WARNING'}, tip_("Tool %r not found for space %r") % (self.name, space_type))
self.report({'WARNING'}, rpt_("Tool %r not found for space %r") % (self.name, space_type))
return {'CANCELLED'}
@ -3188,7 +3189,7 @@ class WM_OT_batch_rename(Operator):
change_len += 1
total_len += 1
self.report({'INFO'}, tip_("Renamed %d of %d %s") % (change_len, total_len, descr))
self.report({'INFO'}, rpt_("Renamed %d of %d %s") % (change_len, total_len, descr))
return {'FINISHED'}

View File

@ -215,6 +215,7 @@ class NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeDeleteGeometry")
node_add_menu.add_node_type(layout, "GeometryNodeDuplicateElements")
node_add_menu.add_node_type(layout, "GeometryNodeMergeByDistance")
node_add_menu.add_node_type(layout, "GeometryNodeSortElements")
node_add_menu.add_node_type(layout, "GeometryNodeTransform")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeSeparateComponents")

View File

@ -8,7 +8,7 @@ from rna_prop_ui import PropertyPanel
from bpy.app.translations import (
pgettext_iface as iface_,
pgettext_tip as tip_,
pgettext_tip as rpt_,
)
@ -581,7 +581,7 @@ def draw_attribute_warnings(context, layout):
if not colliding_names:
return
layout.label(text=tip_("Name collisions: ") + ", ".join(set(colliding_names)),
layout.label(text=rpt_("Name collisions: ") + ", ".join(set(colliding_names)),
icon='ERROR', translate=False)

View File

@ -27,6 +27,15 @@ class GPENCIL_MT_material_context_menu(Menu):
layout.operator("grease_pencil.material_unlock_all", icon='UNLOCKED', text="Unlock All")
layout.operator("grease_pencil.material_lock_unselected", text="Lock Unselected")
layout.operator("grease_pencil.material_lock_unused", text="Lock Unused")
layout.separator()
layout.operator(
"grease_pencil.material_copy_to_object",
text="Copy Material to Selected").only_active = True
layout.operator("grease_pencil.material_copy_to_object",
text="Copy All Materials to Selected").only_active = False
else:
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

View File

@ -8,7 +8,7 @@ from bl_ui.utils import PresetPanel
from bpy.app.translations import (
contexts as i18n_contexts,
pgettext_tip as tip_,
pgettext_iface as iface_,
)
@ -75,10 +75,10 @@ class RENDER_PT_format(RenderOutputButtonsPanel, Panel):
custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60, 120, 240})
if custom_framerate is True:
fps_label_text = tip_("Custom (%.4g fps)") % fps_rate
fps_label_text = iface_("Custom (%.4g fps)") % fps_rate
show_framerate = True
else:
fps_label_text = tip_("%.4g fps") % fps_rate
fps_label_text = iface_("%.4g fps") % fps_rate
show_framerate = (preset_label == "Custom")
RENDER_PT_format._frame_rate_args_prev = args

View File

@ -8,6 +8,7 @@ from rna_prop_ui import PropertyPanel
from bpy.app.translations import (
contexts as i18n_contexts,
pgettext_iface as iface_,
pgettext_rpt as rpt_,
)
from bl_ui.utils import PresetPanel
@ -221,7 +222,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
row.template_ID(psys, "settings", new="particle.new")
if part.is_fluid:
layout.label(text=iface_("%d fluid particles for this frame") % part.count, translate=False)
layout.label(text=rpt_("%d fluid particles for this frame") % part.count, translate=False)
return
row = layout.row()
@ -432,10 +433,10 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
label = "ERROR"
icon = 'ERROR'
box.label(text=label, icon=icon)
box.label(text=iface_("Iterations: %d .. %d (avg. %d)") %
box.label(text=rpt_("Iterations: %d .. %d (avg. %d)") %
(result.min_iterations, result.max_iterations, result.avg_iterations),
translate=False)
box.label(text=iface_("Error: %.5f .. %.5f (avg. %.5f)")
box.label(text=rpt_("Error: %.5f .. %.5f (avg. %.5f)")
% (result.min_error, result.max_error, result.avg_error),
translate=False)

View File

@ -10,6 +10,7 @@ from bl_ui.space_view3d import (
VIEW3D_PT_shading_options,
)
from bl_ui.utils import PresetPanel
from bpy.app.translations import pgettext_rpt as rpt_
class RenderButtonsPanel:
@ -829,7 +830,7 @@ class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel):
cache_info = scene.eevee.gi_cache_info
if cache_info:
col.label(text=cache_info)
col.label(text=rpt_(cache_info), translate=False)
col.prop(props, "gi_auto_bake")

View File

@ -6,6 +6,7 @@ import bpy
from bpy.types import Panel, Header, Menu, UIList
from bpy.app.translations import (
pgettext_iface as iface_,
pgettext_rpt as rpt_,
contexts as i18n_contexts,
)
from bl_ui.utils import PresetPanel
@ -170,7 +171,7 @@ class CLIP_HT_header(Header):
r = active_object.reconstruction
if r.is_valid and sc.view == 'CLIP':
layout.label(text=iface_("Solve error: %.2f px") %
layout.label(text=rpt_("Solve error: %.2f px") %
(r.average_error),
translate=False)
@ -769,7 +770,7 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
layout.prop(act_track, "weight_stab")
if act_track.has_bundle:
label_text = iface_("Average Error: %.2f px") % (act_track.average_error)
label_text = rpt_("Average Error: %.2f px") % (act_track.average_error)
layout.label(text=label_text, translate=False)
layout.use_property_split = False

View File

@ -11,6 +11,7 @@ from bpy.types import (
from bpy.app.translations import (
contexts as i18n_contexts,
pgettext_iface as iface_,
pgettext_rpt as rpt_,
)
from bl_ui.properties_grease_pencil_common import (
AnnotationDataPanel,
@ -1905,7 +1906,7 @@ class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
if mask:
sta = mask.frame_start
end = mask.frame_end
layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
layout.label(text=rpt_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
class SEQUENCER_PT_time(SequencerButtonsPanel, Panel):

View File

@ -11,7 +11,7 @@ from bpy.types import (
from bpy.app.translations import (
contexts as i18n_contexts,
pgettext_iface as iface_,
pgettext_tip as tip_,
pgettext_rpt as rpt_,
)
from bl_ui.utils import PresetPanel
@ -260,6 +260,7 @@ class USERPREF_PT_interface_translation(InterfacePanel, CenterAlignMixIn, Panel)
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_reports", text="Reports")
col.prop(view, "use_translate_new_dataname", text="New Data")
@ -2239,11 +2240,11 @@ class USERPREF_PT_addons(AddOnPanel, Panel):
if info["description"]:
split = colsub.row().split(factor=0.15)
split.label(text="Description:")
split.label(text=tip_(info["description"]))
split.label(text=iface_(info["description"]))
if info["location"]:
split = colsub.row().split(factor=0.15)
split.label(text="Location:")
split.label(text=tip_(info["location"]))
split.label(text=iface_(info["location"]))
if mod:
split = colsub.row().split(factor=0.15)
split.label(text="File:")
@ -2259,7 +2260,7 @@ class USERPREF_PT_addons(AddOnPanel, Panel):
if info["warning"]:
split = colsub.row().split(factor=0.15)
split.label(text="Warning:")
split.label(text=" " + info["warning"], icon='ERROR')
split.label(text=" " + iface_(info["warning"]), icon='ERROR')
user_addon = USERPREF_PT_addons.is_user_addon(mod, user_addon_paths)
if info["doc_url"] or info.get("tracker_url"):
@ -2370,7 +2371,7 @@ class StudioLightPanelMixin:
layout.label(text=self.get_error_message())
def get_error_message(self):
return tip_("No custom %s configured") % self.bl_label
return rpt_("No custom %s configured") % self.bl_label
def draw_studio_light(self, layout, studio_light):
box = layout.box()
@ -2398,7 +2399,7 @@ class USERPREF_PT_studiolight_matcaps(StudioLightPanel, StudioLightPanelMixin, P
layout.separator()
def get_error_message(self):
return tip_("No custom MatCaps configured")
return rpt_("No custom MatCaps configured")
class USERPREF_PT_studiolight_world(StudioLightPanel, StudioLightPanelMixin, Panel):
@ -2411,7 +2412,7 @@ class USERPREF_PT_studiolight_world(StudioLightPanel, StudioLightPanelMixin, Pan
layout.separator()
def get_error_message(self):
return tip_("No custom HDRIs configured")
return rpt_("No custom HDRIs configured")
class USERPREF_PT_studiolight_lights(StudioLightPanel, StudioLightPanelMixin, Panel):
@ -2426,7 +2427,7 @@ class USERPREF_PT_studiolight_lights(StudioLightPanel, StudioLightPanelMixin, Pa
layout.separator()
def get_error_message(self):
return tip_("No custom Studio Lights configured")
return rpt_("No custom Studio Lights configured")
class USERPREF_PT_studiolight_light_editor(StudioLightPanel, Panel):

View File

@ -24,7 +24,7 @@ from bl_ui.space_toolsystem_common import (
)
from bpy.app.translations import (
pgettext_iface as iface_,
pgettext_tip as tip_,
pgettext_rpt as rpt_,
contexts as i18n_contexts,
)
@ -2180,6 +2180,10 @@ class VIEW3D_MT_paint_grease_pencil(Menu):
layout.menu("VIEW3D_MT_edit_greasepencil_showhide")
layout.separator()
layout.operator("paint.sample_color")
class VIEW3D_MT_paint_gpencil(Menu):
bl_label = "Paint"
@ -2861,16 +2865,16 @@ class VIEW3D_MT_object_context_menu(Menu):
props.data_path_item = "data.lens"
props.input_scale = 0.1
if obj.data.lens_unit == 'MILLIMETERS':
props.header_text = tip_("Camera Focal Length: %.1fmm")
props.header_text = rpt_("Camera Focal Length: %.1fmm")
else:
props.header_text = tip_("Camera Focal Length: %.1f\u00B0")
props.header_text = rpt_("Camera Focal Length: %.1f\u00B0")
else:
props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.ortho_scale"
props.input_scale = 0.01
props.header_text = tip_("Camera Lens Scale: %.3f")
props.header_text = rpt_("Camera Lens Scale: %.3f")
if not obj.data.dof.focus_object:
if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
@ -2880,7 +2884,7 @@ class VIEW3D_MT_object_context_menu(Menu):
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.dof.focus_distance"
props.input_scale = 0.02
props.header_text = tip_("Focus Distance: %.3f")
props.header_text = rpt_("Focus Distance: %.3f")
layout.separator()
@ -2891,13 +2895,13 @@ class VIEW3D_MT_object_context_menu(Menu):
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.extrude"
props.input_scale = 0.01
props.header_text = tip_("Extrude: %.3f")
props.header_text = rpt_("Extrude: %.3f")
props = layout.operator("wm.context_modal_mouse", text="Adjust Offset")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.offset"
props.input_scale = 0.01
props.header_text = tip_("Offset: %.3f")
props.header_text = rpt_("Offset: %.3f")
layout.separator()
@ -2908,7 +2912,7 @@ class VIEW3D_MT_object_context_menu(Menu):
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "empty_display_size"
props.input_scale = 0.01
props.header_text = tip_("Empty Display Size: %.3f")
props.header_text = rpt_("Empty Display Size: %.3f")
layout.separator()
@ -2926,36 +2930,36 @@ class VIEW3D_MT_object_context_menu(Menu):
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.energy"
props.input_scale = 1.0
props.header_text = tip_("Light Power: %.3f")
props.header_text = rpt_("Light Power: %.3f")
if light.type == 'AREA':
if light.shape in {'RECTANGLE', 'ELLIPSE'}:
props = layout.operator("wm.context_modal_mouse", text="Adjust Area Light X Size")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.size"
props.header_text = tip_("Light Size X: %.3f")
props.header_text = rpt_("Light Size X: %.3f")
props = layout.operator("wm.context_modal_mouse", text="Adjust Area Light Y Size")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.size_y"
props.header_text = tip_("Light Size Y: %.3f")
props.header_text = rpt_("Light Size Y: %.3f")
else:
props = layout.operator("wm.context_modal_mouse", text="Adjust Area Light Size")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.size"
props.header_text = tip_("Light Size: %.3f")
props.header_text = rpt_("Light Size: %.3f")
elif light.type in {'SPOT', 'POINT'}:
props = layout.operator("wm.context_modal_mouse", text="Adjust Light Radius")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.shadow_soft_size"
props.header_text = tip_("Light Radius: %.3f")
props.header_text = rpt_("Light Radius: %.3f")
elif light.type == 'SUN':
props = layout.operator("wm.context_modal_mouse", text="Adjust Sun Light Angle")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.angle"
props.header_text = tip_("Light Angle: %.3f")
props.header_text = rpt_("Light Angle: %.3f")
if light.type == 'SPOT':
layout.separator()
@ -2964,13 +2968,13 @@ class VIEW3D_MT_object_context_menu(Menu):
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.spot_size"
props.input_scale = 0.01
props.header_text = tip_("Spot Size: %.2f")
props.header_text = rpt_("Spot Size: %.2f")
props = layout.operator("wm.context_modal_mouse", text="Adjust Spot Light Blend")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.spot_blend"
props.input_scale = -0.01
props.header_text = tip_("Spot Blend: %.2f")
props.header_text = rpt_("Spot Blend: %.2f")
layout.separator()
@ -5821,10 +5825,13 @@ class VIEW3D_MT_edit_greasepencil_stroke(Menu):
def draw(self, _context):
layout = self.layout
layout.operator("grease_pencil.stroke_subdivide", text="Subdivide")
layout.operator("grease_pencil.stroke_subdivide_smooth", text="Subdivide and Smooth")
layout.operator("grease_pencil.stroke_simplify", text="Simplify")
layout.separator()
layout.menu("VIEW3D_MT_grease_pencil_assign_material")
layout.operator("grease_pencil.set_active_material")
layout.separator()
@ -8133,6 +8140,27 @@ class VIEW3D_MT_greasepencil_material_active(Menu):
layout.operator("grease_pencil.set_material", text=mat.name, icon_value=icon).slot = mat.name
class VIEW3D_MT_grease_pencil_assign_material(Menu):
bl_label = "Assign Material"
def draw(self, context):
layout = self.layout
ob = context.active_object
mat_active = ob.active_material
if len(ob.material_slots) == 0:
row = layout.row()
row.label(text="No Materials")
row.enabled = False
return
for slot in ob.material_slots:
mat = slot.material
if mat:
layout.operator("grease_pencil.stroke_material_set", text=mat.name,
icon='LAYER_ACTIVE' if mat == mat_active else 'BLANK1').material = mat.name
class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
bl_label = ""
@ -8152,6 +8180,8 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
col.label(text="Point", icon='GP_SELECT_POINTS')
# Main Strokes Operators
col.operator("grease_pencil.stroke_subdivide", text="Subdivide")
col.operator("grease_pencil.stroke_subdivide_smooth", text="Subdivide and Smooth")
col.operator("grease_pencil.stroke_simplify", text="Simplify")
col.separator()
@ -8178,6 +8208,8 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
col.label(text="Stroke", icon='GP_SELECT_STROKES')
# Main Strokes Operators
col.operator("grease_pencil.stroke_subdivide", text="Subdivide")
col.operator("grease_pencil.stroke_subdivide_smooth", text="Subdivide and Smooth")
col.operator("grease_pencil.stroke_simplify", text="Simplify")
col.separator()
@ -8188,6 +8220,11 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
col.separator()
col.menu("VIEW3D_MT_grease_pencil_assign_material")
col.operator("grease_pencil.set_active_material", text="Set as Active Material")
col.separator()
col.menu("VIEW3D_MT_mirror")
@ -8884,6 +8921,7 @@ classes = (
VIEW3D_MT_gpencil_autoweights,
VIEW3D_MT_gpencil_edit_context_menu,
VIEW3D_MT_greasepencil_edit_context_menu,
VIEW3D_MT_grease_pencil_assign_material,
VIEW3D_MT_edit_greasepencil,
VIEW3D_MT_edit_greasepencil_delete,
VIEW3D_MT_edit_greasepencil_stroke,

View File

@ -1,8 +1,8 @@
# Example of a group that edits a single property
# using the predefined gizmo arrow.
#
# Usage: Select a light in the 3D view and drag the arrow at it's rear
# to change it's energy value.
# Usage: Select a light in the 3D view and drag the arrow at its rear
# to change its energy value.
#
import bpy
from bpy.types import (

View File

@ -49,8 +49,11 @@ BoneCollection *ANIM_bonecoll_new(const char *name) ATTR_WARN_UNUSED_RESULT;
* of a bArmature. Normally bone collections are owned (and thus managed) by the armature.
*
* \see ANIM_armature_bonecoll_remove
*
* \param do_id_user_count whether to update user counts for IDs referenced from IDProperties of
* the bone collection. Needs to be false when freeing a CoW copy, true otherwise.
*/
void ANIM_bonecoll_free(BoneCollection *bcoll);
void ANIM_bonecoll_free(BoneCollection *bcoll, bool do_id_user_count = true);
/**
* Recalculate the armature & bone runtime data.

View File

@ -73,13 +73,13 @@ BoneCollection *ANIM_bonecoll_new(const char *name)
return bcoll;
}
void ANIM_bonecoll_free(BoneCollection *bcoll)
void ANIM_bonecoll_free(BoneCollection *bcoll, const bool do_id_user_count)
{
BLI_assert_msg(BLI_listbase_is_empty(&bcoll->bones),
"bone collection still has bones assigned to it, will cause dangling pointers in "
"bone runtime data");
if (bcoll->prop) {
IDP_FreeProperty(bcoll->prop);
IDP_FreeProperty_ex(bcoll->prop, do_id_user_count);
}
MEM_delete(bcoll);
}
@ -1157,6 +1157,9 @@ bool armature_bonecoll_is_descendant_of(const bArmature *armature,
const int potential_parent_index,
const int potential_descendant_index)
{
BLI_assert_msg(potential_descendant_index >= 0,
"Potential descendant has to exist for this function call to make sense.");
if (armature_bonecoll_is_child_of(armature, potential_parent_index, potential_descendant_index))
{
/* Found a direct child. */

View File

@ -375,7 +375,7 @@ bool insert_keyframe_direct(ReportList *reports,
PointerRNA tmp_ptr;
if (RNA_path_resolve_property(&ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
const char *idname = (ptr.owner_id) ? ptr.owner_id->name : TIP_("<No ID pointer>");
const char *idname = (ptr.owner_id) ? ptr.owner_id->name : RPT_("<No ID pointer>");
BKE_reportf(reports,
RPT_ERROR,
@ -529,7 +529,7 @@ int insert_keyframe(Main *bmain,
reports,
RPT_ERROR,
"Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
(id) ? id->name : TIP_("<Missing ID block>"),
(id) ? id->name : RPT_("<Missing ID block>"),
rna_path);
return 0;
}

View File

@ -166,7 +166,7 @@ class CurvesGeometry : public ::CurvesGeometry {
/**
* Mutable access to curve types. Call #tag_topology_changed and #update_curve_types after
* changing any type. Consider using the other methods to change types below.
* */
*/
MutableSpan<int8_t> curve_types_for_write();
/** Set all curve types to the value and call #update_curve_types. */
void fill_curve_types(CurveType type);

View File

@ -136,7 +136,7 @@ float driver_get_variable_value(const struct AnimationEvalContext *anim_eval_con
struct DriverVar *dvar);
typedef enum eDriverVariablePropertyResult {
/** The property reference has been succesfully resolved and can be accessed. */
/** The property reference has been successfully resolved and can be accessed. */
DRIVER_VAR_PROPERTY_SUCCESS,
/** Evaluation should use the fallback value. */
DRIVER_VAR_PROPERTY_FALLBACK,

View File

@ -447,6 +447,7 @@ class MeshComponent : public GeometryComponent {
public:
MeshComponent();
MeshComponent(Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
~MeshComponent();
GeometryComponentPtr copy() const override;
@ -501,6 +502,8 @@ class PointCloudComponent : public GeometryComponent {
public:
PointCloudComponent();
PointCloudComponent(PointCloud *pointcloud,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
~PointCloudComponent();
GeometryComponentPtr copy() const override;
@ -561,6 +564,7 @@ class CurveComponent : public GeometryComponent {
public:
CurveComponent();
CurveComponent(Curves *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
~CurveComponent();
GeometryComponentPtr copy() const override;
@ -602,6 +606,8 @@ class InstancesComponent : public GeometryComponent {
public:
InstancesComponent();
InstancesComponent(Instances *instances,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
~InstancesComponent();
GeometryComponentPtr copy() const override;

View File

@ -818,7 +818,6 @@ void BKE_grease_pencil_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil_src,
GreasePencil *grease_pencil_dst);
int BKE_grease_pencil_object_material_index_get(Object *ob, Material *ma);
int BKE_grease_pencil_object_material_index_get_by_name(Object *ob, const char *name);
Material *BKE_grease_pencil_object_material_new(Main *bmain,
Object *ob,

View File

@ -114,6 +114,9 @@ bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob);
bool BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob);
bool BKE_object_material_slot_used(struct Object *object, short actcol);
int BKE_object_material_index_get(Object *ob, Material *ma);
int BKE_object_material_ensure(Main *bmain, Object *ob, Material *material);
struct Material *BKE_gpencil_material(struct Object *ob, short act);
struct MaterialGPencilStyle *BKE_gpencil_material_settings(struct Object *ob, short act);

View File

@ -68,6 +68,22 @@ enum class ModifierTypeType {
enum ModifierTypeFlag {
eModifierTypeFlag_AcceptsMesh = (1 << 0),
eModifierTypeFlag_AcceptsCVs = (1 << 1),
/**
* Modifiers that enable this flag can have the modifiers "On Cage" option toggled,
* see: #eModifierMode_OnCage, where the output of the modifier can be selected directly.
* In some cases the cage geometry use read to tool code as well (loop-cut & knife are examples).
*
* When set, geometry from the resulting mesh can be mapped back to the original indices
* via #CD_ORIGINDEX.
*
* While many modifiers using this flag preserve the order of geometry arrays,
* this isn't always the case, this flag doesn't imply #ModifierTypeType::OnlyDeform.
* Geometry from the original mesh may be removed from the resulting mesh or new geometry
* may be added (where the #CD_ORIGINDEX value will be #ORIGINDEX_NONE).
*
* Modifiers that create entirely new geometry from the input should not enable this flag
* because none of the geometry will be selectable when "On Cage" is enabled.
*/
eModifierTypeFlag_SupportsMapping = (1 << 2),
eModifierTypeFlag_SupportsEditmode = (1 << 3),

View File

@ -1327,7 +1327,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define GEO_NODE_BAKE 2120
#define GEO_NODE_GET_NAMED_GRID 2121
#define GEO_NODE_STORE_NAMED_GRID 2122
#define GEO_NODE_OBJECT_TRANSFORM 2123
#define GEO_NODE_SORT_ELEMENTS 2123
#define GEO_NODE_OBJECT_TRANSFORM 2124
/** \} */

View File

@ -8,6 +8,8 @@
* \ingroup bke
*/
#include <iosfwd>
#include "DNA_node_types.h"
#include "BLI_vector.hh"
@ -42,6 +44,8 @@ class bNodeTreeZone {
bool contains_node_recursively(const bNode &node) const;
bool contains_zone_recursively(const bNodeTreeZone &other_zone) const;
friend std::ostream &operator<<(std::ostream &stream, const bNodeTreeZone &zone);
};
class bNodeTreeZones {
@ -72,6 +76,8 @@ class bNodeTreeZones {
* nested zone. For nodes that are at the root level, the returned list is empty.
*/
Vector<const bNodeTreeZone *> get_zone_stack_for_node(const int32_t node_id) const;
friend std::ostream &operator<<(std::ostream &stream, const bNodeTreeZones &zones);
};
const bNodeTreeZones *get_tree_zones(const bNodeTree &tree);

View File

@ -87,7 +87,14 @@ struct ObjectRuntime {
*/
Mesh *mesh_deform_eval = nullptr;
/* Evaluated mesh cage in edit mode. */
/**
* Evaluated mesh cage in edit mode.
*
* \note When the mesh's `runtime->deformed_only` is true, the meshes vertex positions
* and other geometry arrays will be aligned the edit-mesh. Otherwise the #CD_ORIGINDEX
* custom-data should be used to map the cage geometry back to the original indices, see
* #eModifierTypeFlag_SupportsMapping.
*/
Mesh *editmesh_eval_cage = nullptr;
/**

View File

@ -9,20 +9,13 @@
* \brief General operations for point clouds.
*/
#ifdef __cplusplus
# include <mutex>
#include <mutex>
# include "BLI_bounds_types.hh"
# include "BLI_math_vector_types.hh"
# include "BLI_shared_cache.hh"
#include "BLI_bounds_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_shared_cache.hh"
# include "DNA_pointcloud_types.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "DNA_pointcloud_types.h"
struct Depsgraph;
struct Main;
@ -34,7 +27,6 @@ struct Scene;
extern const char *POINTCLOUD_ATTR_POSITION;
extern const char *POINTCLOUD_ATTR_RADIUS;
#ifdef __cplusplus
namespace blender::bke {
struct PointCloudRuntime {
@ -50,8 +42,6 @@ struct PointCloudRuntime {
} // namespace blender::bke
#endif
void *BKE_pointcloud_add(struct Main *bmain, const char *name);
void *BKE_pointcloud_add_default(struct Main *bmain, const char *name);
struct PointCloud *BKE_pointcloud_new_nomain(int totpoint);
@ -79,7 +69,3 @@ void BKE_pointcloud_batch_cache_free(struct PointCloud *pointcloud);
extern void (*BKE_pointcloud_batch_cache_dirty_tag_cb)(struct PointCloud *pointcloud, int mode);
extern void (*BKE_pointcloud_batch_cache_free_cb)(struct PointCloud *pointcloud);
#ifdef __cplusplus
}
#endif

View File

@ -27,6 +27,7 @@ struct BlendWriter;
struct Header;
struct ID;
struct IDRemapper;
struct LayoutPanelState;
struct LibraryForeachIDData;
struct ListBase;
struct Menu;
@ -606,6 +607,14 @@ void BKE_screen_area_free(ScrArea *area);
void BKE_region_callback_free_gizmomap_set(void (*callback)(wmGizmoMap *));
void BKE_region_callback_refresh_tag_gizmomap_set(void (*callback)(wmGizmoMap *));
/**
* Get the layout panel state for the given idname. If it does not exist yet, initialize a new
* panel state with the given default value.
*/
LayoutPanelState *BKE_panel_layout_panel_state_ensure(Panel *panel,
const char *idname,
bool default_closed);
/**
* Find a region of type \a region_type in provided \a regionbase.
*

View File

@ -48,7 +48,7 @@ extern void sbFreeSimulation(struct SoftBody *sb);
/**
* Do one simulation step, reading and writing vertex locs from given array.
* */
*/
extern void sbObjectStep(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,

View File

@ -37,7 +37,7 @@ enum eSubdivFVarLinearInterpolation {
};
struct SubdivSettings {
/* Simple subdivision corresponds to "Simple" option in the interface. When it's enabled the
/* Simple subdivision corresponds to "Simple" option in the interface. When it's enabled, the
* subdivided mesh is not "smoothed": new vertices are added uniformly on the existing surface.
*
* On an OpenSubdiv implementation level this translates to a subdivision scheme:

View File

@ -29,7 +29,7 @@ struct EditFontSelBox {
/**
* Edit data for #Curve (a text curve, with an #Object::type of `OB_FONT`).
* */
*/
struct EditFont {
/** Array of UTF32 code-points. */
char32_t *textbuf;

View File

@ -475,7 +475,7 @@ set(SRC
BKE_pbvh_api.hh
BKE_pbvh_pixels.hh
BKE_pointcache.h
BKE_pointcloud.h
BKE_pointcloud.hh
BKE_pose_backup.h
BKE_preferences.h
BKE_preview_image.hh

View File

@ -3235,7 +3235,7 @@ static void animsys_create_action_track_strip(const AnimData *adt,
/* Must set NLASTRIP_FLAG_USR_INFLUENCE, or else the default setting overrides, and influence
* doesn't work.
*/
r_action_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
r_action_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE | NLASTRIP_FLAG_NO_TIME_MAP;
const bool tweaking = (adt->flag & ADT_NLA_EDIT_ON) != 0;
const bool soloing = (adt->flag & ADT_NLA_SOLO_TRACK) != 0;

View File

@ -137,7 +137,7 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports,
(pchan) ? pchan->name : ob->id.name,
avs->path_sf,
avs->path_ef,
(avs->path_sf == avs->path_ef) ? TIP_(", cannot have single-frame paths") : "");
(avs->path_sf == avs->path_ef) ? RPT_(", cannot have single-frame paths") : "");
return nullptr;
}

View File

@ -95,16 +95,19 @@ static void armature_init_data(ID *id)
*
* Note: this function's use case is narrow in scope, intended only for use in
* `armature_copy_data()` below. You probably don't want to use this otherwise.
*
* \param lib_id_flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more).
*/
static void copy_bone_collection(bArmature *armature_dst,
BoneCollection *&bcoll_dst,
const BoneCollection *bcoll_src)
const BoneCollection *bcoll_src,
const int lib_id_flag)
{
bcoll_dst = static_cast<BoneCollection *>(MEM_dupallocN(bcoll_src));
/* ID properties. */
if (bcoll_dst->prop) {
bcoll_dst->prop = IDP_CopyProperty(bcoll_dst->prop);
bcoll_dst->prop = IDP_CopyProperty_ex(bcoll_dst->prop, lib_id_flag);
}
/* Bone references. */
@ -169,8 +172,10 @@ static void armature_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, c
MEM_dupallocN(armature_src->collection_array));
armature_dst->collection_array_num = armature_src->collection_array_num;
for (int i = 0; i < armature_src->collection_array_num; i++) {
copy_bone_collection(
armature_dst, armature_dst->collection_array[i], armature_src->collection_array[i]);
copy_bone_collection(armature_dst,
armature_dst->collection_array[i],
armature_src->collection_array[i],
flag);
}
}
else {
@ -193,7 +198,7 @@ static void armature_free_data(ID *id)
if (armature->collection_array) {
for (BoneCollection *bcoll : armature->collections_span()) {
BLI_freelistN(&bcoll->bones);
ANIM_bonecoll_free(bcoll);
ANIM_bonecoll_free(bcoll, false);
}
MEM_freeN(armature->collection_array);
}

View File

@ -32,7 +32,7 @@
#include "BKE_editmesh.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_report.h"
#include "RNA_access.hh"

View File

@ -943,29 +943,6 @@ void gather_attributes(const AttributeAccessor src_attributes,
});
}
static bool indices_are_range(const Span<int> indices, const IndexRange range)
{
if (indices.size() != range.size()) {
return false;
}
return threading::parallel_reduce(
range,
4096,
true,
[&](const IndexRange range, const bool init) {
if (!init) {
return false;
}
for (const int i : range) {
if (indices[i] != i) {
return false;
}
}
return true;
},
std::logical_and());
}
void gather_attributes(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
@ -973,7 +950,7 @@ void gather_attributes(const AttributeAccessor src_attributes,
const Span<int> indices,
MutableAttributeAccessor dst_attributes)
{
if (indices_are_range(indices, IndexRange(src_attributes.domain_size(domain)))) {
if (array_utils::indices_are_range(indices, IndexRange(src_attributes.domain_size(domain)))) {
copy_attributes(src_attributes, domain, propagation_info, skip, dst_attributes);
}
else {

View File

@ -8,7 +8,7 @@
#include "BKE_instances.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BLI_endian_defines.h"
#include "BLI_endian_switch.h"

View File

@ -9,7 +9,7 @@
#include "BKE_instances.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BLI_endian_defines.h"
#include "BLI_endian_switch.h"

View File

@ -28,7 +28,7 @@
#include "BKE_editmesh.hh"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "MEM_guardedalloc.h"

View File

@ -4761,16 +4761,16 @@ bool BKE_nurb_valid_message(const int pnts,
message_dst[0] = 0;
return false;
}
msg_template = TIP_("At least two points required");
msg_template = RPT_("At least two points required");
break;
case NURBSValidationStatus::MorePointsThanOrderRequired:
msg_template = TIP_("Must have more control points than Order");
msg_template = RPT_("Must have more control points than Order");
break;
case NURBSValidationStatus::MoreRowsForBezierRequired:
msg_template = TIP_("%d more %s row(s) needed for Bezier");
msg_template = RPT_("%d more %s row(s) needed for Bezier");
break;
case NURBSValidationStatus::MorePointsForBezierRequired:
msg_template = TIP_("%d more point(s) needed for Bezier");
msg_template = RPT_("%d more point(s) needed for Bezier");
break;
}

View File

@ -230,8 +230,10 @@ const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
Mesh *mesh_cage = BKE_object_get_editmesh_eval_cage(ob);
if (Mesh *mesh_cage = BKE_object_get_editmesh_eval_cage(ob)) {
if (mesh_cage && mesh_cage->runtime->deformed_only) {
BLI_assert(BKE_mesh_wrapper_vert_len(mesh_cage) == em->bm->totvert);
/* Deformed, and we have deformed coords already. */
coords = BKE_mesh_wrapper_vert_coords(mesh_cage);
}

View File

@ -27,6 +27,11 @@ namespace blender::bke {
CurveComponent::CurveComponent() : GeometryComponent(Type::Curve) {}
CurveComponent::CurveComponent(Curves *curve, GeometryOwnershipType ownership)
: GeometryComponent(Type::Curve), curves_(curve), ownership_(ownership)
{
}
CurveComponent::~CurveComponent()
{
this->clear();

View File

@ -32,6 +32,11 @@ namespace blender::bke {
InstancesComponent::InstancesComponent() : GeometryComponent(Type::Instance) {}
InstancesComponent::InstancesComponent(Instances *instances, GeometryOwnershipType ownership)
: GeometryComponent(Type::Instance), instances_(instances), ownership_(ownership)
{
}
InstancesComponent::~InstancesComponent()
{
this->clear();

View File

@ -28,6 +28,11 @@ namespace blender::bke {
MeshComponent::MeshComponent() : GeometryComponent(Type::Mesh) {}
MeshComponent::MeshComponent(Mesh *mesh, GeometryOwnershipType ownership)
: GeometryComponent(Type::Mesh), mesh_(mesh), ownership_(ownership)
{
}
MeshComponent::~MeshComponent()
{
this->clear();

View File

@ -6,7 +6,7 @@
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "attribute_access_intern.hh"
@ -18,6 +18,11 @@ namespace blender::bke {
PointCloudComponent::PointCloudComponent() : GeometryComponent(Type::PointCloud) {}
PointCloudComponent::PointCloudComponent(PointCloud *pointcloud, GeometryOwnershipType ownership)
: GeometryComponent(Type::PointCloud), pointcloud_(pointcloud), ownership_(ownership)
{
}
PointCloudComponent::~PointCloudComponent()
{
this->clear();

View File

@ -11,7 +11,7 @@
#include "BKE_grease_pencil.hh"
#include "BKE_instances.hh"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_type_conversions.hh"
#include "DNA_mesh_types.h"

View File

@ -19,7 +19,7 @@
#include "BKE_mesh_wrapper.hh"
#include "BKE_modifier.hh"
#include "BKE_object_types.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_volume.hh"
#include "DNA_collection_types.h"

View File

@ -542,7 +542,7 @@ void BKE_gpencil_modifier_set_error(GpencilModifierData *md, const char *format,
{
char buffer[512];
va_list ap;
const char *format_tip = TIP_(format);
const char *format_tip = RPT_(format);
va_start(ap, format);
vsnprintf(buffer, sizeof(buffer), format_tip, ap);

View File

@ -1223,19 +1223,6 @@ void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil
/** \name Grease Pencil material functions
* \{ */
int BKE_grease_pencil_object_material_index_get(Object *ob, Material *ma)
{
short *totcol = BKE_object_material_len_p(ob);
Material *read_ma = nullptr;
for (short i = 0; i < *totcol; i++) {
read_ma = BKE_object_material_get(ob, i + 1);
if (ma == read_ma) {
return i;
}
}
return -1;
}
int BKE_grease_pencil_object_material_index_get_by_name(Object *ob, const char *name)
{
short *totcol = BKE_object_material_len_p(ob);
@ -1311,7 +1298,7 @@ Material *BKE_grease_pencil_object_material_ensure_from_brush(Main *bmain,
Material *ma = BKE_grease_pencil_brush_material_get(brush);
/* check if the material is already on object material slots and add it if missing */
if (ma && BKE_grease_pencil_object_material_index_get(ob, ma) < 0) {
if (ma && BKE_object_material_index_get(ob, ma) < 0) {
BKE_object_material_slot_add(bmain, ob);
BKE_object_material_assign(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
}

View File

@ -823,6 +823,33 @@ void BKE_id_material_eval_ensure_default_slot(ID *id)
}
}
int BKE_object_material_index_get(Object *ob, Material *ma)
{
short *totcol = BKE_object_material_len_p(ob);
Material *read_ma = nullptr;
for (short i = 0; i < *totcol; i++) {
read_ma = BKE_object_material_get(ob, i + 1);
if (ma == read_ma) {
return i;
}
}
return -1;
}
int BKE_object_material_ensure(Main *bmain, Object *ob, Material *material)
{
if (!material) {
return -1;
}
int index = BKE_object_material_index_get(ob, material);
if (index < 0) {
BKE_object_material_slot_add(bmain, ob);
BKE_object_material_assign(bmain, ob, material, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
return ob->totcol - 1;
}
return index;
}
Material *BKE_gpencil_material(Object *ob, short act)
{
Material *ma = BKE_object_material_get(ob, act);

View File

@ -49,7 +49,7 @@
/* -- */
#include "BKE_object.hh"
/* -- */
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_curve_to_mesh.hh"

View File

@ -74,9 +74,9 @@ MeshRuntime::~MeshRuntime()
static int reset_bits_and_count(MutableBitSpan bits, const Span<int> indices_to_reset)
{
int count = bits.size();
for (const int vert : indices_to_reset) {
if (bits[vert]) {
bits[vert].reset();
for (const int i : indices_to_reset) {
if (bits[i]) {
bits[i].reset();
count--;
}
}

View File

@ -419,7 +419,7 @@ void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_for
{
char buffer[512];
va_list ap;
const char *format = TIP_(_format);
const char *format = RPT_(_format);
va_start(ap, _format);
vsnprintf(buffer, sizeof(buffer), format, ap);
@ -446,7 +446,7 @@ void BKE_modifier_set_warning(const Object *ob, ModifierData *md, const char *_f
{
char buffer[512];
va_list ap;
const char *format = TIP_(_format);
const char *format = RPT_(_format);
va_start(ap, _format);
vsnprintf(buffer, sizeof(buffer), format, ap);
@ -1263,7 +1263,7 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
BLO_reportf_wrap(
BLO_read_data_reports(reader),
RPT_WARNING,
TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
RPT_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
md->name,
ob->id.name + 2);
md = modifier_replace_with_fluid(reader, ob, lb, md);
@ -1273,7 +1273,7 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
BLO_reportf_wrap(
BLO_read_data_reports(reader),
RPT_WARNING,
TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
RPT_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
md->name,
ob->id.name + 2);
md = modifier_replace_with_fluid(reader, ob, lb, md);

View File

@ -2,6 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include <iostream>
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_zones.hh"
@ -351,6 +353,7 @@ static std::unique_ptr<bNodeTreeZones> discover_tree_zones(const bNodeTree &tree
update_zone_border_links(tree, *tree_zones);
// std::cout << *tree_zones << std::endl;
return tree_zones;
}
@ -522,4 +525,37 @@ const bNodeZoneType *zone_type_by_node_type(const int node_type)
return nullptr;
}
std::ostream &operator<<(std::ostream &stream, const bNodeTreeZones &zones)
{
for (const std::unique_ptr<bNodeTreeZone> &zone : zones.zones) {
stream << *zone;
if (zones.zones.last().get() != zone.get()) {
stream << "\n";
}
}
return stream;
}
std::ostream &operator<<(std::ostream &stream, const bNodeTreeZone &zone)
{
stream << zone.index << ": Parent index: ";
if (zone.parent_zone != nullptr) {
stream << zone.parent_zone->index;
}
else {
stream << "*";
}
stream << "; Input: " << (zone.input_node ? zone.input_node->name : "null");
stream << ", Output: " << (zone.output_node ? zone.output_node->name : "null");
stream << "; Border Links: {\n";
for (const bNodeLink *border_link : zone.border_links) {
stream << " " << border_link->fromnode->name << ": " << border_link->fromsock->name << " -> ";
stream << border_link->tonode->name << ": " << border_link->tosock->name << ";\n";
}
stream << "}.";
return stream;
}
} // namespace blender::bke

View File

@ -119,7 +119,7 @@
#include "BKE_paint.hh"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_pose_backup.h"
#include "BKE_preview_image.hh"
#include "BKE_rigidbody.h"
@ -915,12 +915,12 @@ static void object_blend_read_after_liblink(BlendLibReader *reader, ID *id)
if (ob->id.lib) {
BLO_reportf_wrap(reports,
RPT_INFO,
TIP_("Can't find object data of %s lib %s"),
RPT_("Can't find object data of %s lib %s"),
ob->id.name + 2,
ob->id.lib->filepath);
}
else {
BLO_reportf_wrap(reports, RPT_INFO, TIP_("Object %s lost data"), ob->id.name + 2);
BLO_reportf_wrap(reports, RPT_INFO, RPT_("Object %s lost data"), ob->id.name + 2);
}
reports->count.missing_obdata++;
}

View File

@ -47,7 +47,7 @@
#include "BKE_object_types.hh"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_scene.h"
#include "BKE_volume.hh"

View File

@ -1221,7 +1221,7 @@ static void update_normals_faces(PBVH &pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
*
* Those boundary face and vertex indices are deduplicated with #VectorSet in order to avoid
* duplicate work recalculation for the same vertex, and to make parallel storage for vertices
* during reclculation thread-safe. */
* during recalculation thread-safe. */
const Span<float3> positions = pbvh.vert_positions;
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();

View File

@ -3691,13 +3691,13 @@ void BKE_ptcache_update_info(PTCacheID *pid)
/* smoke doesn't use frame 0 as info frame so can't check based on totpoint */
if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN && totframes) {
SNPRINTF(cache->info, TIP_("%i frames found!"), totframes);
SNPRINTF(cache->info, RPT_("%i frames found!"), totframes);
}
else if (totframes && cache->totpoint) {
SNPRINTF(cache->info, TIP_("%i points found!"), cache->totpoint);
SNPRINTF(cache->info, RPT_("%i points found!"), cache->totpoint);
}
else {
STRNCPY(cache->info, TIP_("No valid data to read!"));
STRNCPY(cache->info, RPT_("No valid data to read!"));
}
return;
}
@ -3707,10 +3707,10 @@ void BKE_ptcache_update_info(PTCacheID *pid)
int totpoint = pid->totpoint(pid->calldata, 0);
if (cache->totpoint > totpoint) {
SNPRINTF(mem_info, TIP_("%i cells + High Resolution cached"), totpoint);
SNPRINTF(mem_info, RPT_("%i cells + High Resolution cached"), totpoint);
}
else {
SNPRINTF(mem_info, TIP_("%i cells cached"), totpoint);
SNPRINTF(mem_info, RPT_("%i cells cached"), totpoint);
}
}
else {
@ -3722,7 +3722,7 @@ void BKE_ptcache_update_info(PTCacheID *pid)
}
}
SNPRINTF(mem_info, TIP_("%i frames on disk"), totframes);
SNPRINTF(mem_info, RPT_("%i frames on disk"), totframes);
}
}
else {
@ -3750,14 +3750,14 @@ void BKE_ptcache_update_info(PTCacheID *pid)
BLI_str_format_int_grouped(formatted_tot, totframes);
BLI_str_format_byte_unit(formatted_mem, bytes, false);
SNPRINTF(mem_info, TIP_("%s frames in memory (%s)"), formatted_tot, formatted_mem);
SNPRINTF(mem_info, RPT_("%s frames in memory (%s)"), formatted_tot, formatted_mem);
}
if (cache->flag & PTCACHE_OUTDATED) {
SNPRINTF(cache->info, TIP_("%s, cache is outdated!"), mem_info);
SNPRINTF(cache->info, RPT_("%s, cache is outdated!"), mem_info);
}
else if (cache->flag & PTCACHE_FRAMES_SKIPPED) {
SNPRINTF(cache->info, TIP_("%s, not exact since frame %i"), mem_info, cache->last_exact);
SNPRINTF(cache->info, RPT_("%s, not exact since frame %i"), mem_info, cache->last_exact);
}
else {
SNPRINTF(cache->info, "%s.", mem_info);

View File

@ -37,7 +37,7 @@
#include "BKE_modifier.hh"
#include "BKE_object.hh"
#include "BKE_object_types.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BLT_translation.h"

View File

@ -29,25 +29,25 @@ const char *BKE_report_type_str(eReportType type)
{
switch (type) {
case RPT_DEBUG:
return TIP_("Debug");
return RPT_("Debug");
case RPT_INFO:
return TIP_("Info");
return RPT_("Info");
case RPT_OPERATOR:
return TIP_("Operator");
return RPT_("Operator");
case RPT_PROPERTY:
return TIP_("Property");
return RPT_("Property");
case RPT_WARNING:
return TIP_("Warning");
return RPT_("Warning");
case RPT_ERROR:
return TIP_("Error");
return RPT_("Error");
case RPT_ERROR_INVALID_INPUT:
return TIP_("Invalid Input Error");
return RPT_("Invalid Input Error");
case RPT_ERROR_INVALID_CONTEXT:
return TIP_("Invalid Context Error");
return RPT_("Invalid Context Error");
case RPT_ERROR_OUT_OF_MEMORY:
return TIP_("Out Of Memory Error");
return RPT_("Out Of Memory Error");
default:
return TIP_("Undefined Type");
return RPT_("Undefined Type");
}
}
@ -126,7 +126,7 @@ void BKE_report(ReportList *reports, eReportType type, const char *_message)
{
Report *report;
int len;
const char *message = TIP_(_message);
const char *message = RPT_(_message);
if (BKE_reports_print_test(reports, type)) {
printf("%s: %s\n", BKE_report_type_str(type), message);
@ -154,7 +154,7 @@ void BKE_reportf(ReportList *reports, eReportType type, const char *_format, ...
{
Report *report;
va_list args;
const char *format = TIP_(_format);
const char *format = RPT_(_format);
if (BKE_reports_print_test(reports, type)) {
printf("%s: ", BKE_report_type_str(type));
@ -207,7 +207,7 @@ void BKE_reports_prepend(ReportList *reports, const char *prepend)
if (!reports || !reports->list.first) {
return;
}
reports_prepend_impl(reports, TIP_(prepend));
reports_prepend_impl(reports, RPT_(prepend));
}
void BKE_reports_prependf(ReportList *reports, const char *prepend_format, ...)
@ -217,7 +217,7 @@ void BKE_reports_prependf(ReportList *reports, const char *prepend_format, ...)
}
va_list args;
va_start(args, prepend_format);
char *prepend = BLI_vsprintfN(TIP_(prepend_format), args);
char *prepend = BLI_vsprintfN(RPT_(prepend_format), args);
va_end(args);
reports_prepend_impl(reports, prepend);

View File

@ -502,7 +502,11 @@ static void scene_foreach_toolsettings_id_pointer_process(
ID *id_old_new = id_old != nullptr ? BLO_read_get_new_id_address_from_session_uuid(
reader, id_old->session_uuid) :
nullptr;
if (!ELEM(id_old_new, id_old, nullptr)) {
/* The new address may be the same as the old one, in which case there is nothing to do. */
if (id_old_new == id_old) {
break;
}
if (id_old_new != nullptr) {
BLI_assert(id_old == id_old_new->orig_id);
*id_old_p = id_old_new;
if (cb_flag & IDWALK_CB_USER) {
@ -518,7 +522,7 @@ static void scene_foreach_toolsettings_id_pointer_process(
* There is a nasty twist here though: a previous call to 'undo_preserve' on the Scene ID may
* have modified it, even though the undo step detected it as unmodified. In such case, the
* value of `*id_p` may end up also pointing to an invalid (no more in newly read Main) ID,
* se it also needs to be checked from its `session_uuid`. */
* so it also needs to be checked from its `session_uuid`. */
ID *id = *id_p;
ID *id_new = id != nullptr ?
BLO_read_get_new_id_address_from_session_uuid(reader, id->session_uuid) :
@ -1543,7 +1547,7 @@ static void scene_blend_read_after_liblink(BlendLibReader *reader, ID *id)
if (base_legacy->object == nullptr) {
BLO_reportf_wrap(BLO_read_lib_reports(reader),
RPT_WARNING,
TIP_("LIB: object lost from scene: '%s'"),
RPT_("LIB: object lost from scene: '%s'"),
sce->id.name + 2);
BLI_remlink(&sce->base, base_legacy);
if (base_legacy == sce->basact) {

View File

@ -323,6 +323,14 @@ static void panel_list_copy(ListBase *newlb, const ListBase *lb)
new_panel->runtime = new_runtime;
new_panel->activedata = nullptr;
new_panel->drawname = nullptr;
BLI_listbase_clear(&new_panel->layout_panel_states);
LISTBASE_FOREACH (LayoutPanelState *, src_state, &old_panel->layout_panel_states) {
LayoutPanelState *new_state = MEM_new<LayoutPanelState>(__func__, *src_state);
new_state->idname = BLI_strdup(src_state->idname);
BLI_addtail(&new_panel->layout_panel_states, new_state);
}
BLI_addtail(newlb, new_panel);
panel_list_copy(&new_panel->children, &old_panel->children);
}
@ -487,6 +495,22 @@ void BKE_region_callback_free_gizmomap_set(void (*callback)(wmGizmoMap *))
region_free_gizmomap_callback = callback;
}
LayoutPanelState *BKE_panel_layout_panel_state_ensure(Panel *panel,
const char *idname,
const bool default_closed)
{
LISTBASE_FOREACH (LayoutPanelState *, state, &panel->layout_panel_states) {
if (STREQ(state->idname, idname)) {
return state;
}
}
LayoutPanelState *state = MEM_cnew<LayoutPanelState>(__func__);
state->idname = BLI_strdup(idname);
SET_FLAG_FROM_TEST(state->flag, !default_closed, LAYOUT_PANEL_STATE_FLAG_OPEN);
BLI_addtail(&panel->layout_panel_states, state);
return state;
}
Panel *BKE_panel_new(PanelType *panel_type)
{
Panel *panel = MEM_cnew<Panel>(__func__);
@ -502,6 +526,12 @@ void BKE_panel_free(Panel *panel)
{
MEM_SAFE_FREE(panel->activedata);
MEM_SAFE_FREE(panel->drawname);
LISTBASE_FOREACH (LayoutPanelState *, state, &panel->layout_panel_states) {
MEM_freeN(state->idname);
}
BLI_freelistN(&panel->layout_panel_states);
MEM_delete(panel->runtime);
MEM_freeN(panel);
}
@ -1054,6 +1084,10 @@ static void write_panel_list(BlendWriter *writer, ListBase *lb)
{
LISTBASE_FOREACH (Panel *, panel, lb) {
BLO_write_struct(writer, Panel, panel);
BLO_write_struct_list(writer, LayoutPanelState, &panel->layout_panel_states);
LISTBASE_FOREACH (LayoutPanelState *, state, &panel->layout_panel_states) {
BLO_write_string(writer, state->idname);
}
write_panel_list(writer, &panel->children);
}
}
@ -1116,6 +1150,10 @@ static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb)
panel->activedata = nullptr;
panel->type = nullptr;
panel->drawname = nullptr;
BLO_read_list(reader, &panel->layout_panel_states);
LISTBASE_FOREACH (LayoutPanelState *, state, &panel->layout_panel_states) {
BLO_read_data_address(reader, &state->idname);
}
direct_link_panel_list(reader, &panel->children);
}
}

View File

@ -83,6 +83,19 @@ inline void scatter(const Span<T> src,
});
}
template<typename T>
inline void scatter(const Span<T> src,
const IndexMask &indices,
MutableSpan<T> dst,
const int64_t grain_size = 4096)
{
BLI_assert(indices.size() == src.size());
BLI_assert(indices.min_array_size() <= dst.size());
indices.foreach_index_optimized<int64_t>(
GrainSize(grain_size),
[&](const int64_t index, const int64_t pos) { dst[index] = src[pos]; });
}
/**
* Fill the destination span by gathering indexed values from the `src` array.
*/
@ -281,4 +294,6 @@ bool indexed_data_equal(const Span<T> all_values, const Span<int> indices, const
return false;
}
bool indices_are_range(Span<int> indices, IndexRange range);
} // namespace blender::array_utils

View File

@ -155,6 +155,8 @@ void copy_group_sizes(OffsetIndices<int> offsets, const IndexMask &mask, Mutable
/** Gather the number of indices in each indexed group to sizes. */
void gather_group_sizes(OffsetIndices<int> offsets, const IndexMask &mask, MutableSpan<int> sizes);
void gather_group_sizes(OffsetIndices<int> offsets, Span<int> indices, MutableSpan<int> sizes);
/** Build new offsets that contains only the groups chosen by \a selection. */
OffsetIndices<int> gather_selected_offsets(OffsetIndices<int> src_offsets,
const IndexMask &selection,

View File

@ -2,6 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include <functional>
#include "BLI_array_utils.hh"
#include "BLI_threads.h"
@ -196,4 +198,22 @@ int64_t count_booleans(const VArray<bool> &varray)
return count_booleans(varray, IndexMask(varray.size()));
}
bool indices_are_range(Span<int> indices, IndexRange range)
{
if (indices.size() != range.size()) {
return false;
}
return threading::parallel_reduce(
range.index_range(),
4096,
true,
[&](const IndexRange part, const bool is_range) {
const Span<int> local_indices = indices.slice(part);
const IndexRange local_range = range.slice(part);
return is_range &&
std::equal(local_indices.begin(), local_indices.end(), local_range.begin());
},
std::logical_and<bool>());
}
} // namespace blender::array_utils

View File

@ -48,6 +48,17 @@ void gather_group_sizes(const OffsetIndices<int> offsets,
});
}
void gather_group_sizes(const OffsetIndices<int> offsets,
const Span<int> indices,
MutableSpan<int> sizes)
{
threading::parallel_for(indices.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
sizes[i] = offsets[indices[i]].size();
}
});
}
OffsetIndices<int> gather_selected_offsets(const OffsetIndices<int> src_offsets,
const IndexMask &selection,
const int start_offset,

View File

@ -1113,7 +1113,7 @@ static bool is_minversion_older_than_blender(FileData *fd, ReportList *reports)
}
BKE_reportf(reports,
RPT_ERROR,
TIP_("The file was saved by a newer version, open it with Blender %s or later"),
"The file was saved by a newer version, open it with Blender %s or later",
min_reader_ver_str);
CLOG_WARN(&LOG,
"%s: File saved by a newer version of Blender (%s), Blender %s or later is "
@ -1172,7 +1172,7 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
RPT_WARNING,
"Unable to read '%s': %s",
filepath,
errno ? strerror(errno) : TIP_("insufficient content"));
errno ? strerror(errno) : RPT_("insufficient content"));
if (rawfile) {
rawfile->close(rawfile);
}
@ -1232,7 +1232,7 @@ static FileData *blo_filedata_from_file_open(const char *filepath, BlendFileRead
RPT_WARNING,
"Unable to open '%s': %s",
filepath,
errno ? strerror(errno) : TIP_("unknown error reading file"));
errno ? strerror(errno) : RPT_("unknown error reading file"));
return nullptr;
}
return blo_filedata_from_file_descriptor(filepath, reports, file);
@ -1272,7 +1272,7 @@ FileData *blo_filedata_from_memory(const void *mem, int memsize, BlendFileReadRe
{
if (!mem || memsize < SIZEOFBLENDERHEADER) {
BKE_report(
reports->reports, RPT_WARNING, (mem) ? TIP_("Unable to read") : TIP_("Unable to open"));
reports->reports, RPT_WARNING, (mem) ? RPT_("Unable to read") : RPT_("Unable to open"));
return nullptr;
}
@ -2275,7 +2275,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
if (BLI_path_cmp(newmain->curlib->filepath_abs, lib->filepath_abs) == 0) {
BLO_reportf_wrap(fd->reports,
RPT_WARNING,
TIP_("Library '%s', '%s' had multiple instances, save and reload!"),
RPT_("Library '%s', '%s' had multiple instances, save and reload!"),
lib->filepath,
lib->filepath_abs);
@ -4032,7 +4032,7 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
BLO_reportf_wrap(fd->reports,
RPT_WARNING,
TIP_("LIB: Data refers to main .blend file: '%s' from %s"),
RPT_("LIB: Data refers to main .blend file: '%s' from %s"),
idname,
mainvar->curlib->filepath_abs);
return;
@ -4546,7 +4546,7 @@ static void read_library_linked_id(
if (!is_valid) {
BLO_reportf_wrap(basefd->reports,
RPT_ERROR,
TIP_("LIB: %s: '%s' is directly linked from '%s' (parent '%s'), but is a "
RPT_("LIB: %s: '%s' is directly linked from '%s' (parent '%s'), but is a "
"non-linkable data type"),
BKE_idtype_idcode_to_name(GS(id->name)),
id->name + 2,
@ -4565,7 +4565,7 @@ static void read_library_linked_id(
else {
BLO_reportf_wrap(basefd->reports,
RPT_INFO,
TIP_("LIB: %s: '%s' missing from '%s', parent '%s'"),
RPT_("LIB: %s: '%s' missing from '%s', parent '%s'"),
BKE_idtype_idcode_to_name(GS(id->name)),
id->name + 2,
mainvar->curlib->filepath_abs,
@ -4679,7 +4679,7 @@ static FileData *read_library_file_data(FileData *basefd,
BLO_reportf_wrap(basefd->reports,
RPT_INFO,
TIP_("Read packed library: '%s', parent '%s'"),
RPT_("Read packed library: '%s', parent '%s'"),
mainptr->curlib->filepath,
library_parent_filepath(mainptr->curlib));
fd = blo_filedata_from_memory(pf->data, pf->size, basefd->reports);
@ -4691,7 +4691,7 @@ static FileData *read_library_file_data(FileData *basefd,
/* Read file on disk. */
BLO_reportf_wrap(basefd->reports,
RPT_INFO,
TIP_("Read library: '%s', '%s', parent '%s'"),
RPT_("Read library: '%s', '%s', parent '%s'"),
mainptr->curlib->filepath_abs,
mainptr->curlib->filepath,
library_parent_filepath(mainptr->curlib));
@ -4732,7 +4732,7 @@ static FileData *read_library_file_data(FileData *basefd,
if (fd == nullptr) {
BLO_reportf_wrap(
basefd->reports, RPT_INFO, TIP_("Cannot find lib '%s'"), mainptr->curlib->filepath_abs);
basefd->reports, RPT_INFO, RPT_("Cannot find lib '%s'"), mainptr->curlib->filepath_abs);
basefd->reports->count.missing_libraries++;
}

View File

@ -2961,7 +2961,7 @@ void do_versions_after_linking_280(FileData *fd, Main *bmain)
if (ob->type != OB_EMPTY && ob->instance_collection != nullptr) {
BLO_reportf_wrap(fd->reports,
RPT_INFO,
TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
RPT_("Non-Empty object '%s' cannot duplicate collection '%s' "
"anymore in Blender 2.80 and later, removed instancing"),
ob->id.name + 2,
ob->instance_collection->id.name + 2);

View File

@ -393,14 +393,14 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
if (ob->id.lib) {
BLO_reportf_wrap(fd->reports,
RPT_INFO,
TIP_("Proxy lost from object %s lib %s\n"),
RPT_("Proxy lost from object %s lib %s\n"),
ob->id.name + 2,
ob->id.lib->filepath);
}
else {
BLO_reportf_wrap(fd->reports,
RPT_INFO,
TIP_("Proxy lost from object %s lib <NONE>\n"),
RPT_("Proxy lost from object %s lib <NONE>\n"),
ob->id.name + 2);
}
fd->reports->count.missing_obproxies++;

View File

@ -262,6 +262,18 @@ void blo_do_versions_userdef(UserDef *userdef)
userdef->pad_rot_angle = 15.0f;
}
/* If the userdef was created on a different platform, it may have an
* unsupported GPU backend selected. If so, pick a supported default. */
#ifdef __APPLE__
if (userdef->gpu_backend == GPU_BACKEND_OPENGL) {
userdef->gpu_backend = GPU_BACKEND_METAL;
}
#else
if (userdef->gpu_backend == GPU_BACKEND_METAL) {
userdef->gpu_backend = GPU_BACKEND_OPENGL;
}
#endif
/* graph editor - unselected F-Curve visibility */
if (userdef->fcu_inactive_alpha == 0) {
userdef->fcu_inactive_alpha = 0.25f;
@ -482,8 +494,8 @@ void blo_do_versions_userdef(UserDef *userdef)
USER_FLAG_UNUSED_6 | USER_FLAG_UNUSED_7 | USER_FLAG_UNUSED_9 |
USER_DEVELOPER_UI);
userdef->uiflag &= ~(USER_HEADER_BOTTOM);
userdef->transopts &= ~(USER_TR_UNUSED_2 | USER_TR_UNUSED_3 | USER_TR_UNUSED_4 |
USER_TR_UNUSED_6 | USER_TR_UNUSED_7);
userdef->transopts &= ~(USER_TR_UNUSED_3 | USER_TR_UNUSED_4 | USER_TR_UNUSED_6 |
USER_TR_UNUSED_7);
userdef->uiflag |= USER_LOCK_CURSOR_ADJUST;
}
@ -856,15 +868,6 @@ void blo_do_versions_userdef(UserDef *userdef)
BKE_addon_remove_safe(&userdef->addons, "io_scene_obj");
}
if (!USER_VERSION_ATLEAST(400, 12)) {
#ifdef __APPLE__
/* Drop OpenGL support on MAC devices as they don't support OpenGL 4.3. */
if (userdef->gpu_backend == GPU_BACKEND_OPENGL) {
userdef->gpu_backend = GPU_BACKEND_METAL;
}
#endif
}
if (!USER_VERSION_ATLEAST(400, 15)) {
userdef->node_preview_res = 120;
}

Some files were not shown because too many files have changed in this diff Show More