GPv3: Opacity modifier #116946

Merged
Lukas Tönne merged 52 commits from LukasTonne/blender:gp3-opacity-modifier into main 2024-01-16 16:56:22 +01:00
112 changed files with 1104 additions and 1174 deletions
Showing only changes of commit 4db9214fd7 - 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

@ -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

@ -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

@ -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;
};

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

@ -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

@ -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

@ -364,7 +364,7 @@ bool BKE_mesh_has_custom_loop_normals(struct Mesh *mesh);
/**
* Higher level functions hiding most of the code needed around call to
* #normals_loop_custom_set().
* #normals_corner_custom_set().
*
* \param r_custom_loop_normals: is not const, since code will replace zero_v3 normals there
* with automatically computed vectors.
@ -372,7 +372,7 @@ bool BKE_mesh_has_custom_loop_normals(struct Mesh *mesh);
void BKE_mesh_set_custom_normals(struct Mesh *mesh, float (*r_custom_loop_normals)[3]);
/**
* Higher level functions hiding most of the code needed around call to
* #normals_loop_custom_set_from_verts().
* #normals_corner_custom_set_from_verts().
*
* \param r_custom_vert_normals: is not const, since code will replace zero_v3 normals there
* with automatically computed vectors.

View File

@ -157,13 +157,12 @@ struct CornerNormalSpaceArray {
bool create_corners_by_space = false;
};
short2 lnor_space_custom_normal_to_data(const CornerNormalSpace &lnor_space,
const float3 &custom_lnor);
short2 corner_space_custom_normal_to_data(const CornerNormalSpace &lnor_space,
const float3 &custom_lnor);
/**
* Compute split normals, i.e. vertex normals associated with each face (hence 'loop normals').
* Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry
* (splitting edges).
* Compute split normals, i.e. vertex normals associated with each face. Used to visualize sharp
* edges (or non-smooth faces) without actually modifying the geometry (splitting edges).
*
* \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on
* each side of the edge.
@ -172,54 +171,54 @@ short2 lnor_space_custom_normal_to_data(const CornerNormalSpace &lnor_space,
* \param r_lnors_spacearr: Optional return data filled with information about the custom
* normals spaces for each grouped fan of face corners.
*/
void normals_calc_loop(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int> corner_edges,
Span<int> loop_to_face_map,
Span<float3> vert_normals,
Span<float3> face_normals,
Span<bool> sharp_edges,
Span<bool> sharp_faces,
const short2 *clnors_data,
CornerNormalSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals);
void normals_calc_corners(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int> corner_edges,
Span<int> corner_to_face_map,
Span<float3> vert_normals,
Span<float3> face_normals,
Span<bool> sharp_edges,
Span<bool> sharp_faces,
const short2 *clnors_data,
CornerNormalSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_corner_normals);
/**
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
*/
void normals_loop_custom_set(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> vert_normals,
Span<float3> face_normals,
Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals,
MutableSpan<short2> r_clnors_data);
void normals_corner_custom_set(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> vert_normals,
Span<float3> face_normals,
Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_corner_normals,
MutableSpan<short2> r_clnors_data);
/**
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
*/
void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> vert_normals,
Span<float3> face_normals,
Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals,
MutableSpan<short2> r_clnors_data);
void normals_corner_custom_set_from_verts(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> vert_normals,
Span<float3> face_normals,
Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals,
MutableSpan<short2> r_clnors_data);
/**
* Define sharp edges as needed to mimic 'autosmooth' from angle threshold.
*
* Used when defining an empty custom loop normals data layer,
* Used when defining an empty custom corner normals data layer,
* to keep same shading as with auto-smooth!
*
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
@ -228,7 +227,7 @@ void edges_sharp_from_angle_set(OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int> corner_edges,
Span<float3> face_normals,
Span<int> loop_to_face,
Span<int> corner_to_face,
Span<bool> sharp_faces,
const float split_angle,
MutableSpan<bool> sharp_edges);

View File

@ -274,7 +274,7 @@ int *BKE_mesh_calc_smoothgroups(int edges_num,
namespace blender::bke::mesh {
Array<int> build_loop_to_face_map(OffsetIndices<int> faces);
Array<int> build_corner_to_face_map(OffsetIndices<int> faces);
GroupedSpan<int> build_vert_to_edge_map(Span<int2> edges,
int verts_num,
@ -292,15 +292,15 @@ GroupedSpan<int> build_vert_to_face_map(OffsetIndices<int> faces,
Array<int> &r_indices);
Array<int> build_vert_to_corner_indices(Span<int> corner_verts, OffsetIndices<int> offsets);
GroupedSpan<int> build_vert_to_loop_map(Span<int> corner_verts,
int verts_num,
Array<int> &r_offsets,
Array<int> &r_indices);
GroupedSpan<int> build_vert_to_corner_map(Span<int> corner_verts,
int verts_num,
Array<int> &r_offsets,
Array<int> &r_indices);
GroupedSpan<int> build_edge_to_loop_map(Span<int> corner_edges,
int edges_num,
Array<int> &r_offsets,
Array<int> &r_indices);
GroupedSpan<int> build_edge_to_corner_map(Span<int> corner_edges,
int edges_num,
Array<int> &r_offsets,
Array<int> &r_indices);
GroupedSpan<int> build_edge_to_face_map(OffsetIndices<int> faces,
Span<int> corner_edges,

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

@ -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 it'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

@ -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

@ -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

@ -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

@ -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

@ -379,17 +379,17 @@ static void data_transfer_dtdata_type_postprocess(Mesh *me_dst,
"sharp_edge", bke::AttrDomain::Edge);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", bke::AttrDomain::Face);
/* Note loop_nors_dst contains our custom normals as transferred from source... */
blender::bke::mesh::normals_loop_custom_set(me_dst->vert_positions(),
me_dst->edges(),
me_dst->faces(),
me_dst->corner_verts(),
me_dst->corner_edges(),
me_dst->vert_normals(),
me_dst->face_normals(),
sharp_faces,
sharp_edges.span,
{loop_nors_dst, me_dst->corners_num},
{custom_nors_dst, me_dst->corners_num});
blender::bke::mesh::normals_corner_custom_set(me_dst->vert_positions(),
me_dst->edges(),
me_dst->faces(),
me_dst->corner_verts(),
me_dst->corner_edges(),
me_dst->vert_normals(),
me_dst->face_normals(),
sharp_faces,
sharp_edges.span,
{loop_nors_dst, me_dst->corners_num},
{custom_nors_dst, me_dst->corners_num});
sharp_edges.finish();
CustomData_free_layers(ldata_dst, CD_NORMAL, me_dst->corners_num);
}

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

@ -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"

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

@ -2280,7 +2280,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
const AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", AttrDomain::Edge);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", AttrDomain::Face);
mesh::normals_calc_loop(
mesh::normals_calc_corners(
positions,
edges,
faces,

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

@ -373,7 +373,7 @@ static GroupedSpan<int> gather_groups(const Span<int> group_indices,
return {OffsetIndices<int>(r_offsets), r_indices};
}
Array<int> build_loop_to_face_map(const OffsetIndices<int> faces)
Array<int> build_corner_to_face_map(const OffsetIndices<int> faces)
{
Array<int> map(faces.total_size());
offset_indices::build_reverse_map(faces, map);
@ -430,18 +430,18 @@ Array<int> build_vert_to_corner_indices(const Span<int> corner_verts,
return reverse_indices_in_groups(corner_verts, offsets);
}
GroupedSpan<int> build_vert_to_loop_map(const Span<int> corner_verts,
const int verts_num,
Array<int> &r_offsets,
Array<int> &r_indices)
GroupedSpan<int> build_vert_to_corner_map(const Span<int> corner_verts,
const int verts_num,
Array<int> &r_offsets,
Array<int> &r_indices)
{
return gather_groups(corner_verts, verts_num, r_offsets, r_indices);
}
GroupedSpan<int> build_edge_to_loop_map(const Span<int> corner_edges,
const int edges_num,
Array<int> &r_offsets,
Array<int> &r_indices)
GroupedSpan<int> build_edge_to_corner_map(const Span<int> corner_edges,
const int edges_num,
Array<int> &r_offsets,
Array<int> &r_indices)
{
return gather_groups(corner_edges, edges_num, r_offsets, r_indices);
}
@ -858,7 +858,7 @@ static bool mesh_calc_islands_loop_face_uv(const int totedge,
Array<int> edge_to_loop_indices;
GroupedSpan<int> edge_to_loop_map;
if (luvs) {
edge_to_loop_map = bke::mesh::build_edge_to_loop_map(
edge_to_loop_map = bke::mesh::build_edge_to_corner_map(
{corner_edges, totloop}, totedge, edge_to_loop_offsets, edge_to_loop_indices);
}

View File

@ -411,19 +411,19 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
const bke::AttributeAccessor attributes = result->attributes();
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", AttrDomain::Edge);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", AttrDomain::Face);
blender::bke::mesh::normals_calc_loop(result->vert_positions(),
result_edges,
result_faces,
result_corner_verts,
result_corner_edges,
result->corner_to_face_map(),
result->vert_normals(),
result->face_normals(),
sharp_edges,
sharp_faces,
clnors,
&lnors_spacearr,
loop_normals);
blender::bke::mesh::normals_calc_corners(result->vert_positions(),
result_edges,
result_faces,
result_corner_verts,
result_corner_edges,
result->corner_to_face_map(),
result->vert_normals(),
result->face_normals(),
sharp_edges,
sharp_faces,
clnors,
&lnors_spacearr,
loop_normals);
/* mirroring has to account for loops being reversed in faces in second half */
for (const int i : src_faces.index_range()) {
@ -440,7 +440,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
mul_m4_v3(mtx_nor, loop_normals[mirrorj]);
const int space_index = lnors_spacearr.corner_space_indices[mirrorj];
clnors[mirrorj] = blender::bke::mesh::lnor_space_custom_normal_to_data(
clnors[mirrorj] = blender::bke::mesh::corner_space_custom_normal_to_data(
lnors_spacearr.spaces[space_index], loop_normals[mirrorj]);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -120,7 +120,7 @@ blender::Span<int> Mesh::corner_to_face_map() const
using namespace blender;
this->runtime->corner_to_face_map_cache.ensure([&](Array<int> &r_data) {
const OffsetIndices faces = this->faces();
r_data = bke::mesh::build_loop_to_face_map(faces);
r_data = bke::mesh::build_corner_to_face_map(faces);
});
return this->runtime->corner_to_face_map_cache.data();
}

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"

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

@ -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

@ -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;
@ -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;
}

View File

@ -1062,7 +1062,7 @@ static void bm_mesh_loops_calc_normals_for_vert_without_clnors(
}
/**
* BMesh version of bke::mesh::normals_calc_loop() in `mesh_evaluate.cc`
* BMesh version of bke::mesh::normals_calc_corners() in `mesh_evaluate.cc`
* Will use first clnors_data array, and fallback to cd_loop_clnors_offset
* (use nullptr and -1 to not use clnors).
*
@ -1413,7 +1413,7 @@ static bool bm_mesh_loops_split_lnor_fans(BMesh *bm,
/* Notes:
* * In case of mono-loop smooth fan, we have nothing to do.
* * Loops in this linklist are ordered (in reversed order compared to how they were
* discovered by bke::mesh::normals_calc_loop(), but this is not a problem).
* discovered by bke::mesh::normals_calc_corners(), but this is not a problem).
* Which means if we find a mismatching clnor,
* we know all remaining loops will have to be in a new, different smooth fan/lnor space.
* * In smooth fan case, we compare each clnor against a ref one,

View File

@ -2,6 +2,11 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_base.hh"
#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
#include "MEM_guardedalloc.h"
#include "COM_SunBeamsOperation.h"
@ -17,331 +22,61 @@ SunBeamsOperation::SunBeamsOperation()
flags_.complex = true;
}
void SunBeamsOperation::calc_rays_common_data()
{
/* convert to pixels */
source_px_[0] = data_.source[0] * this->get_width();
source_px_[1] = data_.source[1] * this->get_height();
ray_length_px_ = data_.ray_length * std::max(this->get_width(), this->get_height());
}
void SunBeamsOperation::init_execution()
{
calc_rays_common_data();
input_program_ = this->get_input_socket_reader(0);
}
/**
* Defines a line accumulator for a specific sector,
* given by the four matrix entries that rotate from buffer space into the sector
*
* (x,y) is used to designate buffer space coordinates
* (u,v) is used to designate sector space coordinates
*
* For a target point (x,y) the sector should be chosen such that
* `u >= v >= 0`
* This removes the need to handle all sorts of special cases.
*
* Template parameters:
* \param fxu: buffer increment in x for sector `u + 1`.
* \param fxv: buffer increment in x for sector `v + 1`.
* \param fyu: buffer increment in y for sector `u + 1`.
* \param fyv: buffer increment in y for sector `v + 1`.
*/
template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
void SunBeamsOperation::execute_pixel(float output[4], int x, int y, void * /* data */)
{
const float2 input_size = float2(input_program_->get_width(), input_program_->get_height());
const int max_steps = int(data_.ray_length * math::length(input_size));
const float2 source = float2(data_.source);
/* utility functions implementing the matrix transform to/from sector space */
const float2 texel = float2(x, y);
static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v)
{
int x0 = int(source[0]);
int y0 = int(source[1]);
x -= float(x0);
y -= float(y0);
u = x * fxu + y * fyu;
v = x * fxv + y * fyv;
/* The number of steps is the distance in pixels from the source to the current texel. With
* at least a single step and at most the user specified maximum ray length, which is
* proportional to the diagonal pixel count. */
const float unbounded_steps = math::max(1.0f, math::distance(texel, source * input_size));
const int steps = math::min(max_steps, int(unbounded_steps));
/* We integrate from the current pixel to the source pixel, so compute the start coordinates
* and step vector in the direction to source. Notice that the step vector is still computed
* from the unbounded steps, such that the total integration length becomes limited by the
* bounded steps, and thus by the maximum ray length. */
const float2 coordinates = (texel + float2(0.5f)) / input_size;
const float2 vector_to_source = source - coordinates;
const float2 step_vector = vector_to_source / unbounded_steps;
float accumulated_weight = 0.0f;
float4 accumulated_color = float4(0.0f);
for (int i = 0; i <= steps; i++) {
float2 position = coordinates + i * step_vector;
/* We are already past the image boundaries, and any future steps are also past the image
* boundaries, so break. */
if (position.x < 0.0f || position.y < 0.0f || position.x > 1.0f || position.y > 1.0f) {
break;
}
const float2 coordinates = position * input_size;
float4 sample_color;
input_program_->read_sampled(
sample_color, coordinates.x, coordinates.y, PixelSampler::Bilinear);
/* Attenuate the contributions of pixels that are further away from the source using a
* quadratic falloff. Also weight by the alpha to give more significance to opaque pixels.
*/
const float weight = (math::square(1.0f - i / float(steps))) * sample_color.w;
accumulated_weight += weight;
accumulated_color += sample_color * weight;
}
static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y)
{
int x0 = int(source[0]);
int y0 = int(source[1]);
x = x0 + u * fxu + v * fxv;
y = y0 + u * fyu + v * fyv;
}
/**
* Set up the initial buffer pointer and calculate necessary variables for looping.
*
* Note that sector space is centered around the "source" point while the loop starts
* at dist_min from the target pt. This way the loop can be canceled as soon as it runs
* out of the buffer rect, because no pixels further along the line can contribute.
*
* \param x, y: Start location in the buffer
* \param num: Total steps in the loop
* \param v, dv: Vertical offset in sector space, for line offset perpendicular to the loop axis
*/
static float *init_buffer_iterator(MemoryBuffer *input,
const float source[2],
const float co[2],
float dist_min,
float dist_max,
int &x,
int &y,
int &num,
float &v,
float &dv,
float &falloff_factor)
{
float pu, pv;
buffer_to_sector(source, co[0], co[1], pu, pv);
/* line angle */
double tan_phi = pv / double(pu);
double dr = sqrt(tan_phi * tan_phi + 1.0);
double cos_phi = 1.0 / dr;
/* clamp u range to avoid influence of pixels "behind" the source */
float umin = max_ff(pu - cos_phi * dist_min, 0.0f);
float umax = max_ff(pu - cos_phi * dist_max, 0.0f);
v = umin * tan_phi;
dv = tan_phi;
int start = int(floorf(umax));
int end = int(ceilf(umin));
num = end - start;
sector_to_buffer(source, end, int(ceilf(v)), x, y);
falloff_factor = dist_max > dist_min ? dr / double(dist_max - dist_min) : 0.0f;
float *iter = input->get_buffer() + input->get_coords_offset(x, y);
return iter;
}
/**
* Perform the actual accumulation along a ray segment from source to pt.
* Only pixels within dist_min..dist_max contribute.
*
* The loop runs backwards(!) over the primary sector space axis u, i.e. increasing distance to
* pt. After each step it decrements v by dv < 1, adding a buffer shift when necessary.
*/
static void eval(MemoryBuffer *input,
float output[4],
const float co[2],
const float source[2],
float dist_min,
float dist_max)
{
const rcti &rect = input->get_rect();
int x, y, num;
float v, dv;
float falloff_factor;
float border[4];
zero_v4(output);
if (int(co[0] - source[0]) == 0 && int(co[1] - source[1]) == 0) {
copy_v4_v4(output, input->get_elem(source[0], source[1]));
return;
}
/* Initialize the iteration variables. */
float *buffer = init_buffer_iterator(
input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor);
zero_v3(border);
border[3] = 1.0f;
/* v_local keeps track of when to decrement v (see below) */
float v_local = v - floorf(v);
for (int i = 0; i < num; i++) {
float weight = 1.0f - float(i) * falloff_factor;
weight *= weight;
/* range check, use last valid color when running beyond the image border */
if (x >= rect.xmin && x < rect.xmax && y >= rect.ymin && y < rect.ymax) {
madd_v4_v4fl(output, buffer, buffer[3] * weight);
/* use as border color in case subsequent pixels are out of bounds */
copy_v4_v4(border, buffer);
}
else {
madd_v4_v4fl(output, border, border[3] * weight);
}
/* TODO: implement proper filtering here, see
* https://en.wikipedia.org/wiki/Lanczos_resampling
* https://en.wikipedia.org/wiki/Sinc_function
*
* using lanczos with x = distance from the line segment,
* normalized to a == 0.5f, could give a good result
*
* for now just divide equally at the end ...
*/
/* decrement u */
x -= fxu;
y -= fyu;
buffer -= fxu * input->elem_stride + fyu * input->row_stride;
/* decrement v (in steps of dv < 1) */
v_local -= dv;
if (v_local < 0.0f) {
v_local += 1.0f;
x -= fxv;
y -= fyv;
buffer -= fxv * input->elem_stride + fyv * input->row_stride;
}
}
/* normalize */
if (num > 0) {
mul_v4_fl(output, 1.0f / float(num));
}
}
};
/**
* Dispatch function which selects an appropriate accumulator based on the sector of the target
* point, relative to the source.
*
* The BufferLineAccumulator defines the actual loop over the buffer, with an efficient inner loop
* due to using compile time constants instead of a local matrix variable defining the sector
* space.
*/
static void accumulate_line(MemoryBuffer *input,
float output[4],
const float co[2],
const float source[2],
float dist_min,
float dist_max)
{
/* coordinates relative to source */
float pt_ofs[2] = {co[0] - source[0], co[1] - source[1]};
/* The source sectors are defined like so:
*
* \ 3 | 2 /
* \ | /
* 4 \ | / 1
* \|/
* -----------
* /|\
* 5 / | \ 8
* / | \
* / 6 | 7 \
*
* The template arguments encode the transformation into "sector space",
* by means of rotation/mirroring matrix elements.
*/
if (fabsf(pt_ofs[1]) > fabsf(pt_ofs[0])) {
if (pt_ofs[0] > 0.0f) {
if (pt_ofs[1] > 0.0f) {
/* 2 */
BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 7 */
BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
}
else {
if (pt_ofs[1] > 0.0f) {
/* 3 */
BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 6 */
BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
}
}
else {
if (pt_ofs[0] > 0.0f) {
if (pt_ofs[1] > 0.0f) {
/* 1 */
BufferLineAccumulator<1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 8 */
BufferLineAccumulator<1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max);
}
}
else {
if (pt_ofs[1] > 0.0f) {
/* 4 */
BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 5 */
BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max);
}
}
}
}
void *SunBeamsOperation::initialize_tile_data(rcti * /*rect*/)
{
void *buffer = get_input_operation(0)->initialize_tile_data(nullptr);
return buffer;
}
void SunBeamsOperation::execute_pixel(float output[4], int x, int y, void *data)
{
const float co[2] = {float(x), float(y)};
accumulate_line((MemoryBuffer *)data, output, co, source_px_, 0.0f, ray_length_px_);
}
static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length)
{
float co[2] = {float(x), float(y)};
float dir[2], dist;
/* move (x,y) vector toward the source by ray_length distance */
sub_v2_v2v2(dir, co, source);
dist = normalize_v2(dir);
mul_v2_fl(dir, min_ff(dist, ray_length));
sub_v2_v2(co, dir);
int ico[2] = {int(co[0]), int(co[1])};
BLI_rcti_do_minmax_v(rect, ico);
}
bool SunBeamsOperation::determine_depending_area_of_interest(rcti *input,
ReadBufferOperation *read_operation,
rcti *output)
{
/* Enlarges the rect by moving each corner toward the source.
* This is the maximum distance that pixels can influence each other
* and gives a rect that contains all possible accumulated pixels.
*/
rcti rect = *input;
calc_ray_shift(&rect, input->xmin, input->ymin, source_px_, ray_length_px_);
calc_ray_shift(&rect, input->xmin, input->ymax, source_px_, ray_length_px_);
calc_ray_shift(&rect, input->xmax, input->ymin, source_px_, ray_length_px_);
calc_ray_shift(&rect, input->xmax, input->ymax, source_px_, ray_length_px_);
return NodeOperation::determine_depending_area_of_interest(&rect, read_operation, output);
}
void SunBeamsOperation::get_area_of_interest(const int input_idx,
const rcti &output_area,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
UNUSED_VARS(input_idx);
calc_rays_common_data();
r_input_area = output_area;
/* Enlarges the rect by moving each corner toward the source.
* This is the maximum distance that pixels can influence each other
* and gives a rect that contains all possible accumulated pixels. */
calc_ray_shift(&r_input_area, output_area.xmin, output_area.ymin, source_px_, ray_length_px_);
calc_ray_shift(&r_input_area, output_area.xmin, output_area.ymax, source_px_, ray_length_px_);
calc_ray_shift(&r_input_area, output_area.xmax, output_area.ymin, source_px_, ray_length_px_);
calc_ray_shift(&r_input_area, output_area.xmax, output_area.ymax, source_px_, ray_length_px_);
accumulated_color /= accumulated_weight != 0.0f ? accumulated_weight : 1.0f;
copy_v4_v4(output, accumulated_color);
}
void SunBeamsOperation::update_memory_buffer_partial(MemoryBuffer *output,
@ -349,16 +84,63 @@ void SunBeamsOperation::update_memory_buffer_partial(MemoryBuffer *output,
Span<MemoryBuffer *> inputs)
{
MemoryBuffer *input = inputs[0];
float coords[2];
const float2 input_size = float2(input->get_width(), input->get_height());
const int max_steps = int(data_.ray_length * math::length(input_size));
const float2 source = float2(data_.source);
for (int y = area.ymin; y < area.ymax; y++) {
coords[1] = y;
float *out_elem = output->get_elem(area.xmin, y);
for (int x = area.xmin; x < area.xmax; x++) {
coords[0] = x;
accumulate_line(input, out_elem, coords, source_px_, 0.0f, ray_length_px_);
out_elem += output->elem_stride;
const float2 texel = float2(x, y);
/* The number of steps is the distance in pixels from the source to the current texel. With
* at least a single step and at most the user specified maximum ray length, which is
* proportional to the diagonal pixel count. */
const float unbounded_steps = math::max(1.0f, math::distance(texel, source * input_size));
const int steps = math::min(max_steps, int(unbounded_steps));
/* We integrate from the current pixel to the source pixel, so compute the start coordinates
* and step vector in the direction to source. Notice that the step vector is still computed
* from the unbounded steps, such that the total integration length becomes limited by the
* bounded steps, and thus by the maximum ray length. */
const float2 coordinates = (texel + float2(0.5f)) / input_size;
const float2 vector_to_source = source - coordinates;
const float2 step_vector = vector_to_source / unbounded_steps;
float accumulated_weight = 0.0f;
float4 accumulated_color = float4(0.0f);
for (int i = 0; i <= steps; i++) {
float2 position = coordinates + i * step_vector;
/* We are already past the image boundaries, and any future steps are also past the image
* boundaries, so break. */
if (position.x < 0.0f || position.y < 0.0f || position.x > 1.0f || position.y > 1.0f) {
break;
}
const float2 coordinates = position * input_size;
float4 sample_color;
input->read_elem_bilinear(coordinates.x, coordinates.y, sample_color);
/* Attenuate the contributions of pixels that are further away from the source using a
* quadratic falloff. Also weight by the alpha to give more significance to opaque pixels.
*/
const float weight = (math::square(1.0f - i / float(steps))) * sample_color.w;
accumulated_weight += weight;
accumulated_color += sample_color * weight;
}
accumulated_color /= accumulated_weight != 0.0f ? accumulated_weight : 1.0f;
copy_v4_v4(output->get_elem(x, y), accumulated_color);
}
}
}
void SunBeamsOperation::deinit_execution()
{
input_program_ = nullptr;
}
} // namespace blender::compositor

View File

@ -16,12 +16,6 @@ class SunBeamsOperation : public MultiThreadedOperation {
void init_execution() override;
void *initialize_tile_data(rcti *rect) override;
bool determine_depending_area_of_interest(rcti *input,
ReadBufferOperation *read_operation,
rcti *output) override;
void set_data(const NodeSunBeams &data)
{
data_ = data;
@ -30,16 +24,12 @@ class SunBeamsOperation : public MultiThreadedOperation {
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
private:
void calc_rays_common_data();
void deinit_execution() override;
private:
NodeSunBeams data_;
float source_px_[2];
float ray_length_px_;
SocketReader *input_program_;
};
} // namespace blender::compositor

View File

@ -125,9 +125,6 @@ class ConvertColorToVectorOperation : public ConversionOperation {
* components.
* \{ */
/*
*
* */
class ConvertVectorToFloatOperation : public ConversionOperation {
public:
ConvertVectorToFloatOperation(Context &context);

View File

@ -363,7 +363,7 @@ bool Instance::do_planar_probe_sync() const
/**
* Conceptually renders one sample per pixel.
* Everything based on random sampling should be done here (i.e: DRWViews jitter)
**/
*/
void Instance::render_sample()
{
if (sampling.finished_viewport()) {

View File

@ -523,12 +523,12 @@ void DeferredLayer::end_sync()
sub.shader_set(sh);
sub.state_set(DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS);
if (GPU_stencil_export_support()) {
/* The shader sets the stencil directly in one fullscreen pass. */
/* The shader sets the stencil directly in one full-screen pass. */
sub.state_stencil(0xFFu, /* Set by shader */ 0x0u, 0xFFu);
sub.draw_procedural(GPU_PRIM_TRIS, 1, 3);
}
else {
/* The shader cannot set the stencil directly. So we do one fullscreen pass for each
/* The shader cannot set the stencil directly. So we do one full-screen pass for each
* stencil bit we need to set and accumulate the result. */
for (size_t i = 0; i <= log2_ceil(closure_count_); i++) {
int stencil_value = 1 << i;
@ -714,8 +714,8 @@ void DeferredLayer::render(View &main_view,
}
else {
if (!GPU_stencil_export_support()) {
/* Clearing custom load-store framebuffers is invalid,
* clear the stencil as a regular framebuffer first. */
/* Clearing custom load-store frame-buffers is invalid,
* clear the stencil as a regular frame-buffer first. */
GPU_framebuffer_bind(gbuffer_fb);
GPU_framebuffer_clear_stencil(gbuffer_fb, 0x0u);
}

View File

@ -67,7 +67,8 @@ void forward_lighting_eval(float thickness, out vec3 radiance, out vec3 transmit
#endif
#ifdef MAT_SUBSURFACE
vec3 sss_profile = subsurface_transmission(g_diffuse_data.sss_radius, thickness);
vec3 sss_profile = subsurface_transmission(to_closure_subsurface(g_diffuse_data).sss_radius,
thickness);
stack.cl[cl_subsurface_id].light_shadowed *= sss_profile;
stack.cl[cl_subsurface_id].light_unshadowed *= sss_profile;
/* Fuse back the SSS transmittance with the diffuse lighting. */

View File

@ -38,7 +38,7 @@ struct IMAGE_Data {
*
* The drawing mode decides how to draw the image on the screen. Each way how to draw would have
* its own subclass. For now there is only a single drawing mode. #DefaultDrawingMode.
**/
*/
class AbstractDrawingMode {
public:
virtual ~AbstractDrawingMode() = default;

View File

@ -16,7 +16,7 @@
#include "BKE_geometry_set.hh"
#include "BKE_instances.hh"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "DRW_render.hh"

View File

@ -23,7 +23,7 @@
#include "DNA_pointcloud_types.h"
#include "BKE_attribute.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "GPU_batch.h"
#include "GPU_material.h"

View File

@ -38,7 +38,7 @@
#include "BKE_paint.hh"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_screen.hh"
#include "BKE_subdiv_modifier.hh"
#include "BKE_viewer_path.hh"

View File

@ -86,7 +86,7 @@ class View {
* Update culling data using a compute shader.
* This is to be used if the matrices were updated externally
* on the GPU (not using the `sync()` method).
**/
*/
void compute_procedural_bounds();
bool is_persp(int view_id = 0) const

View File

@ -325,17 +325,22 @@ static void extract_edit_data_loose_geom_subdiv(const DRWSubdivCache &subdiv_cac
const int edge_index = loose_edge.coarse_edge_index;
BMEdge *eed = mr.e_origindex ? bm_original_edge_get(mr, edge_index) :
BM_edge_at_index(mr.bm, edge_index);
mesh_render_data_edge_flag(mr, eed, &data[0]);
data[1] = data[0];
if (eed) {
mesh_render_data_edge_flag(mr, eed, &data[0]);
data[1] = data[0];
const DRWSubdivLooseVertex &v1 = loose_geom.verts[loose_edge.loose_subdiv_v1_index];
const DRWSubdivLooseVertex &v2 = loose_geom.verts[loose_edge.loose_subdiv_v2_index];
const DRWSubdivLooseVertex &v1 = loose_geom.verts[loose_edge.loose_subdiv_v1_index];
const DRWSubdivLooseVertex &v2 = loose_geom.verts[loose_edge.loose_subdiv_v2_index];
if (v1.coarse_vertex_index != -1u) {
mesh_render_data_vert_flag(mr, eed->v1, &data[0]);
if (v1.coarse_vertex_index != -1u) {
mesh_render_data_vert_flag(mr, eed->v1, &data[0]);
}
if (v2.coarse_vertex_index != -1u) {
mesh_render_data_vert_flag(mr, eed->v2, &data[1]);
}
}
if (v2.coarse_vertex_index != -1u) {
mesh_render_data_vert_flag(mr, eed->v2, &data[1]);
else {
memset(&data[1], 0, sizeof(EditLoopData));
}
}
}

View File

@ -33,7 +33,7 @@
#include "BKE_mesh_wrapper.hh"
#include "BKE_node_runtime.hh"
#include "BKE_object.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_report.h"
#include "BKE_screen.hh"

View File

@ -159,7 +159,7 @@ struct tGPDfill {
int fill_simplylvl;
/** boundary limits drawing mode */
int fill_draw_mode;
/** types of extensions **/
/** Types of extensions. */
int fill_extend_mode;
/* scaling factor */
float fill_factor;

View File

@ -534,7 +534,7 @@ enum eAnimChannels_SetFlag {
ACHANNEL_SETFLAG_INVERT = 2,
/** some on -> all off / all on */
ACHANNEL_SETFLAG_TOGGLE = 3,
/** turn off, keep active flag **/
/** Turn off, keep active flag. */
ACHANNEL_SETFLAG_EXTEND_RANGE = 4,
};

View File

@ -108,6 +108,22 @@ static const char *shortcut_get_operator_property(bContext *C, uiBut *but, IDPro
}
}
if (MenuType *mt = UI_but_menutype_get(but)) {
const IDPropertyTemplate val = {0};
IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__);
IDP_AddToGroup(prop, IDP_NewString(mt->idname, "name"));
*r_prop = prop;
return "WM_OT_call_menu";
}
if (PanelType *pt = UI_but_paneltype_get(but)) {
const IDPropertyTemplate val = {0};
IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__);
IDP_AddToGroup(prop, IDP_NewString(pt->idname, "name"));
*r_prop = prop;
return "WM_OT_call_panel";
}
*r_prop = nullptr;
return nullptr;
}

View File

@ -264,14 +264,14 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
bbox.ymax -= field->image_size[1];
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
/* Draw checker pattern behind the image in case is has transparency. */
imm_draw_box_checker_2d(float(bbox.xmin),
float(bbox.ymax),
float(bbox.xmin + field->image_size[0]),
float(bbox.ymax + field->image_size[1]));
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR);
immDrawPixelsTexScaledFullSize(&state,
bbox.xmin,
@ -307,6 +307,8 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
float(bbox.xmin + field->image_size[0]),
float(bbox.ymax + field->image_size[1]));
immUnbindProgram();
GPU_blend(GPU_BLEND_NONE);
}
else if (field->format.style == UI_TIP_STYLE_SPACER) {
bbox.ymax -= data->lineh * UI_TIP_SPACER;
@ -1203,6 +1205,21 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
return data;
}
static uiTooltipData *ui_tooltip_data_from_custom_func(bContext *C, uiBut *but)
{
/* Create tooltip data. */
uiTooltipData *data = MEM_cnew<uiTooltipData>(__func__);
/* Create fields from custom callback. */
but->tip_custom_func(C, data, but->tip_arg);
if (data->fields_len == 0) {
MEM_freeN(data);
return nullptr;
}
return data;
}
static ARegion *ui_tooltip_create_with_data(bContext *C,
uiTooltipData *data,
const float init_position[2],
@ -1474,8 +1491,7 @@ ARegion *UI_tooltip_create_from_button_or_extra_icon(
uiTooltipData *data = nullptr;
if (but->tip_custom_func) {
data = (uiTooltipData *)MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
but->tip_custom_func(C, data, but->tip_arg);
data = ui_tooltip_data_from_custom_func(C, but);
}
if (data == nullptr) {

View File

@ -878,7 +878,7 @@ static bool loop_uv_match(BMLoop *loop,
* \param visited: A set of edges to prevent recursing down the same edge multiple times.
* \param cd_loop_uv_offset: The UV layer.
* \return true if there are edges that fan between them that are seam-free.
* */
*/
static bool seam_connected_recursive(BMEdge *edge,
const float luv_anchor[2],
const float luv_fan[2],

View File

@ -84,7 +84,7 @@
#include "BKE_object.hh"
#include "BKE_object_types.hh"
#include "BKE_particle.h"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_speaker.h"

View File

@ -40,7 +40,7 @@
#include "BKE_modifier.hh"
#include "BKE_node_runtime.hh"
#include "BKE_object.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_report.h"
#include "BKE_scene.h"

View File

@ -67,7 +67,7 @@
#include "BKE_ocean.h"
#include "BKE_paint.hh"
#include "BKE_particle.h"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_softbody.h"

View File

@ -75,7 +75,7 @@
#include "BKE_node_tree_interface.hh"
#include "BKE_object.hh"
#include "BKE_object_types.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_speaker.h"

View File

@ -50,7 +50,7 @@
#include "BKE_multires.hh"
#include "BKE_object.hh"
#include "BKE_object_types.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_tracking.h"

View File

@ -2754,7 +2754,7 @@ static void calc_brush_local_mat(const float rotation,
* the brush). */
angle = rotation + cache->special_rotation;
/* By convention, motion direction points down the brush's Y axis, the angle represents the X
* axis, normal is a 90 deg ccw rotation of the motion direction. */
* axis, normal is a 90 deg CCW rotation of the motion direction. */
float motion_normal_screen[2];
motion_normal_screen[0] = cosf(angle);
motion_normal_screen[1] = sinf(angle);

View File

@ -528,7 +528,7 @@ void split_edges(Mesh &mesh,
Array<int> edge_to_corner_offsets;
Array<int> edge_to_corner_indices;
const GroupedSpan<int> edge_to_corner_map = bke::mesh::build_edge_to_loop_map(
const GroupedSpan<int> edge_to_corner_map = bke::mesh::build_edge_to_corner_map(
mesh.corner_edges(), orig_edges.size(), edge_to_corner_offsets, edge_to_corner_indices);
Array<int> vert_to_edge_offsets;

View File

@ -11,7 +11,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_geometry_set.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "GEO_point_merge_by_distance.hh"
#include "GEO_randomize.hh"

View File

@ -22,7 +22,7 @@
#include "BKE_instances.hh"
#include "BKE_material.h"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_type_conversions.hh"
namespace blender::geometry {

View File

@ -23,7 +23,7 @@ namespace blender::gpu {
/**
* Implementation of Multi Draw Indirect using OpenGL.
**/
*/
class MTLDrawList : public DrawList {
private:

View File

@ -163,7 +163,7 @@ struct MTLShaderBuilder {
* - set MSL source.
* - set Vertex/Fragment function names.
* - Create and populate #MTLShaderInterface.
**/
*/
class MTLShader : public Shader {
friend shader::ShaderCreateInfo;
friend shader::StageInterfaceInfo;

View File

@ -163,7 +163,7 @@ MTLVertexFormat mtl_datatype_to_vertex_type(eMTLDataType type);
/**
* Implementation of Shader interface for Metal Back-end.
**/
*/
class MTLShaderInterface : public ShaderInterface {
private:

View File

@ -24,7 +24,7 @@ class MTLContext;
/**
* State manager keeping track of the draw state and applying it before drawing.
* Metal Implementation.
**/
*/
class MTLStateManager : public StateManager {
private:

View File

@ -442,10 +442,10 @@ void MTLStateManager::set_blend(const eGPUBlend value)
/**
* Factors to the equation.
* SRC is fragment shader output.
* DST is framebuffer color.
* DST is frame-buffer color.
* final.rgb = SRC.rgb * src_rgb + DST.rgb * dst_rgb;
* final.a = SRC.a * src_alpha + DST.a * dst_alpha;
**/
*/
MTLBlendFactor src_rgb;
MTLBlendFactor dst_rgb;
MTLBlendFactor src_alpha;

View File

@ -19,7 +19,7 @@ class MTLStorageBuf;
/**
* Implementation of Uniform Buffers using Metal.
**/
*/
class MTLUniformBuf : public UniformBuf {
friend class MTLStorageBuf; /* For bind as SSBO resource access. */

View File

@ -28,7 +28,7 @@ class MTLVertBuf : public VertBuf {
friend class MTLStorageBuf; /* For bind as SSBO resource access and copy sub. */
private:
/** Metal buffer allocation. **/
/** Metal buffer allocation. */
gpu::MTLBuffer *vbo_ = nullptr;
/** Texture used if the buffer is bound as buffer texture. Init on first use. */
::GPUTexture *buffer_texture_ = nullptr;

View File

@ -27,7 +27,7 @@ class VKFrameBuffer : public FrameBuffer {
VkFramebuffer vk_framebuffer_ = VK_NULL_HANDLE;
/* Vulkan device who created the handle. */
VkDevice vk_device_ = VK_NULL_HANDLE;
/* Base render pass used for framebuffer creation. */
/* Base render pass used for frame-buffer creation. */
VkRenderPass vk_render_pass_ = VK_NULL_HANDLE;
/* Number of layers if the attachments are layered textures. */
int depth_ = 1;
@ -40,8 +40,8 @@ class VKFrameBuffer : public FrameBuffer {
public:
/**
* Create a conventional framebuffer to attach texture to.
**/
* Create a conventional frame-buffer to attach texture to.
*/
VKFrameBuffer(const char *name);
~VKFrameBuffer();

View File

@ -28,6 +28,12 @@ void VKSampler::create(const GPUSamplerState &sampler_state)
VkSamplerCreateInfo sampler_info = {};
sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
/* Extend */
sampler_info.addressModeU = to_vk_sampler_address_mode(sampler_state.extend_x);
sampler_info.addressModeV = sampler_info.addressModeW = to_vk_sampler_address_mode(
sampler_state.extend_yz);
sampler_info.minLod = 0;
sampler_info.maxLod = 1000;
if (sampler_state.type == GPU_SAMPLER_STATE_TYPE_PARAMETERS) {
/* Apply filtering. */
@ -38,17 +44,13 @@ void VKSampler::create(const GPUSamplerState &sampler_state)
if (sampler_state.filtering & GPU_SAMPLER_FILTERING_MIPMAP) {
sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
}
if (device.physical_device_features_get().samplerAnisotropy == VK_TRUE &&
sampler_state.filtering & GPU_SAMPLER_FILTERING_ANISOTROPIC)
if ((sampler_state.filtering & GPU_SAMPLER_FILTERING_ANISOTROPIC) &&
(U.anisotropic_filter > 1) &&
(device.physical_device_features_get().samplerAnisotropy == VK_TRUE))
{
sampler_info.anisotropyEnable = VK_TRUE;
sampler_info.maxAnisotropy = min_ff(1.0f, U.anisotropic_filter);
sampler_info.maxAnisotropy = U.anisotropic_filter;
}
/* Extend */
sampler_info.addressModeU = to_vk_sampler_address_mode(sampler_state.extend_x);
sampler_info.addressModeV = sampler_info.addressModeW = to_vk_sampler_address_mode(
sampler_state.extend_yz);
}
else if (sampler_state.type == GPU_SAMPLER_STATE_TYPE_CUSTOM) {
if (sampler_state.custom_type == GPU_SAMPLER_CUSTOM_ICON) {
@ -63,8 +65,6 @@ void VKSampler::create(const GPUSamplerState &sampler_state)
sampler_info.minFilter = VK_FILTER_LINEAR;
sampler_info.compareEnable = VK_TRUE;
sampler_info.compareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
sampler_info.minLod = -1000;
sampler_info.maxLod = 1000;
}
}

View File

@ -23,6 +23,18 @@
namespace blender::gpu {
static VkImageAspectFlags to_vk_image_aspect_single_bit(const VkImageAspectFlags format,
bool stencil)
{
switch (format) {
case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
return (stencil) ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
default:
break;
}
return format;
}
VKTexture::~VKTexture()
{
if (vk_image_ != VK_NULL_HANDLE && allocation_ != VK_NULL_HANDLE) {
@ -294,7 +306,8 @@ void VKTexture::update_sub(
region.imageOffset.x = offset[0];
region.imageOffset.y = offset[1];
region.imageOffset.z = offset[2];
region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(device_format_);
region.imageSubresource.aspectMask = to_vk_image_aspect_single_bit(
to_vk_image_aspect_flag_bits(device_format_), false);
region.imageSubresource.mipLevel = mip;
region.imageSubresource.layerCount = layers;

View File

@ -69,6 +69,9 @@ bool imb_save_tiff(ImBuf *ibuf, const char *filepath, int flags)
else if (ibuf->foptions.flag & TIF_COMPRESS_PACKBITS) {
file_spec.attribute("compression", "packbits");
}
else if (ibuf->foptions.flag & TIF_COMPRESS_NONE) {
file_spec.attribute("compression", "none");
}
return imb_oiio_write(ctx, filepath, file_spec);
}

View File

@ -72,10 +72,10 @@ void WorldData::init()
if (!input_socket) {
return;
}
bNodeLink const *link = input_socket->directly_linked_links()[0];
if (input_socket->directly_linked_links().is_empty()) {
return;
}
bNodeLink const *link = input_socket->directly_linked_links()[0];
bNode *input_node = link->fromnode;
if (input_node->type != SH_NODE_BACKGROUND) {

View File

@ -213,7 +213,7 @@ static const std::optional<bke::AttrDomain> convert_usd_varying_to_blender(
blender::Map<pxr::TfToken, bke::AttrDomain> map;
map.add_new(pxr::UsdGeomTokens->faceVarying, bke::AttrDomain::Corner);
map.add_new(pxr::UsdGeomTokens->vertex, bke::AttrDomain::Point);
map.add_new(pxr::UsdGeomTokens->varying, bke::AttrDomain::Point);
map.add_new(pxr::UsdGeomTokens->varying, bke::AttrDomain::Corner);
map.add_new(pxr::UsdGeomTokens->face, bke::AttrDomain::Face);
/* As there's no "constant" type in Blender, for now we're
* translating into a point Attribute. */

View File

@ -280,8 +280,7 @@ static void create_usd_preview_surface_material(const USDExporterContext &usd_ex
void set_normal_texture_range(pxr::UsdShadeShader &usd_shader, const InputSpec &input_spec)
{
/* Set the scale and bias for normal map textures
* The USD spec requires them to be within the -1 to 1 space
* */
* The USD spec requires them to be within the -1 to 1 space. */
/* Only run if this input_spec is for a normal. */
if (input_spec.input_name != usdtokens::normal) {

View File

@ -131,7 +131,7 @@ enum {
/**
* YAFRAY: light shadow-buffer flag, soft-light.
* Since it is used with LOCAL light, can't use LA_SHAD.
* */
*/
// LA_YF_SOFT = 1 << 14, /* Deprecated. */
// LA_LAYER_SHADOW = 1 << 15, /* Deprecated. */
// LA_SHAD_TEX = 1 << 16, /* Deprecated. */

View File

@ -301,9 +301,9 @@ enum PropertyFlag {
PROP_NO_DEG_UPDATE = (1 << 30),
/**
* Filepaths that refer to output get a special treatment such
* File-paths that refer to output get a special treatment such
* as having the +/- operators available in the file browser.
**/
*/
PROP_PATH_OUTPUT = (1 << 2),
};
ENUM_OPERATORS(PropertyFlag, PROP_TEXTEDIT_UPDATE)

View File

@ -506,7 +506,7 @@ static bool rna_Armature_collections_override_apply(Main *bmain,
/* These are stored by Blender when overridable properties are changed on the root
* collections, However, these are *also* created on the `armature.collections_all` property,
* which is actually where these per-collection overrides are handled. This doesn't seem to
* be proper behaviour, but I (Sybren) also don't want to spam the console about this as this
* be proper behavior, but I (Sybren) also don't want to spam the console about this as this
* is not something a user could fix. */
return false;
default:

View File

@ -1013,7 +1013,7 @@ static void rna_def_attribute_bool(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "MBoolProperty");
RNA_def_struct_ui_text(srna, "Bool Attribute Value", "Bool value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "b", 0x01);
RNA_def_property_boolean_sdna(prop, nullptr, "b", 0);
}
static void rna_def_attribute_int8(BlenderRNA *brna)

View File

@ -51,7 +51,7 @@
# include "BKE_object.hh"
# include "BKE_paint.hh"
# include "BKE_particle.h"
# include "BKE_pointcloud.h"
# include "BKE_pointcloud.hh"
# include "BKE_scene.h"
# include "BKE_sound.h"
# include "BKE_speaker.h"

View File

@ -23,7 +23,7 @@
# include "BLI_math_vector.h"
# include "BKE_customdata.hh"
# include "BKE_pointcloud.h"
# include "BKE_pointcloud.hh"
# include "DEG_depsgraph.hh"

View File

@ -54,7 +54,7 @@
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.hh"
#include "BKE_object.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_screen.hh"
#include "BKE_workspace.h"

View File

@ -325,17 +325,17 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
}
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", bke::AttrDomain::Face);
bke::mesh::normals_loop_custom_set(vert_positions,
edges,
faces,
corner_verts,
corner_edges,
mesh->vert_normals(),
mesh->face_normals(),
sharp_faces,
sharp_edges,
nos,
clnors);
bke::mesh::normals_corner_custom_set(vert_positions,
edges,
faces,
corner_verts,
corner_edges,
mesh->vert_normals(),
mesh->face_normals(),
sharp_faces,
sharp_edges,
nos,
clnors);
MEM_freeN(cos);
MEM_freeN(done_verts);
@ -431,17 +431,17 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
}
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", bke::AttrDomain::Face);
bke::mesh::normals_loop_custom_set(positions,
edges,
faces,
corner_verts,
corner_edges,
mesh->vert_normals(),
mesh->face_normals(),
sharp_faces,
sharp_edges,
nos,
clnors);
bke::mesh::normals_corner_custom_set(positions,
edges,
faces,
corner_verts,
corner_edges,
mesh->vert_normals(),
mesh->face_normals(),
sharp_faces,
sharp_edges,
nos,
clnors);
}
static bool is_valid_target(NormalEditModifierData *enmd)
@ -515,19 +515,19 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size()));
loop_normals.reinitialize(corner_verts.size());
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", bke::AttrDomain::Face);
blender::bke::mesh::normals_calc_loop(positions,
edges,
faces,
corner_verts,
corner_edges,
result->corner_to_face_map(),
result->vert_normals(),
result->face_normals(),
sharp_edges.span,
sharp_faces,
clnors,
nullptr,
loop_normals);
blender::bke::mesh::normals_calc_corners(positions,
edges,
faces,
corner_verts,
corner_edges,
result->corner_to_face_map(),
result->vert_normals(),
result->face_normals(),
sharp_edges.span,
sharp_faces,
clnors,
nullptr,
loop_normals);
}
if (clnors == nullptr) {

View File

@ -221,19 +221,19 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
/* This will give us loop normal spaces,
* we do not actually care about computed loop_normals for now... */
loop_normals.reinitialize(corner_verts.size());
bke::mesh::normals_calc_loop(positions,
edges,
faces,
corner_verts,
corner_edges,
loop_to_face,
wn_data->vert_normals,
wn_data->face_normals,
wn_data->sharp_edges,
wn_data->sharp_faces,
has_clnors ? clnors.data() : nullptr,
&lnors_spacearr,
loop_normals);
bke::mesh::normals_calc_corners(positions,
edges,
faces,
corner_verts,
corner_edges,
loop_to_face,
wn_data->vert_normals,
wn_data->face_normals,
wn_data->sharp_edges,
wn_data->sharp_faces,
has_clnors ? clnors.data() : nullptr,
&lnors_spacearr,
loop_normals);
WeightedNormalDataAggregateItem start_item{};
start_item.curr_strength = FACE_STRENGTH_WEAK;
@ -306,17 +306,17 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
}
}
blender::bke::mesh::normals_loop_custom_set(positions,
edges,
faces,
corner_verts,
corner_edges,
wn_data->vert_normals,
face_normals,
wn_data->sharp_faces,
wn_data->sharp_edges,
loop_normals,
clnors);
blender::bke::mesh::normals_corner_custom_set(positions,
edges,
faces,
corner_verts,
corner_edges,
wn_data->vert_normals,
face_normals,
wn_data->sharp_faces,
wn_data->sharp_edges,
loop_normals,
clnors);
}
else {
/* TODO: Ideally, we could add an option to `BKE_mesh_normals_loop_custom_[from_verts_]set()`
@ -335,33 +335,33 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal);
}
blender::bke::mesh::normals_loop_custom_set_from_verts(positions,
edges,
faces,
corner_verts,
corner_edges,
wn_data->vert_normals,
face_normals,
wn_data->sharp_faces,
wn_data->sharp_edges,
vert_normals,
clnors);
blender::bke::mesh::normals_corner_custom_set_from_verts(positions,
edges,
faces,
corner_verts,
corner_edges,
wn_data->vert_normals,
face_normals,
wn_data->sharp_faces,
wn_data->sharp_edges,
vert_normals,
clnors);
}
else {
loop_normals.reinitialize(corner_verts.size());
blender::bke::mesh::normals_calc_loop(positions,
edges,
faces,
corner_verts,
corner_edges,
loop_to_face,
wn_data->vert_normals,
face_normals,
wn_data->sharp_edges,
wn_data->sharp_faces,
has_clnors ? clnors.data() : nullptr,
nullptr,
loop_normals);
blender::bke::mesh::normals_calc_corners(positions,
edges,
faces,
corner_verts,
corner_edges,
loop_to_face,
wn_data->vert_normals,
face_normals,
wn_data->sharp_edges,
wn_data->sharp_faces,
has_clnors ? clnors.data() : nullptr,
nullptr,
loop_normals);
for (int corner = 0; corner < corner_verts.size(); corner++) {
const int item_index = corner_verts[corner];
@ -369,17 +369,17 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
copy_v3_v3(loop_normals[corner], items_data[item_index].normal);
}
}
blender::bke::mesh::normals_loop_custom_set(positions,
edges,
faces,
corner_verts,
corner_edges,
wn_data->vert_normals,
face_normals,
wn_data->sharp_faces,
wn_data->sharp_edges,
loop_normals,
clnors);
blender::bke::mesh::normals_corner_custom_set(positions,
edges,
faces,
corner_verts,
corner_edges,
wn_data->vert_normals,
face_normals,
wn_data->sharp_faces,
wn_data->sharp_edges,
loop_normals,
clnors);
}
}
}

View File

@ -11,7 +11,7 @@
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.hh"
#include "BKE_node.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "NOD_rna_define.hh"
#include "NOD_socket_search_link.hh"

View File

@ -12,7 +12,7 @@
#include "BKE_customdata.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_instances.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "GEO_resample_curves.hh"

View File

@ -14,7 +14,7 @@
#include "BKE_grease_pencil.hh"
#include "BKE_instances.hh"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "GEO_mesh_copy_selection.hh"

View File

@ -11,7 +11,7 @@
#include "DNA_node_types.h"
#include "DNA_pointcloud_types.h"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "BKE_volume.hh"
#include "BKE_volume_grid.hh"

View File

@ -18,7 +18,7 @@
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.hh"
#include "BKE_mesh_sample.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "UI_interface.hh"
#include "UI_resources.hh"

View File

@ -15,7 +15,7 @@
#include "BKE_curves.hh"
#include "BKE_instances.hh"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "node_geometry_util.hh"

View File

@ -8,7 +8,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_instances.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "node_geometry_util.hh"

View File

@ -11,7 +11,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_customdata.hh"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
#include "BKE_pointcloud.hh"
#include "NOD_rna_define.hh"

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