GPv3: Opacity modifier #116946
30
AUTHORS
30
AUTHORS
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
/* -- */
|
||||
#include "BKE_object.hh"
|
||||
/* -- */
|
||||
#include "BKE_pointcloud.h"
|
||||
#include "BKE_pointcloud.hh"
|
||||
|
||||
#include "BKE_curve_to_mesh.hh"
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -125,9 +125,6 @@ class ConvertColorToVectorOperation : public ConversionOperation {
|
|||
* components.
|
||||
* \{ */
|
||||
|
||||
/*
|
||||
*
|
||||
* */
|
||||
class ConvertVectorToFloatOperation : public ConversionOperation {
|
||||
public:
|
||||
ConvertVectorToFloatOperation(Context &context);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace blender::gpu {
|
|||
|
||||
/**
|
||||
* Implementation of Multi Draw Indirect using OpenGL.
|
||||
**/
|
||||
*/
|
||||
class MTLDrawList : public DrawList {
|
||||
|
||||
private:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue