Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2021-05-26 13:43:49 +0300
committerAntonio Vazquez <blendergit@gmail.com>2021-05-26 13:43:49 +0300
commit786aa4b5181e53151180df5158e722dd4a45e901 (patch)
tree40203ae5171e0cd393a55f331e207de90c151ef1
parent0330805ec7a8d79a0b7d0b1f49b06e0abf2065bc (diff)
parentafec66c024dc2b75447537d45406c06342ec201e (diff)
Merge branch 'master' into eevee-gpencil
-rw-r--r--build_files/build_environment/cmake/versions.cmake8
-rwxr-xr-xbuild_files/build_environment/install_deps.sh6
-rw-r--r--intern/cycles/blender/blender_sync.cpp14
-rw-r--r--intern/cycles/blender/blender_sync.h2
-rw-r--r--intern/cycles/blender/blender_viewport.cpp27
-rw-r--r--intern/cycles/device/device_optix.cpp6
-rw-r--r--intern/cycles/render/alembic.cpp3
-rw-r--r--intern/cycles/render/attribute.cpp61
-rw-r--r--intern/cycles/render/attribute.h33
-rw-r--r--intern/cycles/render/geometry.cpp86
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp36
-rw-r--r--intern/mikktspace/README.md4
-rw-r--r--release/scripts/modules/bl_previews_utils/bl_previews_render.py14
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py47
-rw-r--r--release/scripts/startup/bl_operators/geometry_nodes.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py20
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py2
-rw-r--r--release/scripts/startup/nodeitems_builtins.py10
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh35
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/intern/armature.c2
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc8
-rw-r--r--source/blender/blenkernel/intern/attribute_math.cc15
-rw-r--r--source/blender/blenkernel/intern/fluid.c6
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc56
-rw-r--r--source/blender/blenkernel/intern/lib_id_test.cc1
-rw-r--r--source/blender/blenkernel/intern/node.cc2
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenlib/BLI_color.hh302
-rw-r--r--source/blender/blenlib/CMakeLists.txt2
-rw-r--r--source/blender/blenlib/intern/BLI_color.cc55
-rw-r--r--source/blender/blenlib/tests/BLI_color_test.cc133
-rw-r--r--source/blender/compositor/operations/COM_ConvertOperation.cc35
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc68
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h58
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cc53
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.h5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc4
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h4
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h7
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.cc (renamed from source/blender/draw/intern/draw_cache_impl_curve.c)79
-rw-r--r--source/blender/draw/intern/draw_cache_inline.h4
-rw-r--r--source/blender/editors/geometry/geometry_attributes.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c30
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c4
-rw-r--r--source/blender/editors/object/object_add.c11
-rw-r--r--source/blender/editors/object/object_vgroup.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c5
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_layout.cc2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c3
-rw-r--r--source/blender/editors/transform/transform.c156
-rw-r--r--source/blender/editors/transform/transform.h4
-rw-r--r--source/blender/editors/transform/transform_constraints.c7
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c3
-rw-r--r--source/blender/functions/intern/cpp_types.cc4
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h82
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c586
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c989
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h39
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_util.c6
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.cc10
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.hh2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_capi.cc10
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h2
-rw-r--r--source/blender/makesdna/DNA_view3d_defaults.h1
-rw-r--r--source/blender/makesrna/intern/rna_ID.c21
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c1
-rw-r--r--source/blender/makesrna/intern/rna_object.c10
-rw-r--r--source/blender/makesrna/intern/rna_particle.c12
-rw-r--r--source/blender/makesrna/intern/rna_space.c1
-rw-r--r--source/blender/modifiers/intern/MOD_nodes_evaluator.cc32
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_curve_map.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_separate.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_switch.cc4
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc5
-rw-r--r--source/blender/nodes/intern/node_socket.cc4
-rw-r--r--source/blender/nodes/intern/node_tree_ref.cc6
-rw-r--r--source/blender/nodes/intern/type_conversions.cc50
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.cc (renamed from source/blender/nodes/shader/nodes/node_shader_curves.c)112
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.cc8
-rw-r--r--source/blender/sequencer/SEQ_sequencer.h1
-rw-r--r--source/blender/sequencer/intern/render.c18
-rw-r--r--source/blender/sequencer/intern/sequencer.c15
96 files changed, 2194 insertions, 1510 deletions
diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake
index 83e438614b6..4500245d42a 100644
--- a/build_files/build_environment/cmake/versions.cmake
+++ b/build_files/build_environment/cmake/versions.cmake
@@ -43,7 +43,7 @@ set(JPEG_FILE libjpeg-turbo-${JPEG_VERSION}.tar.gz)
set(BOOST_VERSION 1.73.0)
set(BOOST_VERSION_NODOTS 1_73_0)
set(BOOST_VERSION_NODOTS_SHORT 1_73)
-set(BOOST_URI https://dl.bintray.com/boostorg/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz)
+set(BOOST_URI https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz)
set(BOOST_HASH 4036cd27ef7548b8d29c30ea10956196)
set(BOOST_HASH_TYPE MD5)
set(BOOST_FILE boost_${BOOST_VERSION_NODOTS}.tar.gz)
@@ -297,10 +297,10 @@ set(OPENJPEG_HASH 63f5a4713ecafc86de51bfad89cc07bb788e9bba24ebbf0c4ca637621aadb6
set(OPENJPEG_HASH_TYPE SHA256)
set(OPENJPEG_FILE openjpeg-v${OPENJPEG_VERSION}.tar.gz)
-set(FFMPEG_VERSION 4.2.3)
+set(FFMPEG_VERSION 4.4)
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
-set(FFMPEG_HASH 695fad11f3baf27784e24cb0e977b65a)
-set(FFMPEG_HASH_TYPE MD5)
+set(FFMPEG_HASH 42093549751b582cf0f338a21a3664f52e0a9fbe0d238d3c992005e493607d0e)
+set(FFMPEG_HASH_TYPE SHA256)
set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2)
set(FFTW_VERSION 3.3.8)
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 18922799d08..71ddeaa4576 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -563,9 +563,9 @@ OIDN_SKIP=false
ISPC_VERSION="1.14.1"
-FFMPEG_VERSION="4.2.3"
-FFMPEG_VERSION_SHORT="4.2"
-FFMPEG_VERSION_MIN="3.0"
+FFMPEG_VERSION="4.4"
+FFMPEG_VERSION_SHORT="4.4"
+FFMPEG_VERSION_MIN="4.4"
FFMPEG_VERSION_MAX="5.0"
FFMPEG_FORCE_BUILD=false
FFMPEG_FORCE_REBUILD=false
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 9d0f9f29f94..bacf57df48e 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -224,8 +224,18 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
if (b_v3d) {
BlenderViewportParameters new_viewport_parameters(b_v3d);
+
if (viewport_parameters.modified(new_viewport_parameters)) {
world_recalc = true;
+ has_updates_ = true;
+ }
+
+ if (!has_updates_) {
+ Film *film = scene->film;
+
+ const PassType new_display_pass = new_viewport_parameters.get_viewport_display_render_pass(
+ b_v3d);
+ has_updates_ |= film->get_display_pass() != new_display_pass;
}
}
}
@@ -246,7 +256,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
- sync_view_layer(b_v3d, b_view_layer);
+ sync_view_layer(b_view_layer);
sync_integrator();
sync_film(b_v3d);
sync_shaders(b_depsgraph, b_v3d);
@@ -441,7 +451,7 @@ void BlenderSync::sync_film(BL::SpaceView3D &b_v3d)
/* Render Layer */
-void BlenderSync::sync_view_layer(BL::SpaceView3D & /*b_v3d*/, BL::ViewLayer &b_view_layer)
+void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
{
view_layer.name = b_view_layer.name();
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 15a10f2b46b..8cd65f13f70 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -73,7 +73,7 @@ class BlenderSync {
int width,
int height,
void **python_thread_state);
- void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
+ void sync_view_layer(BL::ViewLayer &b_view_layer);
vector<Pass> sync_render_passes(BL::Scene &b_scene,
BL::RenderLayer &b_render_layer,
BL::ViewLayer &b_view_layer,
diff --git a/intern/cycles/blender/blender_viewport.cpp b/intern/cycles/blender/blender_viewport.cpp
index 73ef5f94720..aac3d41314a 100644
--- a/intern/cycles/blender/blender_viewport.cpp
+++ b/intern/cycles/blender/blender_viewport.cpp
@@ -32,17 +32,26 @@ BlenderViewportParameters::BlenderViewportParameters()
BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d)
: BlenderViewportParameters()
{
+ if (!b_v3d) {
+ return;
+ }
+
+ BL::View3DShading shading = b_v3d.shading();
+
/* We only copy the parameters if we are in look dev mode. otherwise
* defaults are being used. These defaults mimic normal render settings */
- if (b_v3d && b_v3d.shading().type() == BL::View3DShading::type_RENDERED) {
- use_scene_world = b_v3d.shading().use_scene_world_render();
- use_scene_lights = b_v3d.shading().use_scene_lights_render();
- if (!use_scene_world) {
- studiolight_rotate_z = b_v3d.shading().studiolight_rotate_z();
- studiolight_intensity = b_v3d.shading().studiolight_intensity();
- studiolight_background_alpha = b_v3d.shading().studiolight_background_alpha();
- studiolight_path = b_v3d.shading().selected_studio_light().path();
- }
+ if (shading.type() != BL::View3DShading::type_RENDERED) {
+ return;
+ }
+
+ use_scene_world = shading.use_scene_world_render();
+ use_scene_lights = shading.use_scene_lights_render();
+
+ if (!use_scene_world) {
+ studiolight_rotate_z = shading.studiolight_rotate_z();
+ studiolight_intensity = shading.studiolight_intensity();
+ studiolight_background_alpha = shading.studiolight_background_alpha();
+ studiolight_path = shading.selected_studio_light().path();
}
}
diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp
index 01de0724cb2..b008dfa376f 100644
--- a/intern/cycles/device/device_optix.cpp
+++ b/intern/cycles/device/device_optix.cpp
@@ -726,7 +726,11 @@ class OptiXDevice : public CUDADevice {
}
}
else if (task.type == DeviceTask::SHADER) {
- launch_shader_eval(task, thread_index);
+ // CUDA kernels are used when doing baking
+ if (optix_module == NULL)
+ CUDADevice::shader(task);
+ else
+ launch_shader_eval(task, thread_index);
}
else if (task.type == DeviceTask::DENOISE_BUFFER) {
// Set up a single tile that covers the whole task and denoise it
diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp
index cf345ee075d..dcb456dc1ce 100644
--- a/intern/cycles/render/alembic.cpp
+++ b/intern/cycles/render/alembic.cpp
@@ -654,8 +654,7 @@ static void update_attributes(AttributeSet &attributes, CachedData &cached_data,
list<Attribute>::iterator it;
for (it = attributes.attributes.begin(); it != attributes.attributes.end();) {
if (cached_attributes.find(&(*it)) == cached_attributes.end()) {
- attributes.attributes.erase(it++);
- attributes.modified = true;
+ attributes.remove(it++);
continue;
}
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index d6a638fd4cd..bf9d69cb47e 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -383,6 +383,23 @@ AttributeStandard Attribute::name_standard(const char *name)
return ATTR_STD_NONE;
}
+AttrKernelDataType Attribute::kernel_type(const Attribute &attr)
+{
+ if (attr.element == ATTR_ELEMENT_CORNER) {
+ return AttrKernelDataType::UCHAR4;
+ }
+
+ if (attr.type == TypeDesc::TypeFloat) {
+ return AttrKernelDataType::FLOAT;
+ }
+
+ if (attr.type == TypeFloat2) {
+ return AttrKernelDataType::FLOAT2;
+ }
+
+ return AttrKernelDataType::FLOAT3;
+}
+
void Attribute::get_uv_tiles(Geometry *geom,
AttributePrimitive prim,
unordered_set<int> &tiles) const
@@ -417,7 +434,7 @@ void Attribute::get_uv_tiles(Geometry *geom,
/* Attribute Set */
AttributeSet::AttributeSet(Geometry *geometry, AttributePrimitive prim)
- : geometry(geometry), prim(prim)
+ : modified_flag(~0u), geometry(geometry), prim(prim)
{
}
@@ -440,7 +457,7 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
Attribute new_attr(name, type, element, geometry, prim);
attributes.emplace_back(std::move(new_attr));
- modified = true;
+ tag_modified(attributes.back());
return &attributes.back();
}
@@ -462,8 +479,7 @@ void AttributeSet::remove(ustring name)
for (it = attributes.begin(); it != attributes.end(); it++) {
if (&*it == attr) {
- modified = true;
- attributes.erase(it);
+ remove(it);
return;
}
}
@@ -608,8 +624,7 @@ void AttributeSet::remove(AttributeStandard std)
for (it = attributes.begin(); it != attributes.end(); it++) {
if (&*it == attr) {
- modified = true;
- attributes.erase(it);
+ remove(it);
return;
}
}
@@ -634,6 +649,12 @@ void AttributeSet::remove(Attribute *attribute)
}
}
+void AttributeSet::remove(list<Attribute>::iterator it)
+{
+ tag_modified(*it);
+ attributes.erase(it);
+}
+
void AttributeSet::resize(bool reserve_only)
{
foreach (Attribute &attr, attributes) {
@@ -674,15 +695,13 @@ void AttributeSet::update(AttributeSet &&new_attributes)
for (it = attributes.begin(); it != attributes.end();) {
if (it->std != ATTR_STD_NONE) {
if (new_attributes.find(it->std) == nullptr) {
- modified = true;
- attributes.erase(it++);
+ remove(it++);
continue;
}
}
else if (it->name != "") {
if (new_attributes.find(it->name) == nullptr) {
- modified = true;
- attributes.erase(it++);
+ remove(it++);
continue;
}
}
@@ -699,7 +718,27 @@ void AttributeSet::clear_modified()
foreach (Attribute &attr, attributes) {
attr.modified = false;
}
- modified = false;
+
+ modified_flag = 0;
+}
+
+void AttributeSet::tag_modified(const Attribute &attr)
+{
+ /* Some attributes are not stored in the various kernel attribute arrays
+ * (DeviceScene::attribute_*), so the modified flags are only set if the associated standard
+ * corresponds to an attribute which will be stored in the kernel's attribute arrays. */
+ const bool modifies_device_array = (attr.std != ATTR_STD_FACE_NORMAL &&
+ attr.std != ATTR_STD_VERTEX_NORMAL);
+
+ if (modifies_device_array) {
+ AttrKernelDataType kernel_type = Attribute::kernel_type(attr);
+ modified_flag |= (1u << kernel_type);
+ }
+}
+
+bool AttributeSet::modified(AttrKernelDataType kernel_type) const
+{
+ return (modified_flag & (1u << kernel_type)) != 0;
}
/* AttributeRequest */
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index 18c9e5ab83a..004c267cabc 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -39,6 +39,21 @@ class Hair;
class Mesh;
struct Transform;
+/* AttrKernelDataType.
+ *
+ * The data type of the device arrays storing the attribute's data. Those data types are different
+ * than the ones for attributes as some attribute types are stored in the same array, e.g. Point,
+ * Vector, and Transform are all stored as float3 in the kernel.
+ *
+ * The values of this enumeration are also used as flags to detect changes in AttributeSet. */
+
+enum AttrKernelDataType {
+ FLOAT = 0,
+ FLOAT2 = 1,
+ FLOAT3 = 2,
+ UCHAR4 = 3,
+};
+
/* Attribute
*
* Arbitrary data layers on meshes.
@@ -167,6 +182,8 @@ class Attribute {
static const char *standard_name(AttributeStandard std);
static AttributeStandard name_standard(const char *name);
+ static AttrKernelDataType kernel_type(const Attribute &attr);
+
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set<int> &tiles) const;
};
@@ -175,11 +192,12 @@ class Attribute {
* Set of attributes on a mesh. */
class AttributeSet {
+ uint32_t modified_flag;
+
public:
Geometry *geometry;
AttributePrimitive prim;
list<Attribute> attributes;
- bool modified = true;
AttributeSet(Geometry *geometry, AttributePrimitive prim);
AttributeSet(AttributeSet &&) = default;
@@ -197,6 +215,8 @@ class AttributeSet {
void remove(Attribute *attribute);
+ void remove(list<Attribute>::iterator it);
+
void resize(bool reserve_only = false);
void clear(bool preserve_voxel_data = false);
@@ -204,7 +224,18 @@ class AttributeSet {
* and remove any attribute not found on the new set from this. */
void update(AttributeSet &&new_attributes);
+ /* Return whether the attributes of the given kernel_type are modified, where "modified" means
+ * that some attributes of the given type were added or removed from this AttributeSet. This does
+ * not mean that the data of the remaining attributes in this AttributeSet were also modified. To
+ * check this, use Attribute.modified. */
+ bool modified(AttrKernelDataType kernel_type) const;
+
void clear_modified();
+
+ private:
+ /* Set the relevant modified flag for the attribute. Only attributes that are stored in device
+ * arrays will be considered for tagging this AttributeSet as modified. */
+ void tag_modified(const Attribute &attr);
};
/* AttributeRequest
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index 16fc36231b4..1c4b360750f 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -830,10 +830,13 @@ void GeometryManager::device_update_attributes(Device *device,
dscene->attributes_float3.alloc(attr_float3_size);
dscene->attributes_uchar4.alloc(attr_uchar4_size);
- const bool copy_all_data = dscene->attributes_float.need_realloc() ||
- dscene->attributes_float2.need_realloc() ||
- dscene->attributes_float3.need_realloc() ||
- dscene->attributes_uchar4.need_realloc();
+ /* The order of those flags needs to match that of AttrKernelDataType. */
+ const bool attributes_need_realloc[4] = {
+ dscene->attributes_float.need_realloc(),
+ dscene->attributes_float2.need_realloc(),
+ dscene->attributes_float3.need_realloc(),
+ dscene->attributes_uchar4.need_realloc(),
+ };
size_t attr_float_offset = 0;
size_t attr_float2_offset = 0;
@@ -852,7 +855,7 @@ void GeometryManager::device_update_attributes(Device *device,
if (attr) {
/* force a copy if we need to reallocate all the data */
- attr->modified |= copy_all_data;
+ attr->modified |= attributes_need_realloc[Attribute::kernel_type(*attr)];
}
update_attribute_element_offset(geom,
@@ -875,7 +878,7 @@ void GeometryManager::device_update_attributes(Device *device,
if (subd_attr) {
/* force a copy if we need to reallocate all the data */
- subd_attr->modified |= copy_all_data;
+ subd_attr->modified |= attributes_need_realloc[Attribute::kernel_type(*subd_attr)];
}
update_attribute_element_offset(mesh,
@@ -906,6 +909,10 @@ void GeometryManager::device_update_attributes(Device *device,
foreach (AttributeRequest &req, attributes.requests) {
Attribute *attr = values.find(req);
+ if (attr) {
+ attr->modified |= attributes_need_realloc[Attribute::kernel_type(*attr)];
+ }
+
update_attribute_element_offset(object->geometry,
dscene->attributes_float,
attr_float_offset,
@@ -941,10 +948,10 @@ void GeometryManager::device_update_attributes(Device *device,
/* copy to device */
progress.set_status("Updating Mesh", "Copying Attributes to device");
- dscene->attributes_float.copy_to_device();
- dscene->attributes_float2.copy_to_device();
- dscene->attributes_float3.copy_to_device();
- dscene->attributes_uchar4.copy_to_device();
+ dscene->attributes_float.copy_to_device_if_modified();
+ dscene->attributes_float2.copy_to_device_if_modified();
+ dscene->attributes_float3.copy_to_device_if_modified();
+ dscene->attributes_uchar4.copy_to_device_if_modified();
if (progress.get_cancel())
return;
@@ -1431,24 +1438,46 @@ static void update_device_flags_attribute(uint32_t &device_update_flags,
continue;
}
- if (attr.element == ATTR_ELEMENT_CORNER) {
- device_update_flags |= ATTR_UCHAR4_MODIFIED;
- }
- else if (attr.type == TypeDesc::TypeFloat) {
- device_update_flags |= ATTR_FLOAT_MODIFIED;
- }
- else if (attr.type == TypeFloat2) {
- device_update_flags |= ATTR_FLOAT2_MODIFIED;
- }
- else if (attr.type == TypeDesc::TypeMatrix) {
- device_update_flags |= ATTR_FLOAT3_MODIFIED;
- }
- else if (attr.element != ATTR_ELEMENT_VOXEL) {
- device_update_flags |= ATTR_FLOAT3_MODIFIED;
+ AttrKernelDataType kernel_type = Attribute::kernel_type(attr);
+
+ switch (kernel_type) {
+ case AttrKernelDataType::FLOAT: {
+ device_update_flags |= ATTR_FLOAT_MODIFIED;
+ break;
+ }
+ case AttrKernelDataType::FLOAT2: {
+ device_update_flags |= ATTR_FLOAT2_MODIFIED;
+ break;
+ }
+ case AttrKernelDataType::FLOAT3: {
+ device_update_flags |= ATTR_FLOAT3_MODIFIED;
+ break;
+ }
+ case AttrKernelDataType::UCHAR4: {
+ device_update_flags |= ATTR_UCHAR4_MODIFIED;
+ break;
+ }
}
}
}
+static void update_attribute_realloc_flags(uint32_t &device_update_flags,
+ const AttributeSet &attributes)
+{
+ if (attributes.modified(AttrKernelDataType::FLOAT)) {
+ device_update_flags |= ATTR_FLOAT_NEEDS_REALLOC;
+ }
+ if (attributes.modified(AttrKernelDataType::FLOAT2)) {
+ device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
+ }
+ if (attributes.modified(AttrKernelDataType::FLOAT3)) {
+ device_update_flags |= ATTR_FLOAT3_NEEDS_REALLOC;
+ }
+ if (attributes.modified(AttrKernelDataType::UCHAR4)) {
+ device_update_flags |= ATTR_UCHAR4_NEEDS_REALLOC;
+ }
+}
+
void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
{
if (!need_update() && !need_flags_update) {
@@ -1471,16 +1500,11 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
foreach (Geometry *geom, scene->geometry) {
geom->has_volume = false;
- if (geom->attributes.modified) {
- device_update_flags |= ATTRS_NEED_REALLOC;
- }
+ update_attribute_realloc_flags(device_update_flags, geom->attributes);
if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
-
- if (mesh->subd_attributes.modified) {
- device_update_flags |= ATTRS_NEED_REALLOC;
- }
+ update_attribute_realloc_flags(device_update_flags, mesh->subd_attributes);
}
foreach (Node *node, geom->get_used_shaders()) {
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index ef155d96f99..3af92153e8b 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -121,22 +121,30 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
monitor.dwFlags = 0;
GetMonitorInfo(MonitorFromRect(&win_rect, MONITOR_DEFAULTTONEAREST), &monitor);
- /* Adjust our requested size to allow for caption and borders and constrain to monitor. */
- AdjustWindowRectEx(&win_rect, WS_CAPTION, FALSE, 0);
+ /* Constrain requested size and position to fit within this monitor. */
width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect.right - win_rect.left);
- left = min(max(monitor.rcWork.left, win_rect.left), monitor.rcWork.right - width);
height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect.bottom - win_rect.top);
- top = min(max(monitor.rcWork.top, win_rect.top), monitor.rcWork.bottom - height);
-
- m_hWnd = ::CreateWindowExW(extended_style, // window extended style
- s_windowClassName, // pointer to registered class name
- title_16, // pointer to window name
- style, // window style
- left, // horizontal position of window
- top, // vertical position of window
- width, // window width
- height, // window height
- m_parentWindowHwnd, // handle to parent or owner window
+ win_rect.left = min(max(monitor.rcWork.left, win_rect.left), monitor.rcWork.right - width);
+ win_rect.right = win_rect.left + width;
+ win_rect.top = min(max(monitor.rcWork.top, win_rect.top), monitor.rcWork.bottom - height);
+ win_rect.bottom = win_rect.top + height;
+
+ /* Adjust to allow for caption, borders, shadows, scaling, etc. Resulting values can be
+ * correctly outside of monitor bounds. Note: You cannot specify WS_OVERLAPPED when calling. */
+ AdjustWindowRectEx(&win_rect, style & ~WS_OVERLAPPED, FALSE, extended_style);
+
+ /* But never allow a top position that can hide part of the title bar. */
+ win_rect.top = max(monitor.rcWork.top, win_rect.top);
+
+ m_hWnd = ::CreateWindowExW(extended_style, // window extended style
+ s_windowClassName, // pointer to registered class name
+ title_16, // pointer to window name
+ style, // window style
+ win_rect.left, // horizontal position of window
+ win_rect.top, // vertical position of window
+ win_rect.right - win_rect.left, // window width
+ win_rect.bottom - win_rect.top, // window height
+ m_parentWindowHwnd, // handle to parent or owner window
0, // handle to menu or child-window identifier
::GetModuleHandle(0), // handle to application instance
0); // pointer to window-creation data
diff --git a/intern/mikktspace/README.md b/intern/mikktspace/README.md
new file mode 100644
index 00000000000..9fda1559e44
--- /dev/null
+++ b/intern/mikktspace/README.md
@@ -0,0 +1,4 @@
+# MikkTSpace
+A common standard for tangent space used in baking tools to produce normal maps.
+
+More information can be found at http://www.mikktspace.com/.
diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py
index 979b47f7a14..51ea53c0eba 100644
--- a/release/scripts/modules/bl_previews_utils/bl_previews_render.py
+++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py
@@ -37,6 +37,9 @@ OBJECT_TYPES_RENDER = {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'}
def ids_nolib(bids):
return (bid for bid in bids if not bid.library)
+def ids_nolib_with_preview(bids):
+ return (bid for bid in bids if (not bid.library and bid.preview))
+
def rna_backup_gen(data, include_props=None, exclude_props=None, root=()):
# only writable properties...
@@ -313,8 +316,9 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
image = bpy.data.images[render_context.image, None]
item = getattr(bpy.data, item_container)[item_name, None]
image.reload()
- item.preview.image_size = (RENDER_PREVIEW_SIZE, RENDER_PREVIEW_SIZE)
- item.preview.image_pixels_float[:] = image.pixels
+ preview = item.preview_ensure()
+ preview.image_size = (RENDER_PREVIEW_SIZE, RENDER_PREVIEW_SIZE)
+ preview.image_pixels_float[:] = image.pixels
# And now, main code!
do_save = True
@@ -451,15 +455,15 @@ def do_clear_previews(do_objects, do_collections, do_scenes, do_data_intern):
bpy.ops.wm.previews_clear(id_type={'SHADING'})
if do_objects:
- for ob in ids_nolib(bpy.data.objects):
+ for ob in ids_nolib_with_preview(bpy.data.objects):
ob.preview.image_size = (0, 0)
if do_collections:
- for grp in ids_nolib(bpy.data.collections):
+ for grp in ids_nolib_with_preview(bpy.data.collections):
grp.preview.image_size = (0, 0)
if do_scenes:
- for scene in ids_nolib(bpy.data.scenes):
+ for scene in ids_nolib_with_preview(bpy.data.scenes):
scene.preview.image_size = (0, 0)
print("Saving %s..." % bpy.data.filepath)
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 9bccc69d41f..d63ae7a2745 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -4485,8 +4485,7 @@ def km_sculpt(params):
items.extend([
# Transfer Sculpt Mode (release to avoid conflict with grease pencil drawing).
- ("object.transfer_mode", {"type": 'D', "value": 'RELEASE'},
- {"properties": [("use_eyedropper", False)]}),
+ ("object.transfer_mode", {"type": 'D', "value": 'RELEASE'}, None),
# Brush strokes
("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("mode", 'NORMAL')]}),
@@ -5026,32 +5025,30 @@ def km_object_non_modal(params):
{"properties": [("mode", 'VERTEX_PAINT'), ("toggle", True)]}),
("object.mode_set", {"type": 'TAB', "value": 'PRESS', "ctrl": True},
{"properties": [("mode", 'WEIGHT_PAINT'), ("toggle", True)]}),
- ])
- elif params.use_pie_click_drag:
- items.extend([
- ("object.mode_set", {"type": 'TAB', "value": 'CLICK'},
- {"properties": [("mode", 'EDIT'), ("toggle", True)]}),
- op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'CLICK_DRAG'}),
- ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None),
- ])
- elif not params.use_v3d_tab_menu:
- items.extend([
- ("object.mode_set", {"type": 'TAB', "value": 'PRESS'},
- {"properties": [("mode", 'EDIT'), ("toggle", True)]}),
- ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None),
- ])
- else:
- # Swap Tab/Ctrl-Tab
- items.extend([
- ("object.mode_set", {"type": 'TAB', "value": 'PRESS', "ctrl": True},
- {"properties": [("mode", 'EDIT'), ("toggle", True)]}),
- op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'PRESS'}),
- ])
- if params.legacy:
- items.extend([
("object.origin_set", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None),
])
+ else:
+ if params.use_pie_click_drag:
+ items.extend([
+ ("object.mode_set", {"type": 'TAB', "value": 'CLICK'},
+ {"properties": [("mode", 'EDIT'), ("toggle", True)]}),
+ op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'CLICK_DRAG'}),
+ ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None),
+ ])
+ elif params.use_v3d_tab_menu:
+ # Swap Tab/Ctrl-Tab
+ items.extend([
+ ("object.mode_set", {"type": 'TAB', "value": 'PRESS', "ctrl": True},
+ {"properties": [("mode", 'EDIT'), ("toggle", True)]}),
+ op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'PRESS'}),
+ ])
+ else:
+ items.extend([
+ ("object.mode_set", {"type": 'TAB', "value": 'PRESS'},
+ {"properties": [("mode", 'EDIT'), ("toggle", True)]}),
+ ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None),
+ ])
return keymap
diff --git a/release/scripts/startup/bl_operators/geometry_nodes.py b/release/scripts/startup/bl_operators/geometry_nodes.py
index 0c7a2a01b7a..71ef89a066b 100644
--- a/release/scripts/startup/bl_operators/geometry_nodes.py
+++ b/release/scripts/startup/bl_operators/geometry_nodes.py
@@ -42,8 +42,8 @@ def geometry_node_group_empty_new():
def geometry_modifier_poll(context):
ob = context.object
- # Test object support for geometry node modifier (No volume, curve, or hair object support yet)
- if not ob or ob.type not in {'MESH', 'POINTCLOUD'}:
+ # Test object support for geometry node modifier (No curve, or hair object support yet)
+ if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME'}:
return False
return True
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index a9f040db9b5..ae15fda2c69 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -1803,9 +1803,10 @@ class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel):
part = particle_get_settings(context)
- col = layout.column()
- col.prop(part.force_field_1, "type", text="Type 1")
- basic_force_field_settings_ui(self, part.force_field_1)
+ if part.force_field_1:
+ col = layout.column()
+ col.prop(part.force_field_1, "type", text="Type 1")
+ basic_force_field_settings_ui(self, part.force_field_1)
class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel):
@@ -1819,9 +1820,10 @@ class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel):
part = particle_get_settings(context)
- col = layout.column()
- col.prop(part.force_field_2, "type", text="Type 2")
- basic_force_field_settings_ui(self, part.force_field_2)
+ if part.force_field_2:
+ col = layout.column()
+ col.prop(part.force_field_2, "type", text="Type 2")
+ basic_force_field_settings_ui(self, part.force_field_2)
class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel):
@@ -1836,7 +1838,8 @@ class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel):
part = particle_get_settings(context)
- basic_force_field_falloff_ui(self, part.force_field_1)
+ if part.force_field_1:
+ basic_force_field_falloff_ui(self, part.force_field_1)
class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel):
@@ -1851,7 +1854,8 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel):
part = particle_get_settings(context)
- basic_force_field_falloff_ui(self, part.force_field_2)
+ if part.force_field_2:
+ basic_force_field_falloff_ui(self, part.force_field_2)
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index 7f55e4888cf..f13a808e324 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -79,7 +79,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
col = flow.column()
- if obj.field.type == 'NONE':
+ if not obj.field or obj.field.type == 'NONE':
col.operator("object.forcefield_toggle", text="Force Field", icon='FORCE_FORCE')
else:
col.operator("object.forcefield_toggle", text="Force Field", icon='X')
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index bae2c14e3d9..4bff18cd1be 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -472,14 +472,6 @@ texture_node_categories = [
]),
]
-
-def not_implemented_node(idname):
- NodeType = getattr(bpy.types, idname)
- name = NodeType.bl_rna.name
- label = "%s (mockup)" % name
- return NodeItem(idname, label=label)
-
-
geometry_node_categories = [
# Geometry Nodes
GeometryNodeCategory("GEO_ATTRIBUTE", "Attribute", items=[
@@ -503,6 +495,7 @@ geometry_node_categories = [
NodeItem("GeometryNodeAttributeTransfer"),
]),
GeometryNodeCategory("GEO_COLOR", "Color", items=[
+ NodeItem("ShaderNodeRGBCurve"),
NodeItem("ShaderNodeValToRGB"),
NodeItem("ShaderNodeSeparateRGB"),
NodeItem("ShaderNodeCombineRGB"),
@@ -565,6 +558,7 @@ geometry_node_categories = [
NodeItem("GeometryNodeSwitch"),
]),
GeometryNodeCategory("GEO_VECTOR", "Vector", items=[
+ NodeItem("ShaderNodeVectorCurve"),
NodeItem("ShaderNodeSeparateXYZ"),
NodeItem("ShaderNodeCombineXYZ"),
NodeItem("ShaderNodeVectorMath"),
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index 0afdc436415..ba683362e69 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -52,7 +52,7 @@ inline void convert_to_static_type(const CustomDataType data_type, const Func &f
func(bool());
break;
case CD_PROP_COLOR:
- func(Color4f());
+ func(ColorGeometry4f());
break;
default:
BLI_assert_unreachable();
@@ -78,8 +78,8 @@ inline void convert_to_static_type(const fn::CPPType &cpp_type, const Func &func
else if (cpp_type.is<bool>()) {
func(bool());
}
- else if (cpp_type.is<Color4f>()) {
- func(Color4f());
+ else if (cpp_type.is<ColorGeometry4f>()) {
+ func(ColorGeometry4f());
}
else {
BLI_assert_unreachable();
@@ -123,9 +123,12 @@ inline float3 mix3(const float3 &weights, const float3 &v0, const float3 &v1, co
}
template<>
-inline Color4f mix3(const float3 &weights, const Color4f &v0, const Color4f &v1, const Color4f &v2)
+inline ColorGeometry4f mix3(const float3 &weights,
+ const ColorGeometry4f &v0,
+ const ColorGeometry4f &v1,
+ const ColorGeometry4f &v2)
{
- Color4f result;
+ ColorGeometry4f result;
interp_v4_v4v4v4(result, v0, v1, v2, weights);
return result;
}
@@ -165,9 +168,10 @@ template<> inline float3 mix2(const float factor, const float3 &a, const float3
return float3::interpolate(a, b, factor);
}
-template<> inline Color4f mix2(const float factor, const Color4f &a, const Color4f &b)
+template<>
+inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b)
{
- Color4f result;
+ ColorGeometry4f result;
interp_v4_v4v4(result, a, b, factor);
return result;
}
@@ -274,15 +278,16 @@ class SimpleMixerWithAccumulationType {
}
};
-class Color4fMixer {
+class ColorGeometryMixer {
private:
- MutableSpan<Color4f> buffer_;
- Color4f default_color_;
+ MutableSpan<ColorGeometry4f> buffer_;
+ ColorGeometry4f default_color_;
Array<float> total_weights_;
public:
- Color4fMixer(MutableSpan<Color4f> buffer, Color4f default_color = {0, 0, 0, 1});
- void mix_in(const int64_t index, const Color4f &color, const float weight = 1.0f);
+ ColorGeometryMixer(MutableSpan<ColorGeometry4f> buffer,
+ ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f));
+ void mix_in(const int64_t index, const ColorGeometry4f &color, const float weight = 1.0f);
void finalize();
};
@@ -299,10 +304,10 @@ template<> struct DefaultMixerStruct<float2> {
template<> struct DefaultMixerStruct<float3> {
using type = SimpleMixer<float3>;
};
-template<> struct DefaultMixerStruct<Color4f> {
- /* Use a special mixer for colors. Color4f can't be added/multiplied, because this is not
+template<> struct DefaultMixerStruct<ColorGeometry4f> {
+ /* Use a special mixer for colors. ColorGeometry4f can't be added/multiplied, because this is not
* something one should usually do with colors. */
- using type = Color4fMixer;
+ using type = ColorGeometryMixer;
};
template<> struct DefaultMixerStruct<int> {
static int double_to_int(const double &value)
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 6bebf74824d..448f4ae48ad 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -325,7 +325,7 @@ typedef struct bNodeType {
/* Execute a geometry node. */
NodeGeometryExecFunction geometry_node_execute;
- bool geometry_node_execute_supports_lazyness;
+ bool geometry_node_execute_supports_laziness;
/* RNA integration */
ExtensionRNA rna_ext;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index f67c2cb4372..4ea71922df5 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2882,7 +2882,7 @@ bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden
if (bb_custom) {
float mat[4][4], smat[4][4];
scale_m4_fl(smat, PCHAN_CUSTOM_BONE_LENGTH(pchan));
- mul_m4_v3(smat, pchan->custom_scale_xyz);
+ rescale_m4(smat, pchan->custom_scale_xyz);
mul_m4_series(mat, ob->obmat, pchan_tx->pose_mat, smat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 62833e10438..d36e9ed3e86 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -61,7 +61,7 @@ const blender::fn::CPPType *custom_data_type_to_cpp_type(const CustomDataType ty
case CD_PROP_INT32:
return &CPPType::get<int>();
case CD_PROP_COLOR:
- return &CPPType::get<Color4f>();
+ return &CPPType::get<ColorGeometry4f>();
case CD_PROP_BOOL:
return &CPPType::get<bool>();
default:
@@ -84,7 +84,7 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type)
if (type.is<int>()) {
return CD_PROP_INT32;
}
- if (type.is<Color4f>()) {
+ if (type.is<ColorGeometry4f>()) {
return CD_PROP_COLOR;
}
if (type.is<bool>()) {
@@ -355,7 +355,7 @@ ReadAttributeLookup CustomDataAttributeProvider::try_get_for_read(
case CD_PROP_INT32:
return this->layer_to_read_attribute<int>(layer, domain_size);
case CD_PROP_COLOR:
- return this->layer_to_read_attribute<Color4f>(layer, domain_size);
+ return this->layer_to_read_attribute<ColorGeometry4f>(layer, domain_size);
case CD_PROP_BOOL:
return this->layer_to_read_attribute<bool>(layer, domain_size);
default:
@@ -389,7 +389,7 @@ WriteAttributeLookup CustomDataAttributeProvider::try_get_for_write(
case CD_PROP_INT32:
return this->layer_to_write_attribute<int>(layer, domain_size);
case CD_PROP_COLOR:
- return this->layer_to_write_attribute<Color4f>(layer, domain_size);
+ return this->layer_to_write_attribute<ColorGeometry4f>(layer, domain_size);
case CD_PROP_BOOL:
return this->layer_to_write_attribute<bool>(layer, domain_size);
default:
diff --git a/source/blender/blenkernel/intern/attribute_math.cc b/source/blender/blenkernel/intern/attribute_math.cc
index 4ff3a6ceff5..5cdf329effb 100644
--- a/source/blender/blenkernel/intern/attribute_math.cc
+++ b/source/blender/blenkernel/intern/attribute_math.cc
@@ -18,18 +18,21 @@
namespace blender::attribute_math {
-Color4fMixer::Color4fMixer(MutableSpan<Color4f> output_buffer, Color4f default_color)
+ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffer,
+ ColorGeometry4f default_color)
: buffer_(output_buffer),
default_color_(default_color),
total_weights_(output_buffer.size(), 0.0f)
{
- buffer_.fill(Color4f(0, 0, 0, 0));
+ buffer_.fill(ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
}
-void Color4fMixer::mix_in(const int64_t index, const Color4f &color, const float weight)
+void ColorGeometryMixer::mix_in(const int64_t index,
+ const ColorGeometry4f &color,
+ const float weight)
{
BLI_assert(weight >= 0.0f);
- Color4f &output_color = buffer_[index];
+ ColorGeometry4f &output_color = buffer_[index];
output_color.r += color.r * weight;
output_color.g += color.g * weight;
output_color.b += color.b * weight;
@@ -37,11 +40,11 @@ void Color4fMixer::mix_in(const int64_t index, const Color4f &color, const float
total_weights_[index] += weight;
}
-void Color4fMixer::finalize()
+void ColorGeometryMixer::finalize()
{
for (const int64_t i : buffer_.index_range()) {
const float weight = total_weights_[i];
- Color4f &output_color = buffer_[i];
+ ColorGeometry4f &output_color = buffer_[i];
if (weight > 0.0f) {
const float weight_inv = 1.0f / weight;
output_color.r *= weight_inv;
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 851d8aae378..493a267c2f0 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -623,7 +623,8 @@ static void clamp_bounds_in_domain(FluidDomainSettings *fds,
static bool is_static_object(Object *ob)
{
/* Check if the object has modifiers that might make the object "dynamic". */
- ModifierData *md = ob->modifiers.first;
+ VirtualModifierData virtualModifierData;
+ ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
for (; md; md = md->next) {
if (ELEM(md->type,
eModifierType_Cloth,
@@ -631,7 +632,8 @@ static bool is_static_object(Object *ob)
eModifierType_Explode,
eModifierType_Ocean,
eModifierType_ShapeKey,
- eModifierType_Softbody)) {
+ eModifierType_Softbody,
+ eModifierType_Nodes)) {
return false;
}
}
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index 2ecd0e6bd85..42f3a854aec 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -219,8 +219,7 @@ static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_corner_to_point(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
/* We compute all interpolated values at once, because for this interpolation, one has to
@@ -249,8 +248,7 @@ static void adapt_mesh_domain_point_to_corner_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_point_to_corner(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
/* It is not strictly necessary to compute the value for all corners here. Instead one could
* lazily lookup the mesh topology when a specific index accessed. This can be more efficient
@@ -290,8 +288,7 @@ static void adapt_mesh_domain_corner_to_face_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_corner_to_face(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totpoly);
@@ -329,8 +326,7 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_corner_to_edge(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totedge);
@@ -365,8 +361,7 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_face_to_point(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totvert);
@@ -394,8 +389,7 @@ void adapt_mesh_domain_face_to_corner_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_face_to_corner(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totloop);
@@ -428,8 +422,7 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_face_to_edge(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totedge);
@@ -467,8 +460,7 @@ static void adapt_mesh_domain_point_to_face_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_point_to_face(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totpoly);
@@ -504,8 +496,7 @@ static void adapt_mesh_domain_point_to_edge_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_point_to_edge(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totedge);
@@ -543,8 +534,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_edge_to_corner(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totloop);
@@ -576,8 +566,7 @@ static void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_edge_to_point(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totvert);
@@ -615,8 +604,7 @@ static void adapt_mesh_domain_edge_to_face_impl(const Mesh &mesh,
static GVArrayPtr adapt_mesh_domain_edge_to_face(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
- const CustomDataType data_type = cpp_type_to_custom_data_type(varray->type());
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
Array<T> values(mesh.totpoly);
@@ -785,18 +773,20 @@ static void set_loop_uv(MLoopUV &uv, float2 co)
copy_v2_v2(uv.uv, co);
}
-static Color4f get_loop_color(const MLoopCol &col)
+static ColorGeometry4f get_loop_color(const MLoopCol &col)
{
- Color4f srgb_color;
- rgba_uchar_to_float(srgb_color, &col.r);
- Color4f linear_color;
- srgb_to_linearrgb_v4(linear_color, srgb_color);
+ ColorGeometry4b encoded_color = ColorGeometry4b(col.r, col.g, col.b, col.a);
+ ColorGeometry4f linear_color = encoded_color.decode();
return linear_color;
}
-static void set_loop_color(MLoopCol &col, Color4f linear_color)
+static void set_loop_color(MLoopCol &col, ColorGeometry4f linear_color)
{
- linearrgb_to_srgb_uchar4(&col.r, linear_color);
+ ColorGeometry4b encoded_color = linear_color.encode();
+ col.r = encoded_color.r;
+ col.g = encoded_color.g;
+ col.b = encoded_color.b;
+ col.a = encoded_color.a;
}
static float get_crease(const MEdge &edge)
@@ -1133,8 +1123,8 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_COLOR,
CD_MLOOPCOL,
corner_access,
- make_derived_read_attribute<MLoopCol, Color4f, get_loop_color>,
- make_derived_write_attribute<MLoopCol, Color4f, get_loop_color, set_loop_color>);
+ make_derived_read_attribute<MLoopCol, ColorGeometry4f, get_loop_color>,
+ make_derived_write_attribute<MLoopCol, ColorGeometry4f, get_loop_color, set_loop_color>);
static VertexGroupsAttributeProvider vertex_groups;
static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access);
diff --git a/source/blender/blenkernel/intern/lib_id_test.cc b/source/blender/blenkernel/intern/lib_id_test.cc
index 9bfd19ae4d6..fbe4a15da1c 100644
--- a/source/blender/blenkernel/intern/lib_id_test.cc
+++ b/source/blender/blenkernel/intern/lib_id_test.cc
@@ -37,6 +37,7 @@ struct LibIDMainSortTestContext {
static void test_lib_id_main_sort_init(LibIDMainSortTestContext *ctx)
{
+ BKE_idtype_init();
ctx->bmain = BKE_main_new();
}
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 643dc58af18..3377f5c69dc 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -513,7 +513,7 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
if (node->storage) {
/* could be handlerized at some point, now only 1 exception still */
- if ((ntree->type == NTREE_SHADER) &&
+ if ((ELEM(ntree->type, NTREE_SHADER, NTREE_GEOMETRY)) &&
ELEM(node->type, SH_NODE_CURVE_VEC, SH_NODE_CURVE_RGB)) {
BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 034af924ab1..e4cfe64df11 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2369,7 +2369,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f
BLI_listbase_clear(&psysn->pathcachebufs);
BLI_listbase_clear(&psysn->childcachebufs);
- if (flag & LIB_ID_CREATE_NO_MAIN) {
+ if (flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) {
/* XXX Disabled, fails when evaluating depsgraph after copying ID with no main for preview
* creation. */
// BLI_assert((psys->flag & PSYS_SHARED_CACHES) == 0);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index ae685357151..a873ecec6f1 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -101,6 +101,8 @@ static void particle_settings_init(ID *id)
MEMCPY_STRUCT_AFTER(particle_settings, DNA_struct_default_get(ParticleSettings), id);
particle_settings->effector_weights = BKE_effector_add_weights(NULL);
+ particle_settings->pd = BKE_partdeflect_new(PFIELD_NULL);
+ particle_settings->pd2 = BKE_partdeflect_new(PFIELD_NULL);
}
static void particle_settings_copy_data(Main *UNUSED(bmain),
diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh
index e57a5109a66..287587e04be 100644
--- a/source/blender/blenlib/BLI_color.hh
+++ b/source/blender/blenlib/BLI_color.hh
@@ -22,41 +22,122 @@
namespace blender {
-struct Color4f {
- float r, g, b, a;
+/**
+ * CPP based color structures.
+ *
+ * Strongly typed color storage structures with space and alpha association.
+ * Will increase readability and visibility of typical mistakes when
+ * working with colors.
+ *
+ * The storage structs can hold 4 channels (r, g, b and a).
+ *
+ * Usage:
+ *
+ * Convert a theme byte color to a linearrgb premultiplied.
+ * ```
+ * ColorTheme4b theme_color;
+ * ColorSceneLinear4f<eAlpha::Premultiplied> linearrgb_color =
+ * BLI_color_convert_to_scene_linear(theme_color).premultiply_alpha();
+ * ```
+ *
+ * The API is structured to make most use of inlining. Most notable are space
+ * conversions done via `BLI_color_convert_to*` functions.
+ *
+ * - Conversions between spaces (theme <=> scene linear) should always be done by
+ * invoking the `BLI_color_convert_to*` methods.
+ * - Encoding colors (compressing to store colors inside a less precision storage)
+ * should be done by invoking the `encode` and `decode` methods.
+ * - Changing alpha association should be done by invoking `premultiply_alpha` or
+ * `unpremultiply_alpha` methods.
+ *
+ * # Encoding.
+ *
+ * Color encoding is used to store colors with less precision as in using `uint8_t` in
+ * stead of `float`. This encoding is supported for `eSpace::SceneLinear`.
+ * To make this clear to the developer the `eSpace::SceneLinearByteEncoded`
+ * space is added.
+ *
+ * # Precision
+ *
+ * Colors can be stored using `uint8_t` or `float` colors. The conversion
+ * between the two precisions are available as methods. (`to_4b` and
+ * `to_4f`).
+ *
+ * # Alpha conversion
+ *
+ * Alpha conversion is only supported in SceneLinear space.
+ *
+ * Extending this file:
+ * - This file can be extended with `ColorHex/Hsl/Hsv` for different representations
+ * of rgb based colors. `ColorHsl4f<eSpace::SceneLinear, eAlpha::Premultiplied>`
+ * - Add non RGB spaces/storages ColorXyz.
+ */
+
+/* Enumeration containing the different alpha modes. */
+enum class eAlpha {
+ /* Color and alpha are unassociated. */
+ Straight,
+ /* Color and alpha are associated. */
+ Premultiplied,
+};
+std::ostream &operator<<(std::ostream &stream, const eAlpha &space);
- Color4f() = default;
+/* Enumeration containing internal spaces. */
+enum class eSpace {
+ /* Blender theme color space (sRGB). */
+ Theme,
+ /* Blender internal scene linear color space (maps to SceneReference role in OCIO). */
+ SceneLinear,
+ /* Blender internal scene linear color space compressed to be stored in 4 uint8_t. */
+ SceneLinearByteEncoded,
+};
+std::ostream &operator<<(std::ostream &stream, const eSpace &space);
- Color4f(const float *rgba) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3])
+/* Template class to store RGBA values with different precision, space and alpha association. */
+template<typename ChannelStorageType, eSpace Space, eAlpha Alpha> class ColorRGBA {
+ public:
+ ChannelStorageType r, g, b, a;
+ constexpr ColorRGBA() = default;
+
+ constexpr ColorRGBA(const ChannelStorageType rgba[4])
+ : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3])
{
}
- Color4f(float r, float g, float b, float a) : r(r), g(g), b(b), a(a)
+ constexpr ColorRGBA(const ChannelStorageType r,
+ const ChannelStorageType g,
+ const ChannelStorageType b,
+ const ChannelStorageType a)
+ : r(r), g(g), b(b), a(a)
{
}
- operator float *()
+ operator ChannelStorageType *()
{
return &r;
}
- operator const float *() const
+ operator const ChannelStorageType *() const
{
return &r;
}
- friend std::ostream &operator<<(std::ostream &stream, Color4f c)
+ friend std::ostream &operator<<(std::ostream &stream,
+ const ColorRGBA<ChannelStorageType, Space, Alpha> &c)
{
- stream << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
+
+ stream << Space << Alpha << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
return stream;
}
- friend bool operator==(const Color4f &a, const Color4f &b)
+ friend bool operator==(const ColorRGBA<ChannelStorageType, Space, Alpha> &a,
+ const ColorRGBA<ChannelStorageType, Space, Alpha> &b)
{
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
}
- friend bool operator!=(const Color4f &a, const Color4f &b)
+ friend bool operator!=(const ColorRGBA<ChannelStorageType, Space, Alpha> &a,
+ const ColorRGBA<ChannelStorageType, Space, Alpha> &b)
{
return !(a == b);
}
@@ -71,58 +152,209 @@ struct Color4f {
}
};
-struct Color4b {
- uint8_t r, g, b, a;
+/* Forward declarations of concrete color classes. */
+template<eAlpha Alpha> class ColorSceneLinear4f;
+template<eAlpha Alpha> class ColorSceneLinearByteEncoded4b;
+template<typename ChannelStorageType> class ColorTheme4;
- Color4b() = default;
+/* Forward declation of precision conversion methods. */
+BLI_INLINE ColorTheme4<float> BLI_color_convert_to_theme4f(const ColorTheme4<uint8_t> &srgb4b);
+BLI_INLINE ColorTheme4<uint8_t> BLI_color_convert_to_theme4b(const ColorTheme4<float> &srgb4f);
- Color4b(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a)
+template<eAlpha Alpha>
+class ColorSceneLinear4f final : public ColorRGBA<float, eSpace::SceneLinear, Alpha> {
+ public:
+ constexpr ColorSceneLinear4f<Alpha>() : ColorRGBA<float, eSpace::SceneLinear, Alpha>()
{
}
- Color4b(Color4f other)
+ constexpr ColorSceneLinear4f<Alpha>(const float *rgba)
+ : ColorRGBA<float, eSpace::SceneLinear, Alpha>(rgba)
{
- rgba_float_to_uchar(*this, other);
}
- operator Color4f() const
+ constexpr ColorSceneLinear4f<Alpha>(float r, float g, float b, float a)
+ : ColorRGBA<float, eSpace::SceneLinear, Alpha>(r, g, b, a)
{
- Color4f result;
- rgba_uchar_to_float(result, *this);
- return result;
}
- operator uint8_t *()
+ /**
+ * Convert to its byte encoded counter space.
+ **/
+ ColorSceneLinearByteEncoded4b<Alpha> encode() const
{
- return &r;
+ ColorSceneLinearByteEncoded4b<Alpha> encoded;
+ linearrgb_to_srgb_uchar4(encoded, *this);
+ return encoded;
}
- operator const uint8_t *() const
+ /**
+ * Convert color and alpha association to premultiplied alpha.
+ *
+ * Does nothing when color has already a premultiplied alpha.
+ */
+ ColorSceneLinear4f<eAlpha::Premultiplied> premultiply_alpha() const
{
- return &r;
+ if constexpr (Alpha == eAlpha::Straight) {
+ ColorSceneLinear4f<eAlpha::Premultiplied> premultiplied;
+ straight_to_premul_v4_v4(premultiplied, *this);
+ return premultiplied;
+ }
+ else {
+ return *this;
+ }
}
- friend std::ostream &operator<<(std::ostream &stream, Color4b c)
+ /**
+ * Convert color and alpha association to straight alpha.
+ *
+ * Does nothing when color has straighten alpha.
+ */
+ ColorSceneLinear4f<eAlpha::Straight> unpremultiply_alpha() const
{
- stream << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
- return stream;
+ if constexpr (Alpha == eAlpha::Premultiplied) {
+ ColorSceneLinear4f<eAlpha::Straight> straighten;
+ premul_to_straight_v4_v4(straighten, *this);
+ return straighten;
+ }
+ else {
+ return *this;
+ }
}
+};
- friend bool operator==(const Color4b &a, const Color4b &b)
+template<eAlpha Alpha>
+class ColorSceneLinearByteEncoded4b final
+ : public ColorRGBA<uint8_t, eSpace::SceneLinearByteEncoded, Alpha> {
+ public:
+ constexpr ColorSceneLinearByteEncoded4b() = default;
+
+ constexpr ColorSceneLinearByteEncoded4b(const uint8_t *rgba)
+ : ColorRGBA<uint8_t, eSpace::SceneLinearByteEncoded, Alpha>(rgba)
{
- return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
}
- friend bool operator!=(const Color4b &a, const Color4b &b)
+ constexpr ColorSceneLinearByteEncoded4b(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+ : ColorRGBA<uint8_t, eSpace::SceneLinearByteEncoded, Alpha>(r, g, b, a)
{
- return !(a == b);
}
- uint64_t hash() const
+ /**
+ * Convert to back to float color.
+ */
+ ColorSceneLinear4f<Alpha> decode() const
+ {
+ ColorSceneLinear4f<Alpha> decoded;
+ srgb_to_linearrgb_uchar4(decoded, *this);
+ return decoded;
+ }
+};
+
+/**
+ * Theme color template class.
+ *
+ * Don't use directly, but use `ColorTheme4b/ColorTheme4b`.
+ *
+ * This has been implemented as a template to improve inlining. When implemented as concrete
+ * classes (ColorTheme4b/f) the functions would be hidden in a compile unit what wouldn't be
+ * inlined.
+ */
+template<typename ChannelStorageType>
+class ColorTheme4 final : public ColorRGBA<ChannelStorageType, eSpace::Theme, eAlpha::Straight> {
+ public:
+ constexpr ColorTheme4() : ColorRGBA<ChannelStorageType, eSpace::Theme, eAlpha::Straight>(){};
+
+ constexpr ColorTheme4(const ChannelStorageType *rgba)
+ : ColorRGBA<ChannelStorageType, eSpace::Theme, eAlpha::Straight>(rgba)
+ {
+ }
+
+ constexpr ColorTheme4(ChannelStorageType r,
+ ChannelStorageType g,
+ ChannelStorageType b,
+ ChannelStorageType a)
+ : ColorRGBA<ChannelStorageType, eSpace::Theme, eAlpha::Straight>(r, g, b, a)
+ {
+ }
+
+ /**
+ * Change precision of color to float.
+ */
+ ColorTheme4<float> to_4f() const
{
- return static_cast<uint64_t>(r * 1283591) ^ static_cast<uint64_t>(g * 850177) ^
- static_cast<uint64_t>(b * 735391) ^ static_cast<uint64_t>(a * 442319);
+ if constexpr ((std::is_same_v<ChannelStorageType, uint8_t>)) {
+ return BLI_color_convert_to_theme4f(*this);
+ }
+ else {
+ return *this;
+ }
+ }
+
+ /**
+ * Change precision of color to uint8_t.
+ */
+ ColorTheme4<uint8_t> to_4b() const
+ {
+ if constexpr ((std::is_same_v<ChannelStorageType, float>)) {
+ return BLI_color_convert_to_theme4b(*this);
+ }
+ else {
+ return *this;
+ }
}
};
+using ColorTheme4b = ColorTheme4<uint8_t>;
+using ColorTheme4f = ColorTheme4<float>;
+
+BLI_INLINE ColorTheme4b BLI_color_convert_to_theme4b(const ColorTheme4f &theme4f)
+{
+ ColorTheme4b theme4b;
+ rgba_float_to_uchar(theme4b, theme4f);
+ return theme4b;
+}
+
+BLI_INLINE ColorTheme4f BLI_color_convert_to_theme4f(const ColorTheme4b &theme4b)
+{
+ ColorTheme4f theme4f;
+ rgba_uchar_to_float(theme4f, theme4b);
+ return theme4f;
+}
+
+BLI_INLINE ColorSceneLinear4f<eAlpha::Straight> BLI_color_convert_to_scene_linear(
+ const ColorTheme4f &theme4f)
+{
+ ColorSceneLinear4f<eAlpha::Straight> scene_linear;
+ srgb_to_linearrgb_v4(scene_linear, theme4f);
+ return scene_linear;
+}
+
+BLI_INLINE ColorSceneLinear4f<eAlpha::Straight> BLI_color_convert_to_scene_linear(
+ const ColorTheme4b &theme4b)
+{
+ ColorSceneLinear4f<eAlpha::Straight> scene_linear;
+ srgb_to_linearrgb_uchar4(scene_linear, theme4b);
+ return scene_linear;
+}
+
+BLI_INLINE ColorTheme4f
+BLI_color_convert_to_theme4f(const ColorSceneLinear4f<eAlpha::Straight> &scene_linear)
+{
+ ColorTheme4f theme4f;
+ linearrgb_to_srgb_v4(theme4f, scene_linear);
+ return theme4f;
+}
+
+BLI_INLINE ColorTheme4b
+BLI_color_convert_to_theme4b(const ColorSceneLinear4f<eAlpha::Straight> &scene_linear)
+{
+ ColorTheme4b theme4b;
+ linearrgb_to_srgb_uchar4(theme4b, scene_linear);
+ return theme4b;
+}
+
+/* Internal roles. For convenience to shorten the type names and hide complexity. */
+using ColorGeometry4f = ColorSceneLinear4f<eAlpha::Premultiplied>;
+using ColorGeometry4b = ColorSceneLinearByteEncoded4b<eAlpha::Premultiplied>;
+
} // namespace blender
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index ce3515ac153..f3dc343ee20 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -39,6 +39,7 @@ set(SRC
intern/BLI_args.c
intern/BLI_array.c
intern/BLI_assert.c
+ intern/BLI_color.cc
intern/BLI_dial_2d.c
intern/BLI_dynstr.c
intern/BLI_filelist.c
@@ -389,6 +390,7 @@ if(WITH_GTESTS)
tests/BLI_array_store_test.cc
tests/BLI_array_test.cc
tests/BLI_array_utils_test.cc
+ tests/BLI_color_test.cc
tests/BLI_delaunay_2d_test.cc
tests/BLI_disjoint_set_test.cc
tests/BLI_edgehash_test.cc
diff --git a/source/blender/blenlib/intern/BLI_color.cc b/source/blender/blenlib/intern/BLI_color.cc
new file mode 100644
index 00000000000..6dcef4f4688
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_color.cc
@@ -0,0 +1,55 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_color.hh"
+
+namespace blender {
+
+std::ostream &operator<<(std::ostream &stream, const eAlpha &space)
+{
+ switch (space) {
+ case eAlpha::Straight: {
+ stream << "Straight";
+ break;
+ }
+ case eAlpha::Premultiplied: {
+ stream << "Premultiplied";
+ break;
+ }
+ }
+ return stream;
+}
+
+std::ostream &operator<<(std::ostream &stream, const eSpace &space)
+{
+ switch (space) {
+ case eSpace::Theme: {
+ stream << "Theme";
+ break;
+ }
+ case eSpace::SceneLinear: {
+ stream << "SceneLinear";
+ break;
+ }
+ case eSpace::SceneLinearByteEncoded: {
+ stream << "SceneLinearByteEncoded";
+ break;
+ }
+ }
+ return stream;
+}
+
+} // namespace blender
diff --git a/source/blender/blenlib/tests/BLI_color_test.cc b/source/blender/blenlib/tests/BLI_color_test.cc
new file mode 100644
index 00000000000..14796e6bf71
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_color_test.cc
@@ -0,0 +1,133 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "BLI_color.hh"
+
+namespace blender::tests {
+
+/**
+ * \name Conversions
+ * \{ */
+
+TEST(color, ThemeByteToFloat)
+{
+ ColorTheme4b theme_byte(192, 128, 64, 128);
+ ColorTheme4f theme_float = theme_byte.to_4f();
+ EXPECT_NEAR(0.75f, theme_float.r, 0.01f);
+ EXPECT_NEAR(0.5f, theme_float.g, 0.01f);
+ EXPECT_NEAR(0.25f, theme_float.b, 0.01f);
+ EXPECT_NEAR(0.5f, theme_float.a, 0.01f);
+}
+
+TEST(color, SrgbStraightFloatToByte)
+{
+ ColorTheme4f theme_float(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorTheme4b theme_byte = theme_float.to_4b();
+ EXPECT_EQ(191, theme_byte.r);
+ EXPECT_EQ(128, theme_byte.g);
+ EXPECT_EQ(64, theme_byte.b);
+ EXPECT_EQ(128, theme_byte.a);
+}
+
+TEST(color, SrgbStraightToSceneLinearPremultiplied)
+{
+ BLI_init_srgb_conversion();
+
+ ColorTheme4b theme(192, 128, 64, 128);
+ ColorSceneLinear4f<eAlpha::Premultiplied> linear =
+ BLI_color_convert_to_scene_linear(theme).premultiply_alpha();
+ EXPECT_NEAR(0.26f, linear.r, 0.01f);
+ EXPECT_NEAR(0.11f, linear.g, 0.01f);
+ EXPECT_NEAR(0.02f, linear.b, 0.01f);
+ EXPECT_NEAR(0.5f, linear.a, 0.01f);
+}
+
+TEST(color, SceneLinearStraightToPremultiplied)
+{
+ ColorSceneLinear4f<eAlpha::Straight> straight(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorSceneLinear4f<eAlpha::Premultiplied> premultiplied = straight.premultiply_alpha();
+ EXPECT_NEAR(0.37f, premultiplied.r, 0.01f);
+ EXPECT_NEAR(0.25f, premultiplied.g, 0.01f);
+ EXPECT_NEAR(0.12f, premultiplied.b, 0.01f);
+ EXPECT_NEAR(0.5f, premultiplied.a, 0.01f);
+}
+
+TEST(color, SceneLinearPremultipliedToStraight)
+{
+ ColorSceneLinear4f<eAlpha::Premultiplied> premultiplied(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorSceneLinear4f<eAlpha::Straight> straight = premultiplied.unpremultiply_alpha();
+ EXPECT_NEAR(1.5f, straight.r, 0.01f);
+ EXPECT_NEAR(1.0f, straight.g, 0.01f);
+ EXPECT_NEAR(0.5f, straight.b, 0.01f);
+ EXPECT_NEAR(0.5f, straight.a, 0.01f);
+}
+
+TEST(color, SceneLinearStraightSrgbFloat)
+{
+ BLI_init_srgb_conversion();
+ ColorSceneLinear4f<eAlpha::Straight> linear(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorTheme4f theme = BLI_color_convert_to_theme4f(linear);
+ EXPECT_NEAR(0.88f, theme.r, 0.01);
+ EXPECT_NEAR(0.73f, theme.g, 0.01);
+ EXPECT_NEAR(0.53f, theme.b, 0.01);
+ EXPECT_NEAR(0.5f, theme.a, 0.01);
+}
+
+TEST(color, SceneLinearPremultipliedToSrgbFloat)
+{
+ BLI_init_srgb_conversion();
+ ColorSceneLinear4f<eAlpha::Premultiplied> linear(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorTheme4f theme = BLI_color_convert_to_theme4f(linear.unpremultiply_alpha());
+
+ EXPECT_NEAR(1.19f, theme.r, 0.01);
+ EXPECT_NEAR(1.0f, theme.g, 0.01);
+ EXPECT_NEAR(0.74f, theme.b, 0.01);
+ EXPECT_NEAR(0.5f, theme.a, 0.01);
+}
+
+TEST(color, SceneLinearStraightSrgbByte)
+{
+ BLI_init_srgb_conversion();
+ ColorSceneLinear4f<eAlpha::Straight> linear(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorTheme4b theme = BLI_color_convert_to_theme4b(linear);
+ EXPECT_EQ(225, theme.r);
+ EXPECT_EQ(188, theme.g);
+ EXPECT_EQ(137, theme.b);
+ EXPECT_EQ(128, theme.a);
+}
+
+TEST(color, SceneLinearPremultipliedToSrgbByte)
+{
+ BLI_init_srgb_conversion();
+ ColorSceneLinear4f<eAlpha::Premultiplied> linear(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorTheme4b theme = BLI_color_convert_to_theme4b(linear.unpremultiply_alpha());
+ EXPECT_EQ(255, theme.r);
+ EXPECT_EQ(255, theme.g);
+ EXPECT_EQ(188, theme.b);
+ EXPECT_EQ(128, theme.a);
+}
+
+TEST(color, SceneLinearByteEncoding)
+{
+ ColorSceneLinear4f<eAlpha::Premultiplied> linear(0.75f, 0.5f, 0.25f, 0.5f);
+ ColorSceneLinearByteEncoded4b<eAlpha::Premultiplied> encoded = linear.encode();
+ EXPECT_EQ(225, encoded.r);
+ EXPECT_EQ(188, encoded.g);
+ EXPECT_EQ(137, encoded.b);
+ EXPECT_EQ(128, encoded.a);
+}
+
+TEST(color, SceneLinearByteDecoding)
+{
+ ColorSceneLinearByteEncoded4b<eAlpha::Premultiplied> encoded(225, 188, 137, 128);
+ ColorSceneLinear4f<eAlpha::Premultiplied> decoded = encoded.decode();
+ EXPECT_NEAR(0.75f, decoded.r, 0.01f);
+ EXPECT_NEAR(0.5f, decoded.g, 0.01f);
+ EXPECT_NEAR(0.25f, decoded.b, 0.01f);
+ EXPECT_NEAR(0.5f, decoded.a, 0.01f);
+}
+
+/* \} */
+
+} // namespace blender::tests
diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cc b/source/blender/compositor/operations/COM_ConvertOperation.cc
index 2ea15185c0f..384936533c7 100644
--- a/source/blender/compositor/operations/COM_ConvertOperation.cc
+++ b/source/blender/compositor/operations/COM_ConvertOperation.cc
@@ -18,6 +18,8 @@
#include "COM_ConvertOperation.h"
+#include "BLI_color.hh"
+
#include "IMB_colormanagement.h"
namespace blender::compositor {
@@ -355,21 +357,10 @@ void ConvertPremulToStraightOperation::executePixelSampled(float output[4],
float y,
PixelSampler sampler)
{
- float inputValue[4];
- float alpha;
-
- this->m_inputOperation->readSampled(inputValue, x, y, sampler);
- alpha = inputValue[3];
-
- if (fabsf(alpha) < 1e-5f) {
- zero_v3(output);
- }
- else {
- mul_v3_v3fl(output, inputValue, 1.0f / alpha);
- }
-
- /* never touches the alpha */
- output[3] = alpha;
+ ColorSceneLinear4f<eAlpha::Premultiplied> input;
+ this->m_inputOperation->readSampled(input, x, y, sampler);
+ ColorSceneLinear4f<eAlpha::Straight> converted = input.unpremultiply_alpha();
+ copy_v4_v4(output, converted);
}
/* ******** Straight to Premul ******** */
@@ -385,16 +376,10 @@ void ConvertStraightToPremulOperation::executePixelSampled(float output[4],
float y,
PixelSampler sampler)
{
- float inputValue[4];
- float alpha;
-
- this->m_inputOperation->readSampled(inputValue, x, y, sampler);
- alpha = inputValue[3];
-
- mul_v3_v3fl(output, inputValue, alpha);
-
- /* never touches the alpha */
- output[3] = alpha;
+ ColorSceneLinear4f<eAlpha::Straight> input;
+ this->m_inputOperation->readSampled(input, x, y, sampler);
+ ColorSceneLinear4f<eAlpha::Premultiplied> converted = input.premultiply_alpha();
+ copy_v4_v4(output, converted);
}
/* ******** Separate Channels ******** */
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
index 46ae00dee34..4edcc206f5b 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
@@ -31,6 +31,31 @@
namespace blender::compositor {
+PlaneDistortBaseOperation::PlaneDistortBaseOperation()
+ : m_motion_blur_samples(1), m_motion_blur_shutter(0.5f)
+{
+}
+
+void PlaneDistortBaseOperation::calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample)
+{
+ BLI_assert(sample < this->m_motion_blur_samples);
+ MotionSample *sample_data = &this->m_samples[sample];
+ if (normalized) {
+ for (int i = 0; i < 4; i++) {
+ sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ }
+ }
+ else {
+ for (int i = 0; i < 4; i++) {
+ sample_data->frameSpaceCorners[i][0] = corners[i][0];
+ sample_data->frameSpaceCorners[i][1] = corners[i][1];
+ }
+ }
+}
+
/* ******** PlaneDistort WarpImage ******** */
BLI_INLINE void warpCoord(float x, float y, float matrix[3][3], float uv[2], float deriv[2][2])
@@ -46,13 +71,11 @@ BLI_INLINE void warpCoord(float x, float y, float matrix[3][3], float uv[2], flo
deriv[1][1] = (matrix[1][1] - matrix[1][2] * uv[1]) / vec[2];
}
-PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation()
+PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() : PlaneDistortBaseOperation()
{
this->addInputSocket(DataType::Color, ResizeMode::None);
this->addOutputSocket(DataType::Color);
this->m_pixelReader = nullptr;
- this->m_motion_blur_samples = 1;
- this->m_motion_blur_shutter = 0.5f;
this->flags.complex = true;
}
@@ -60,24 +83,13 @@ void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2],
bool normalized,
int sample)
{
- BLI_assert(sample < this->m_motion_blur_samples);
+ PlaneDistortBaseOperation::calculateCorners(corners, normalized, sample);
+
const int width = this->m_pixelReader->getWidth();
const int height = this->m_pixelReader->getHeight();
float frame_corners[4][2] = {
{0.0f, 0.0f}, {(float)width, 0.0f}, {(float)width, (float)height}, {0.0f, (float)height}};
MotionSample *sample_data = &this->m_samples[sample];
- if (normalized) {
- for (int i = 0; i < 4; i++) {
- sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
- }
- }
- else {
- for (int i = 0; i < 4; i++) {
- sample_data->frameSpaceCorners[i][0] = corners[i][0];
- sample_data->frameSpaceCorners[i][1] = corners[i][1];
- }
- }
BKE_tracking_homography_between_two_quads(
sample_data->frameSpaceCorners, frame_corners, sample_data->perspectiveMatrix);
}
@@ -147,34 +159,12 @@ bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(
/* ******** PlaneDistort Mask ******** */
-PlaneDistortMaskOperation::PlaneDistortMaskOperation()
+PlaneDistortMaskOperation::PlaneDistortMaskOperation() : PlaneDistortBaseOperation()
{
addOutputSocket(DataType::Value);
/* Currently hardcoded to 8 samples. */
m_osa = 8;
- this->m_motion_blur_samples = 1;
- this->m_motion_blur_shutter = 0.5f;
-}
-
-void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2],
- bool normalized,
- int sample)
-{
- BLI_assert(sample < this->m_motion_blur_samples);
- MotionSample *sample_data = &this->m_samples[sample];
- if (normalized) {
- for (int i = 0; i < 4; i++) {
- sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
- }
- }
- else {
- for (int i = 0; i < 4; i++) {
- sample_data->frameSpaceCorners[i][0] = corners[i][0];
- sample_data->frameSpaceCorners[i][1] = corners[i][1];
- }
- }
}
void PlaneDistortMaskOperation::initExecution()
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
index 95e5c86bd4d..cc6e4d00d71 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
@@ -32,21 +32,43 @@ namespace blender::compositor {
#define PLANE_DISTORT_MAX_SAMPLES 64
-class PlaneDistortWarpImageOperation : public NodeOperation {
+class PlaneDistortBaseOperation : public NodeOperation {
protected:
struct MotionSample {
float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
float perspectiveMatrix[3][3];
};
- SocketReader *m_pixelReader;
MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
int m_motion_blur_samples;
float m_motion_blur_shutter;
public:
+ PlaneDistortBaseOperation();
+
+ void setMotionBlurSamples(int samples)
+ {
+ BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
+ this->m_motion_blur_samples = samples;
+ }
+ void setMotionBlurShutter(float shutter)
+ {
+ this->m_motion_blur_shutter = shutter;
+ }
+
+ virtual void calculateCorners(const float corners[4][2], bool normalized, int sample);
+
+ private:
+ friend class PlaneTrackCommon;
+};
+
+class PlaneDistortWarpImageOperation : public PlaneDistortBaseOperation {
+ protected:
+ SocketReader *m_pixelReader;
+
+ public:
PlaneDistortWarpImageOperation();
- void calculateCorners(const float corners[4][2], bool normalized, int sample);
+ void calculateCorners(const float corners[4][2], bool normalized, int sample) override;
void initExecution() override;
void deinitExecution() override;
@@ -56,47 +78,19 @@ class PlaneDistortWarpImageOperation : public NodeOperation {
bool determineDependingAreaOfInterest(rcti *input,
ReadBufferOperation *readOperation,
rcti *output) override;
-
- void setMotionBlurSamples(int samples)
- {
- BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
- this->m_motion_blur_samples = samples;
- }
- void setMotionBlurShutter(float shutter)
- {
- this->m_motion_blur_shutter = shutter;
- }
};
-class PlaneDistortMaskOperation : public NodeOperation {
+class PlaneDistortMaskOperation : public PlaneDistortBaseOperation {
protected:
- struct MotionSample {
- float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
- };
int m_osa;
- MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
float m_jitter[32][2];
- int m_motion_blur_samples;
- float m_motion_blur_shutter;
public:
PlaneDistortMaskOperation();
- void calculateCorners(const float corners[4][2], bool normalized, int sample);
-
void initExecution() override;
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
-
- void setMotionBlurSamples(int samples)
- {
- BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
- this->m_motion_blur_samples = samples;
- }
- void setMotionBlurShutter(float shutter)
- {
- this->m_motion_blur_shutter = shutter;
- }
};
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
index 565bde6c945..0884f2ad979 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
@@ -41,6 +41,26 @@ PlaneTrackCommon::PlaneTrackCommon()
this->m_planeTrackName[0] = '\0';
}
+void PlaneTrackCommon::read_and_calculate_corners(PlaneDistortBaseOperation *distort_op)
+{
+ float corners[4][2];
+ if (distort_op->m_motion_blur_samples == 1) {
+ readCornersFromTrack(corners, this->m_framenumber);
+ distort_op->calculateCorners(corners, true, 0);
+ }
+ else {
+ const float frame = (float)this->m_framenumber - distort_op->m_motion_blur_shutter;
+ const float frame_step = (distort_op->m_motion_blur_shutter * 2.0f) /
+ distort_op->m_motion_blur_samples;
+ float frame_iter = frame;
+ for (int sample = 0; sample < distort_op->m_motion_blur_samples; sample++) {
+ readCornersFromTrack(corners, frame_iter);
+ distort_op->calculateCorners(corners, true, sample);
+ frame_iter += frame_step;
+ }
+ }
+}
+
void PlaneTrackCommon::readCornersFromTrack(float corners[4][2], float frame)
{
MovieTracking *tracking;
@@ -84,21 +104,7 @@ void PlaneTrackCommon::determineResolution(unsigned int resolution[2],
void PlaneTrackMaskOperation::initExecution()
{
PlaneDistortMaskOperation::initExecution();
- float corners[4][2];
- if (this->m_motion_blur_samples == 1) {
- readCornersFromTrack(corners, this->m_framenumber);
- calculateCorners(corners, true, 0);
- }
- else {
- const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
- const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
- float frame_iter = frame;
- for (int sample = 0; sample < this->m_motion_blur_samples; sample++) {
- readCornersFromTrack(corners, frame_iter);
- calculateCorners(corners, true, sample);
- frame_iter += frame_step;
- }
- }
+ PlaneTrackCommon::read_and_calculate_corners(this);
}
/* ******** PlaneTrackWarpImageOperation ******** */
@@ -106,22 +112,7 @@ void PlaneTrackMaskOperation::initExecution()
void PlaneTrackWarpImageOperation::initExecution()
{
PlaneDistortWarpImageOperation::initExecution();
- /* TODO(sergey): De-duplicate with mask operation. */
- float corners[4][2];
- if (this->m_motion_blur_samples == 1) {
- readCornersFromTrack(corners, this->m_framenumber);
- calculateCorners(corners, true, 0);
- }
- else {
- const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
- const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
- float frame_iter = frame;
- for (int sample = 0; sample < this->m_motion_blur_samples; sample++) {
- readCornersFromTrack(corners, frame_iter);
- calculateCorners(corners, true, sample);
- frame_iter += frame_step;
- }
- }
+ PlaneTrackCommon::read_and_calculate_corners(this);
}
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
index 95a7d536742..d240c8b06e9 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
@@ -40,7 +40,7 @@ class PlaneTrackCommon {
/* note: this class is not an operation itself (to prevent virtual inheritance issues)
* implementation classes must make wrappers to use these methods, see below.
*/
- void readCornersFromTrack(float corners[4][2], float frame);
+ void read_and_calculate_corners(PlaneDistortBaseOperation *distort_op);
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
public:
@@ -62,6 +62,9 @@ class PlaneTrackCommon {
{
this->m_framenumber = framenumber;
}
+
+ private:
+ void readCornersFromTrack(float corners[4][2], float frame);
};
class PlaneTrackMaskOperation : public PlaneDistortMaskOperation, public PlaneTrackCommon {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 77661b4870a..ae530cc010e 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -427,9 +427,9 @@ static int foreach_id_cow_detect_need_for_update_callback(LibraryIDLinkCallbackD
*
* NOTE: Currently the only ID types that depsgraph may decide to not evaluate/generate COW
* copies for, even though they are referenced by other data-blocks, are Collections and Objects
- * (through their various visbility flags, and the ones from LayerCollections too). However, this
+ * (through their various visibility flags, and the ones from LayerCollections too). However, this
* code is kept generic as it makes it more future-proof, and optimization here would give
- * neglectable performance improvements in typical cases.
+ * negligible performance improvements in typical cases.
*
* NOTE: This mechanism may also 'fix' some missing update tagging from non-depsgraph code in
* some cases. This is slightly unfortunate (as it may hide issues in other parts of Blender
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 27167ce839b..045adf4b380 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -51,7 +51,7 @@ set(INC
set(SRC
intern/draw_cache.c
intern/draw_cache_extract_mesh.c
- intern/draw_cache_impl_curve.c
+ intern/draw_cache_impl_curve.cc
intern/draw_cache_impl_displist.c
intern/draw_cache_impl_gpencil.c
intern/draw_cache_impl_hair.c
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 5ceb909bc88..34fe29055d6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -297,7 +297,9 @@ typedef struct GPENCIL_PrivateData {
int v3d_color_type;
/* Current frame */
int cfra;
- /* If we are rendering for final render (F12). */
+ /* If we are rendering for final render (F12).
+ * NOTE: set to false for viewport and opengl rendering (including VSE scene rendering), but set
+ * to true when rendering in `OB_RENDER` shading mode (viewport or opengl rendering) */
bool is_render;
/* If we are in viewport display (used for VFX). */
bool is_viewport;
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 7b97ce43558..5743f39f7da 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -43,6 +43,10 @@ struct bGPdata;
#include "BKE_mesh_types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Expose via BKE callbacks */
void DRW_mball_batch_cache_dirty_tag(struct MetaBall *mb, int mode);
void DRW_mball_batch_cache_validate(struct MetaBall *mb);
@@ -262,3 +266,6 @@ struct GPUBatch *DRW_particles_batch_cache_get_edit_inner_points(struct Object *
struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *object,
struct ParticleSystem *psys,
struct PTCacheEdit *edit);
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.cc
index e9558fb320c..ddafc7205bb 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.cc
@@ -144,7 +144,8 @@ static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_
int normal_len = 0;
const BevList *bl;
const Nurb *nu;
- for (bl = ob_curve_cache->bev.first, nu = lb->first; nu && bl; bl = bl->next, nu = nu->next) {
+ for (bl = (const BevList *)ob_curve_cache->bev.first, nu = (const Nurb *)lb->first; nu && bl;
+ bl = bl->next, nu = nu->next) {
int nr = bl->nr;
int skip = nu->resolu / 16;
#if 0
@@ -163,7 +164,7 @@ static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_
/* ---------------------------------------------------------------------- */
/* Curve Interface, indirect, partially cached access to complex data. */
-typedef struct CurveRenderData {
+struct CurveRenderData {
int types;
struct {
@@ -198,7 +199,7 @@ typedef struct CurveRenderData {
int actnu;
/* edit, index in active nurb (BPoint or BezTriple) */
int actvert;
-} CurveRenderData;
+};
enum {
/* Wire center-line */
@@ -220,7 +221,7 @@ static CurveRenderData *curve_render_data_create(Curve *cu,
CurveCache *ob_curve_cache,
const int types)
{
- CurveRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
+ CurveRenderData *rdata = (CurveRenderData *)MEM_callocN(sizeof(*rdata), __func__);
rdata->types = types;
ListBase *nurbs;
@@ -314,7 +315,7 @@ static void curve_cd_calc_used_gpu_layers(CustomDataMask *cd_layers,
{
for (int i = 0; i < gpumat_array_len; i++) {
struct GPUMaterial *gpumat = gpumat_array[i];
- if (gpumat == NULL) {
+ if (gpumat == nullptr) {
continue;
}
@@ -354,7 +355,7 @@ static void curve_cd_calc_used_gpu_layers(CustomDataMask *cd_layers,
/* ---------------------------------------------------------------------- */
/* Curve GPUBatch Cache */
-typedef struct CurveBatchCache {
+struct CurveBatchCache {
struct {
GPUVertBuf *pos_nor;
GPUVertBuf *edge_fac;
@@ -406,15 +407,15 @@ typedef struct CurveBatchCache {
/* Valid only if edge_detection is up to date. */
bool is_manifold;
-} CurveBatchCache;
+};
/* GPUBatch cache management. */
static bool curve_batch_cache_valid(Curve *cu)
{
- CurveBatchCache *cache = cu->batch_cache;
+ CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache;
- if (cache == NULL) {
+ if (cache == nullptr) {
return false;
}
@@ -426,7 +427,7 @@ static bool curve_batch_cache_valid(Curve *cu)
return false;
}
- if (cache->is_editmode != ((cu->editnurb != NULL) || (cu->editfont != NULL))) {
+ if (cache->is_editmode != ((cu->editnurb != nullptr) || (cu->editfont != nullptr))) {
return false;
}
@@ -441,10 +442,11 @@ static bool curve_batch_cache_valid(Curve *cu)
static void curve_batch_cache_init(Curve *cu)
{
- CurveBatchCache *cache = cu->batch_cache;
+ CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache;
if (!cache) {
- cache = cu->batch_cache = MEM_callocN(sizeof(*cache), __func__);
+ cache = (CurveBatchCache *)MEM_callocN(sizeof(*cache), __func__);
+ cu->batch_cache = cache;
}
else {
memset(cache, 0, sizeof(*cache));
@@ -463,11 +465,12 @@ static void curve_batch_cache_init(Curve *cu)
cache->cd_used = 0;
cache->mat_len = DRW_curve_material_count_get(cu);
- cache->surf_per_mat_tris = MEM_callocN(sizeof(*cache->surf_per_mat_tris) * cache->mat_len,
- __func__);
- cache->surf_per_mat = MEM_callocN(sizeof(*cache->surf_per_mat) * cache->mat_len, __func__);
+ cache->surf_per_mat_tris = (GPUIndexBuf **)MEM_callocN(
+ sizeof(*cache->surf_per_mat_tris) * cache->mat_len, __func__);
+ cache->surf_per_mat = (GPUBatch **)MEM_callocN(sizeof(*cache->surf_per_mat) * cache->mat_len,
+ __func__);
- cache->is_editmode = (cu->editnurb != NULL) || (cu->editfont != NULL);
+ cache->is_editmode = (cu->editnurb != nullptr) || (cu->editfont != nullptr);
cache->is_dirty = false;
}
@@ -482,13 +485,13 @@ void DRW_curve_batch_cache_validate(Curve *cu)
static CurveBatchCache *curve_batch_cache_get(Curve *cu)
{
- return cu->batch_cache;
+ return (CurveBatchCache *)cu->batch_cache;
}
void DRW_curve_batch_cache_dirty_tag(Curve *cu, int mode)
{
- CurveBatchCache *cache = cu->batch_cache;
- if (cache == NULL) {
+ CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache;
+ if (cache == nullptr) {
return;
}
switch (mode) {
@@ -508,7 +511,7 @@ void DRW_curve_batch_cache_dirty_tag(Curve *cu, int mode)
static void curve_batch_cache_clear(Curve *cu)
{
- CurveBatchCache *cache = cu->batch_cache;
+ CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache;
if (!cache) {
return;
}
@@ -553,7 +556,7 @@ void DRW_curve_batch_cache_free(Curve *cu)
/* GPUBatch cache usage. */
static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curves_pos)
{
- BLI_assert(rdata->ob_curve_cache != NULL);
+ BLI_assert(rdata->ob_curve_cache != nullptr);
static GPUVertFormat format = {0};
static struct {
@@ -589,7 +592,7 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv
static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines)
{
- BLI_assert(rdata->ob_curve_cache != NULL);
+ BLI_assert(rdata->ob_curve_cache != nullptr);
const int vert_len = curve_render_data_wire_verts_len_get(rdata);
const int edge_len = curve_render_data_wire_edges_len_get(rdata);
@@ -677,7 +680,9 @@ static void curve_create_edit_curves_nor(CurveRenderData *rdata,
const uint tan_id = do_hq_normals ? attr_id.tan_hq : attr_id.tan;
const uint rad_id = do_hq_normals ? attr_id.rad_hq : attr_id.rad;
- for (bl = rdata->ob_curve_cache->bev.first, nu = rdata->nurbs->first; nu && bl;
+ for (bl = (const BevList *)rdata->ob_curve_cache->bev.first,
+ nu = (const Nurb *)rdata->nurbs->first;
+ nu && bl;
bl = bl->next, nu = nu->next) {
const BevPoint *bevp = bl->bevpoints;
int nr = bl->nr;
@@ -773,8 +778,8 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
GPU_vertbuf_data_alloc(vbo_data, verts_len_capacity);
}
- GPUIndexBufBuilder elb_verts, *elbp_verts = NULL;
- GPUIndexBufBuilder elb_lines, *elbp_lines = NULL;
+ GPUIndexBufBuilder elb_verts, *elbp_verts = nullptr;
+ GPUIndexBufBuilder elb_lines, *elbp_lines = nullptr;
if (DRW_TEST_ASSIGN_IBO(ibo_edit_verts_points)) {
elbp_verts = &elb_verts;
GPU_indexbuf_init(elbp_verts, GPU_PRIM_POINTS, verts_len_capacity, verts_len_capacity);
@@ -785,13 +790,13 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
}
int nu_id = 0;
- for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, nu_id++) {
+ for (Nurb *nu = (Nurb *)rdata->nurbs->first; nu; nu = nu->next, nu_id++) {
const BezTriple *bezt = nu->bezt;
const BPoint *bp = nu->bp;
if (bezt) {
for (int a = 0; a < nu->pntsu; a++, bezt++) {
- if (bezt->hide == true) {
+ if (bezt->hide != 0) {
continue;
}
const bool handle_selected = BEZT_ISSEL_ANY(bezt);
@@ -826,7 +831,7 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
else if (bp) {
int pt_len = nu->pntsu * nu->pntsv;
for (int a = 0; a < pt_len; a++, bp++, vbo_len_used += 1) {
- if (bp->hide == true) {
+ if (bp->hide != 0) {
continue;
}
int u = (a % nu->pntsu);
@@ -837,8 +842,8 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used);
}
if (elbp_lines) {
- const BPoint *bp_next_u = (u < (nu->pntsu - 1)) ? &nu->bp[a + 1] : NULL;
- const BPoint *bp_next_v = (v < (nu->pntsv - 1)) ? &nu->bp[a + nu->pntsu] : NULL;
+ const BPoint *bp_next_u = (u < (nu->pntsu - 1)) ? &nu->bp[a + 1] : nullptr;
+ const BPoint *bp_next_v = (v < (nu->pntsv - 1)) ? &nu->bp[a + nu->pntsu] : nullptr;
if (bp_next_u && (bp_next_u->hide == false)) {
GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used, vbo_len_used + 1);
}
@@ -858,17 +863,17 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
}
/* Resize & Finish */
- if (elbp_verts != NULL) {
+ if (elbp_verts != nullptr) {
GPU_indexbuf_build_in_place(elbp_verts, ibo_edit_verts_points);
}
- if (elbp_lines != NULL) {
+ if (elbp_lines != nullptr) {
GPU_indexbuf_build_in_place(elbp_lines, ibo_edit_lines);
}
if (vbo_len_used != verts_len_capacity) {
- if (vbo_pos != NULL) {
+ if (vbo_pos != nullptr) {
GPU_vertbuf_data_resize(vbo_pos, vbo_len_used);
}
- if (vbo_data != NULL) {
+ if (vbo_data != nullptr) {
GPU_vertbuf_data_resize(vbo_data, vbo_len_used);
}
}
@@ -932,7 +937,7 @@ GPUVertBuf *DRW_curve_batch_cache_pos_vertbuf_get(struct Curve *cu)
/* Request surface to trigger the vbo filling. Otherwise it may do nothing. */
DRW_batch_request(&cache->batch.surfaces);
- DRW_vbo_request(NULL, &cache->ordered.loop_pos_nor);
+ DRW_vbo_request(nullptr, &cache->ordered.loop_pos_nor);
return cache->ordered.loop_pos_nor;
}
@@ -968,7 +973,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen
{
BLI_assert(ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT));
- Curve *cu = ob->data;
+ Curve *cu = (Curve *)ob->data;
CurveBatchCache *cache = curve_batch_cache_get(cu);
/* Verify that all surface batches have needed attribute layers. */
@@ -1118,7 +1123,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen
#ifdef DEBUG
/* Make sure all requested batches have been setup. */
for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); i++) {
- BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], 0));
+ BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], (GPUPrimType)0));
}
#endif
}
diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h
index ebe97b4e7c4..bfc714e5d6a 100644
--- a/source/blender/draw/intern/draw_cache_inline.h
+++ b/source/blender/draw/intern/draw_cache_inline.h
@@ -53,13 +53,13 @@ BLI_INLINE GPUBatch *DRW_batch_request(GPUBatch **batch)
return *batch;
}
-BLI_INLINE bool DRW_batch_requested(GPUBatch *batch, int prim_type)
+BLI_INLINE bool DRW_batch_requested(GPUBatch *batch, GPUPrimType prim_type)
{
/* Batch has been requested if it has been created but not initialized. */
if (batch != NULL && batch->verts[0] == NULL) {
/* HACK. We init without a valid VBO and let the first vbo binding
* fill verts[0]. */
- GPU_batch_init_ex(batch, prim_type, (GPUVertBuf *)1, NULL, 0);
+ GPU_batch_init_ex(batch, prim_type, (GPUVertBuf *)1, NULL, (eGPUBatchFlag)0);
batch->verts[0] = NULL;
return true;
}
diff --git a/source/blender/editors/geometry/geometry_attributes.c b/source/blender/editors/geometry/geometry_attributes.c
index 12f6bb90677..b2ecee90a57 100644
--- a/source/blender/editors/geometry/geometry_attributes.c
+++ b/source/blender/editors/geometry/geometry_attributes.c
@@ -52,12 +52,16 @@ static const EnumPropertyItem *geometry_attribute_domain_itemf(bContext *C,
PropertyRNA *UNUSED(prop),
bool *r_free)
{
+ if (C == NULL) {
+ return DummyRNA_NULL_items;
+ }
+
Object *ob = ED_object_context(C);
- if (ob != NULL) {
- return rna_enum_attribute_domain_itemf(ob->data, r_free);
+ if (ob == NULL) {
+ return DummyRNA_NULL_items;
}
- return DummyRNA_NULL_items;
+ return rna_enum_attribute_domain_itemf(ob->data, r_free);
}
static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 30d85b09974..993065a3a70 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1332,7 +1332,7 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
/* only erase stroke points that are visible */
static bool gpencil_stroke_eraser_is_occluded(
- tGPsdata *p, bGPDlayer *gpl, const bGPDspoint *pt, const int x, const int y)
+ tGPsdata *p, bGPDlayer *gpl, bGPDspoint *pt, const int x, const int y)
{
Object *obact = (Object *)p->ownerPtr.data;
Brush *brush = p->brush;
@@ -1364,7 +1364,11 @@ static bool gpencil_stroke_eraser_is_occluded(
mul_v3_m4v3(fpt, diff_mat, &pt->x);
const float depth_pt = view3d_point_depth(rv3d, fpt);
+ /* Checked occlusion flag. */
+ pt->flag |= GP_SPOINT_TEMP_TAG;
if (depth_pt > depth_mval) {
+ /* Is occluded. */
+ pt->flag |= GP_SPOINT_TEMP_TAG2;
return true;
}
}
@@ -1540,6 +1544,10 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
for (i = 0; i < gps->totpoints; i++) {
bGPDspoint *pt = &gps->points[i];
pt->flag &= ~GP_SPOINT_TAG;
+ /* Occlusion already checked. */
+ pt->flag &= ~GP_SPOINT_TEMP_TAG;
+ /* Point is occluded. */
+ pt->flag &= ~GP_SPOINT_TEMP_TAG2;
}
/* First Pass: Loop over the points in the stroke
@@ -1585,9 +1593,23 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
* - this assumes that linewidth is irrelevant
*/
if (gpencil_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
- if ((gpencil_stroke_eraser_is_occluded(p, gpl, pt0, pc0[0], pc0[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, gpl, pt1, pc1[0], pc1[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, gpl, pt2, pc2[0], pc2[1]) == false)) {
+
+ bool is_occluded_pt0, is_occluded_pt1, is_occluded_pt2 = true;
+ is_occluded_pt0 = (pt0 && ((pt0->flag & GP_SPOINT_TEMP_TAG) != 0)) ?
+ ((pt0->flag & GP_SPOINT_TEMP_TAG2) != 0) :
+ gpencil_stroke_eraser_is_occluded(p, gpl, pt0, pc0[0], pc0[1]);
+ if (is_occluded_pt0) {
+ is_occluded_pt1 = ((pt1->flag & GP_SPOINT_TEMP_TAG) != 0) ?
+ ((pt1->flag & GP_SPOINT_TEMP_TAG2) != 0) :
+ gpencil_stroke_eraser_is_occluded(p, gpl, pt1, pc1[0], pc1[1]);
+ if (is_occluded_pt1) {
+ is_occluded_pt2 = ((pt2->flag & GP_SPOINT_TEMP_TAG) != 0) ?
+ ((pt2->flag & GP_SPOINT_TEMP_TAG2) != 0) :
+ gpencil_stroke_eraser_is_occluded(p, gpl, pt2, pc2[0], pc2[1]);
+ }
+ }
+
+ if (!is_occluded_pt0 || !is_occluded_pt1 || !is_occluded_pt2) {
/* Point is affected: */
/* Adjust thickness
* - Influence of eraser falls off with distance from the middle of the eraser
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index e4f502950ab..b52bfc81b7a 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -138,8 +138,8 @@ void eyedropper_draw_cursor_text_region(const struct bContext *C,
}
const int mval[2] = {
- x - region->winrct.xmin,
- y - region->winrct.ymin,
+ x - region->winrct.xmin,
+ y - region->winrct.ymin,
};
eyedropper_draw_cursor_text_ex(mval[0], mval[1], name);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 8cf7d60e6c4..b0255e79858 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1312,6 +1312,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
const int type = RNA_enum_get(op->ptr, "type");
const bool use_in_front = RNA_boolean_get(op->ptr, "use_in_front");
+ const bool use_lights = RNA_boolean_get(op->ptr, "use_lights");
const int stroke_depth_order = RNA_enum_get(op->ptr, "stroke_depth_order");
ushort local_view_bits;
@@ -1432,6 +1433,13 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
id_us_plus(&md->target_material->id);
}
+ if (use_lights) {
+ ob->dtx |= OB_USE_GPENCIL_LIGHTS;
+ }
+ else {
+ ob->dtx &= ~OB_USE_GPENCIL_LIGHTS;
+ }
+
/* Stroke object is drawn in front of meshes by default. */
if (use_in_front) {
ob->dtx |= OB_DRAW_IN_FRONT;
@@ -1474,6 +1482,7 @@ static void object_add_ui(bContext *UNUSED(C), wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
if (type == GP_LRT_COLLECTION || type == GP_LRT_OBJECT || type == GP_LRT_SCENE) {
+ uiItemR(layout, op->ptr, "use_lights", 0, NULL, ICON_NONE);
uiItemR(layout, op->ptr, "use_in_front", 0, NULL, ICON_NONE);
bool in_front = RNA_boolean_get(op->ptr, "use_in_front");
uiLayout *row = uiLayoutRow(layout, false);
@@ -1520,6 +1529,8 @@ void OBJECT_OT_gpencil_add(wmOperatorType *ot)
false,
"In Front",
"Show line art grease pencil in front of everything");
+ RNA_def_boolean(
+ ot->srna, "use_lights", false, "Use Lights", "Use lights for this grease pencil object");
RNA_def_enum(
ot->srna,
"stroke_depth_order",
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 5f81f9afe4f..3f40d637188 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -3985,6 +3985,10 @@ static const EnumPropertyItem *vgroup_itemf(bContext *C,
PropertyRNA *UNUSED(prop),
bool *r_free)
{
+ if (C == NULL) {
+ return DummyRNA_NULL_items;
+ }
+
Object *ob = ED_object_context(C);
EnumPropertyItem tmp = {0, "", 0, "", ""};
EnumPropertyItem *item = NULL;
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index cd75bc98b15..ac31e0e7c37 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -158,7 +158,7 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
ot->prop = RNA_def_boolean(ot->srna,
"set_view_transform",
true,
- "Set view transform",
+ "Set View Transform",
"Set appropriate view transform based on media colorspace");
}
}
@@ -1081,8 +1081,7 @@ static int sequencer_add_image_strip_invoke(bContext *C,
sequencer_disable_one_time_properties(C, op);
- const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
- RNA_enum_set(op->ptr, "fit_method", tool_settings->fit_method);
+ RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene));
/* Name set already by drag and drop. */
if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) {
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
index d1e80f1d87e..c9b73aabf96 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
@@ -50,7 +50,7 @@ class CellValue {
std::optional<bool> value_bool;
std::optional<float2> value_float2;
std::optional<float3> value_float3;
- std::optional<Color4f> value_color;
+ std::optional<ColorGeometry4f> value_color;
std::optional<ObjectCellValue> value_object;
std::optional<CollectionCellValue> value_collection;
};
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index 02ffa1259fc..452885959f6 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -116,7 +116,7 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
column_id.name,
domain_size,
[varray](int index, CellValue &r_cell_value) {
- Color4f value;
+ ColorGeometry4f value;
varray->get(index, &value);
r_cell_value.value_color = value;
},
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
index f1ca65817f6..8079763a339 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
@@ -170,7 +170,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
this->draw_float_vector(params, Span(&value.x, 3));
}
else if (cell_value.value_color.has_value()) {
- const Color4f value = *cell_value.value_color;
+ const ColorGeometry4f value = *cell_value.value_color;
this->draw_float_vector(params, Span(&value.r, 4));
}
else if (cell_value.value_object.has_value()) {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 0a89b7d0292..4a595c716b6 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2039,6 +2039,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
v3d.shading.type = drawtype;
v3d.flag2 = V3D_HIDE_OVERLAYS;
+ /* HACK: When rendering gpencil objects this opacity is used to mix vertex colors in when not in
+ * render mode. */
+ v3d.overlay.gpencil_vertex_paint_opacity = 1.0f;
if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) {
v3d.flag2 |= V3D_SHOW_ANNOTATION;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index ba8e5c1e2c6..17bfc23aea7 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -724,81 +724,92 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
{
- if (!(t->flag & T_NO_CONSTRAINT)) {
- if (t->flag & T_2D_EDIT && ELEM(modal_type, TFM_MODAL_AXIS_Z, TFM_MODAL_PLANE_Z)) {
+ if (t->flag & T_NO_CONSTRAINT) {
+ return false;
+ }
+
+ if (t->flag & T_2D_EDIT && ELEM(modal_type, TFM_MODAL_AXIS_Z, TFM_MODAL_PLANE_Z)) {
+ return false;
+ }
+
+ int constraint_curr = -1;
+
+ if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) {
+ t->modifiers &= ~(MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE);
+
+ /* Avoid changing orientation in this case. */
+ constraint_curr = -2;
+ }
+ else if (t->con.mode & CON_APPLY) {
+ constraint_curr = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
+ }
+
+ int constraint_new;
+ const char *msg_2d = "", *msg_3d = "";
+
+ /* Initialize */
+ switch (modal_type) {
+ case TFM_MODAL_AXIS_X:
+ msg_2d = TIP_("along X");
+ msg_3d = TIP_("along %s X");
+ constraint_new = CON_AXIS0;
+ break;
+ case TFM_MODAL_AXIS_Y:
+ msg_2d = TIP_("along Y");
+ msg_3d = TIP_("along %s Y");
+ constraint_new = CON_AXIS1;
+ break;
+ case TFM_MODAL_AXIS_Z:
+ msg_2d = TIP_("along Z");
+ msg_3d = TIP_("along %s Z");
+ constraint_new = CON_AXIS2;
+ break;
+ case TFM_MODAL_PLANE_X:
+ msg_3d = TIP_("locking %s X");
+ constraint_new = CON_AXIS1 | CON_AXIS2;
+ break;
+ case TFM_MODAL_PLANE_Y:
+ msg_3d = TIP_("locking %s Y");
+ constraint_new = CON_AXIS0 | CON_AXIS2;
+ break;
+ case TFM_MODAL_PLANE_Z:
+ msg_3d = TIP_("locking %s Z");
+ constraint_new = CON_AXIS0 | CON_AXIS1;
+ break;
+ default:
+ /* Invalid key */
return false;
- }
- int constraint_curr = (t->con.mode & CON_APPLY) ?
- t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2) :
- -1;
- int constraint_new;
- const char *msg_2d = "", *msg_3d = "";
+ }
- /* Initialize */
- switch (modal_type) {
- case TFM_MODAL_AXIS_X:
- msg_2d = TIP_("along X");
- msg_3d = TIP_("along %s X");
- constraint_new = CON_AXIS0;
- break;
- case TFM_MODAL_AXIS_Y:
- msg_2d = TIP_("along Y");
- msg_3d = TIP_("along %s Y");
- constraint_new = CON_AXIS1;
- break;
- case TFM_MODAL_AXIS_Z:
- msg_2d = TIP_("along Z");
- msg_3d = TIP_("along %s Z");
- constraint_new = CON_AXIS2;
- break;
- case TFM_MODAL_PLANE_X:
- msg_3d = TIP_("locking %s X");
- constraint_new = CON_AXIS1 | CON_AXIS2;
- break;
- case TFM_MODAL_PLANE_Y:
- msg_3d = TIP_("locking %s Y");
- constraint_new = CON_AXIS0 | CON_AXIS2;
- break;
- case TFM_MODAL_PLANE_Z:
- msg_3d = TIP_("locking %s Z");
- constraint_new = CON_AXIS0 | CON_AXIS1;
- break;
- default:
- /* Invalid key */
- return false;
+ if (t->flag & T_2D_EDIT) {
+ BLI_assert(modal_type < TFM_MODAL_PLANE_X);
+ if (constraint_new == CON_AXIS2) {
+ return false;
}
-
- if (t->flag & T_2D_EDIT) {
- BLI_assert(modal_type < TFM_MODAL_PLANE_X);
- if (constraint_new == CON_AXIS2) {
- return false;
- }
- if (constraint_curr == constraint_new) {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, constraint_new, msg_2d);
- }
+ if (constraint_curr == constraint_new) {
+ stopConstraint(t);
}
else {
- short orient_index = 1;
- if (t->orient_curr == O_DEFAULT || ELEM(constraint_curr, -1, constraint_new)) {
- /* Successive presses on existing axis, cycle orientation modes. */
- orient_index = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
- }
+ setUserConstraint(t, constraint_new, msg_2d);
+ }
+ }
+ else {
+ short orient_index = 1;
+ if (t->orient_curr == O_DEFAULT || ELEM(constraint_curr, -1, constraint_new)) {
+ /* Successive presses on existing axis, cycle orientation modes. */
+ orient_index = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
+ }
- transform_orientations_current_set(t, orient_index);
- if (orient_index == 0) {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, constraint_new, msg_3d);
- }
+ transform_orientations_current_set(t, orient_index);
+ if (orient_index == 0) {
+ stopConstraint(t);
+ }
+ else {
+ setUserConstraint(t, constraint_new, msg_3d);
}
- t->redraw |= TREDRAW_HARD;
- return true;
}
- return false;
+ t->redraw |= TREDRAW_HARD;
+ return true;
}
int transformEvent(TransInfo *t, const wmEvent *event)
@@ -814,7 +825,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
else if (event->type == MOUSEMOVE) {
- if (t->modifiers & (MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE)) {
+ if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) {
t->con.mode |= CON_SELECT;
}
@@ -1062,10 +1073,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->state = TRANS_CONFIRM;
}
else if ((t->flag & T_NO_CONSTRAINT) == 0) {
- if (t->modifiers & (MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE)) {
+ if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) {
/* Confirm. */
postSelectConstraint(t);
- t->modifiers &= ~(MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE);
+ t->modifiers &= ~(MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE);
}
else {
if (t->options & CTX_CAMERA) {
@@ -1079,8 +1090,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
else {
- t->modifiers |= (event->val == TFM_MODAL_AUTOCONSTRAINT) ? MOD_CONSTRAINT_SELECT :
- MOD_CONSTRAINT_PLANE;
+ t->modifiers |= (event->val == TFM_MODAL_AUTOCONSTRAINT) ?
+ MOD_CONSTRAINT_SELECT_AXIS :
+ MOD_CONSTRAINT_SELECT_PLANE;
if (t->con.mode & CON_APPLY) {
stopConstraint(t);
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 0533c08bdc2..f03defe26e2 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -152,11 +152,11 @@ typedef enum {
/** #TransInfo.modifiers */
typedef enum {
- MOD_CONSTRAINT_SELECT = 1 << 0,
+ MOD_CONSTRAINT_SELECT_AXIS = 1 << 0,
MOD_PRECISION = 1 << 1,
MOD_SNAP = 1 << 2,
MOD_SNAP_INVERT = 1 << 3,
- MOD_CONSTRAINT_PLANE = 1 << 4,
+ MOD_CONSTRAINT_SELECT_PLANE = 1 << 4,
} eTModifier;
/** #TransSnap.status */
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 615467932a7..8c74d5349ba 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -975,7 +975,6 @@ void initSelectConstraint(TransInfo *t)
}
setUserConstraint(t, CON_APPLY | CON_SELECT, "%s");
- setNearestAxis(t);
}
void selectConstraint(TransInfo *t)
@@ -1062,7 +1061,7 @@ static void setNearestAxis3d(TransInfo *t)
}
if (len[0] <= len[1] && len[0] <= len[2]) {
- if (t->modifiers & MOD_CONSTRAINT_PLANE) {
+ if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
t->con.mode |= (CON_AXIS1 | CON_AXIS2);
BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s X axis"), t->spacename);
}
@@ -1072,7 +1071,7 @@ static void setNearestAxis3d(TransInfo *t)
}
}
else if (len[1] <= len[0] && len[1] <= len[2]) {
- if (t->modifiers & MOD_CONSTRAINT_PLANE) {
+ if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
t->con.mode |= (CON_AXIS0 | CON_AXIS2);
BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Y axis"), t->spacename);
}
@@ -1082,7 +1081,7 @@ static void setNearestAxis3d(TransInfo *t)
}
}
else if (len[2] <= len[1] && len[2] <= len[0]) {
- if (t->modifiers & MOD_CONSTRAINT_PLANE) {
+ if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
t->con.mode |= (CON_AXIS0 | CON_AXIS1);
BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Z axis"), t->spacename);
}
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 0bef6364214..175b7b52a1a 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -471,6 +471,7 @@ void initTranslation(TransInfo *t)
t->num.unit_type[2] = B_UNIT_NONE;
}
- transform_mode_default_modal_orientation_set(t, V3D_ORIENT_GLOBAL);
+ transform_mode_default_modal_orientation_set(
+ t, (t->options & CTX_CAMERA) ? V3D_ORIENT_VIEW : V3D_ORIENT_GLOBAL);
}
/** \} */
diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc
index 53c5def57e9..9c2c1621e23 100644
--- a/source/blender/functions/intern/cpp_types.cc
+++ b/source/blender/functions/intern/cpp_types.cc
@@ -34,8 +34,8 @@ MAKE_CPP_TYPE(int32, int32_t)
MAKE_CPP_TYPE(uint32, uint32_t)
MAKE_CPP_TYPE(uint8, uint8_t)
-MAKE_CPP_TYPE(Color4f, blender::Color4f)
-MAKE_CPP_TYPE(Color4b, blender::Color4b)
+MAKE_CPP_TYPE(ColorGeometry4f, blender::ColorGeometry4f)
+MAKE_CPP_TYPE(ColorGeometry4b, blender::ColorGeometry4b)
MAKE_CPP_TYPE(string, std::string)
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 44ff0616fe9..e679dce2f2d 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -93,8 +93,8 @@ typedef struct LineartElementLinkNode {
float crease_threshold;
} LineartElementLinkNode;
-typedef struct LineartLineSegment {
- struct LineartLineSegment *next, *prev;
+typedef struct LineartEdgeSegment {
+ struct LineartEdgeSegment *next, *prev;
/** at==0: left at==1: right (this is in 2D projected space) */
double at;
/** Occlusion level after "at" point */
@@ -107,7 +107,7 @@ typedef struct LineartLineSegment {
* enough for most cases.
*/
unsigned char transparency_mask;
-} LineartLineSegment;
+} LineartEdgeSegment;
typedef struct LineartVert {
double gloc[3];
@@ -163,8 +163,8 @@ typedef struct LineartEdge {
struct Object *object_ref;
} LineartEdge;
-typedef struct LineartLineChain {
- struct LineartLineChain *next, *prev;
+typedef struct LineartEdgeChain {
+ struct LineartEdgeChain *next, *prev;
ListBase chain;
/** Calculated before draw command. */
@@ -179,10 +179,10 @@ typedef struct LineartLineChain {
unsigned char transparency_mask;
struct Object *object_ref;
-} LineartLineChain;
+} LineartEdgeChain;
-typedef struct LineartLineChainItem {
- struct LineartLineChainItem *next, *prev;
+typedef struct LineartEdgeChainItem {
+ struct LineartEdgeChainItem *next, *prev;
/** Need z value for fading */
float pos[3];
/** For restoring position to 3d space */
@@ -192,12 +192,12 @@ typedef struct LineartLineChainItem {
char occlusion;
unsigned char transparency_mask;
size_t index;
-} LineartLineChainItem;
+} LineartEdgeChainItem;
typedef struct LineartChainRegisterEntry {
struct LineartChainRegisterEntry *next, *prev;
- LineartLineChain *rlc;
- LineartLineChainItem *rlci;
+ LineartEdgeChain *ec;
+ LineartEdgeChainItem *eci;
char picked;
/* left/right mark.
@@ -237,31 +237,14 @@ typedef struct LineartRenderBuffer {
int triangle_size;
- unsigned int contour_count;
- unsigned int contour_processed;
- LineartEdge *contour_managed;
- /** A single linked list (cast to #LinkNode). */
- LineartEdge *contours;
-
- unsigned int intersection_count;
- unsigned int intersection_processed;
- LineartEdge *intersection_managed;
- LineartEdge *intersection_lines;
-
- unsigned int crease_count;
- unsigned int crease_processed;
- LineartEdge *crease_managed;
- LineartEdge *crease_lines;
-
- unsigned int material_line_count;
- unsigned int material_processed;
- LineartEdge *material_managed;
- LineartEdge *material_lines;
-
- unsigned int edge_mark_count;
- unsigned int edge_mark_processed;
- LineartEdge *edge_mark_managed;
- LineartEdge *edge_marks;
+ /* Although using ListBase here, LineartEdge is single linked list.
+ * list.last is used to store worker progress along the list.
+ * See lineart_main_occlusion_begin() for more info. */
+ ListBase contour;
+ ListBase intersection;
+ ListBase crease;
+ ListBase material;
+ ListBase edge_mark;
ListBase chains;
@@ -334,20 +317,13 @@ typedef struct LineartRenderTaskInfo {
int thread_id;
- LineartEdge *contour;
- LineartEdge *contour_end;
-
- LineartEdge *intersection;
- LineartEdge *intersection_end;
-
- LineartEdge *crease;
- LineartEdge *crease_end;
-
- LineartEdge *material;
- LineartEdge *material_end;
-
- LineartEdge *edge_mark;
- LineartEdge *edge_mark_end;
+ /* These lists only denote the part of the main edge list that the thread should iterate over.
+ * Be careful to not iterate outside of these bounds as it is not thread safe to do so. */
+ ListBase contour;
+ ListBase intersection;
+ ListBase crease;
+ ListBase material;
+ ListBase edge_mark;
} LineartRenderTaskInfo;
@@ -390,7 +366,7 @@ typedef struct LineartBoundingArea {
short triangle_count;
ListBase linked_triangles;
- ListBase linked_lines;
+ ListBase linked_edges;
/** Reserved for image space reduction && multi-thread chaining. */
ListBase linked_chains;
@@ -529,7 +505,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb);
void MOD_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold);
void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad);
-int MOD_lineart_chain_count(const LineartLineChain *rlc);
+int MOD_lineart_chain_count(const LineartEdgeChain *ec);
void MOD_lineart_chain_clear_picked_flag(struct LineartRenderBuffer *rb);
bool MOD_lineart_compute_feature_lines(struct Depsgraph *depsgraph,
@@ -565,6 +541,6 @@ void MOD_lineart_gpencil_generate(LineartRenderBuffer *rb,
const char *vgname,
int modifier_flags);
-float MOD_lineart_chain_compute_length(LineartLineChain *rlc);
+float MOD_lineart_chain_compute_length(LineartEdgeChain *ec);
void ED_operatortypes_lineart(void);
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
index 4ad8eed6ddd..c8e4e93843a 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -31,16 +31,16 @@
#include <math.h>
-#define LRT_OTHER_RV(e, rv) ((rv) == (e)->v1 ? (e)->v2 : ((rv) == (e)->v2 ? (e)->v1 : NULL))
+#define LRT_OTHER_VERT(e, vt) ((vt) == (e)->v1 ? (e)->v2 : ((vt) == (e)->v2 ? (e)->v1 : NULL))
/* Get a connected line, only for lines who has the exact given vert, or (in the case of
* intersection lines) who has a vert that has the exact same position. */
static LineartEdge *lineart_line_get_connected(LineartBoundingArea *ba,
- LineartVert *rv,
- LineartVert **new_rv,
+ LineartVert *vt,
+ LineartVert **new_vt,
int match_flag)
{
- LISTBASE_FOREACH (LinkData *, lip, &ba->linked_lines) {
+ LISTBASE_FOREACH (LinkData *, lip, &ba->linked_edges) {
LineartEdge *n_e = lip->data;
if ((!(n_e->flags & LRT_EDGE_FLAG_ALL_TYPE)) || (n_e->flags & LRT_EDGE_FLAG_CHAIN_PICKED)) {
@@ -51,18 +51,18 @@ static LineartEdge *lineart_line_get_connected(LineartBoundingArea *ba,
continue;
}
- *new_rv = LRT_OTHER_RV(n_e, rv);
- if (*new_rv) {
+ *new_vt = LRT_OTHER_VERT(n_e, vt);
+ if (*new_vt) {
return n_e;
}
if (n_e->flags & LRT_EDGE_FLAG_INTERSECTION) {
- if (rv->fbcoord[0] == n_e->v1->fbcoord[0] && rv->fbcoord[1] == n_e->v1->fbcoord[1]) {
- *new_rv = LRT_OTHER_RV(n_e, n_e->v1);
+ if (vt->fbcoord[0] == n_e->v1->fbcoord[0] && vt->fbcoord[1] == n_e->v1->fbcoord[1]) {
+ *new_vt = LRT_OTHER_VERT(n_e, n_e->v1);
return n_e;
}
- if (rv->fbcoord[0] == n_e->v2->fbcoord[0] && rv->fbcoord[1] == n_e->v2->fbcoord[1]) {
- *new_rv = LRT_OTHER_RV(n_e, n_e->v2);
+ if (vt->fbcoord[0] == n_e->v2->fbcoord[0] && vt->fbcoord[1] == n_e->v2->fbcoord[1]) {
+ *new_vt = LRT_OTHER_VERT(n_e, n_e->v2);
return n_e;
}
}
@@ -71,33 +71,33 @@ static LineartEdge *lineart_line_get_connected(LineartBoundingArea *ba,
return NULL;
}
-static LineartLineChain *lineart_chain_create(LineartRenderBuffer *rb)
+static LineartEdgeChain *lineart_chain_create(LineartRenderBuffer *rb)
{
- LineartLineChain *rlc;
- rlc = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartLineChain));
+ LineartEdgeChain *ec;
+ ec = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdgeChain));
- BLI_addtail(&rb->chains, rlc);
+ BLI_addtail(&rb->chains, ec);
- return rlc;
+ return ec;
}
-static bool lineart_point_overlapping(LineartLineChainItem *rlci,
+static bool lineart_point_overlapping(LineartEdgeChainItem *eci,
float x,
float y,
double threshold)
{
- if (!rlci) {
+ if (!eci) {
return false;
}
- if (((rlci->pos[0] + threshold) >= x) && ((rlci->pos[0] - threshold) <= x) &&
- ((rlci->pos[1] + threshold) >= y) && ((rlci->pos[1] - threshold) <= y)) {
+ if (((eci->pos[0] + threshold) >= x) && ((eci->pos[0] - threshold) <= x) &&
+ ((eci->pos[1] + threshold) >= y) && ((eci->pos[1] - threshold) <= y)) {
return true;
}
return false;
}
-static LineartLineChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
- LineartLineChain *rlc,
+static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
+ LineartEdgeChain *ec,
float *fbcoord,
float *gpos,
float *normal,
@@ -106,35 +106,35 @@ static LineartLineChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
unsigned char transparency_mask,
size_t index)
{
- LineartLineChainItem *rlci;
+ LineartEdgeChainItem *eci;
- if (lineart_point_overlapping(rlc->chain.last, fbcoord[0], fbcoord[1], 1e-5)) {
+ if (lineart_point_overlapping(ec->chain.last, fbcoord[0], fbcoord[1], 1e-5)) {
/* Because the new chain point is overlapping, just replace the type and occlusion level of the
* current point. This makes it so that the line to the point after this one has the correct
* type and level. */
- LineartLineChainItem *old_rlci = rlc->chain.last;
+ LineartEdgeChainItem *old_rlci = ec->chain.last;
old_rlci->line_type = type;
old_rlci->occlusion = level;
old_rlci->transparency_mask = transparency_mask;
return old_rlci;
}
- rlci = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartLineChainItem));
+ eci = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdgeChainItem));
- copy_v2_v2(rlci->pos, fbcoord);
- copy_v3_v3(rlci->gpos, gpos);
- rlci->index = index;
- copy_v3_v3(rlci->normal, normal);
- rlci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
- rlci->occlusion = level;
- rlci->transparency_mask = transparency_mask;
- BLI_addtail(&rlc->chain, rlci);
+ copy_v2_v2(eci->pos, fbcoord);
+ copy_v3_v3(eci->gpos, gpos);
+ eci->index = index;
+ copy_v3_v3(eci->normal, normal);
+ eci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
+ eci->occlusion = level;
+ eci->transparency_mask = transparency_mask;
+ BLI_addtail(&ec->chain, eci);
- return rlci;
+ return eci;
}
-static LineartLineChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb,
- LineartLineChain *rlc,
+static LineartEdgeChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb,
+ LineartEdgeChain *ec,
float *fbcoord,
float *gpos,
float *normal,
@@ -143,32 +143,32 @@ static LineartLineChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb
unsigned char transparency_mask,
size_t index)
{
- LineartLineChainItem *rlci;
+ LineartEdgeChainItem *eci;
- if (lineart_point_overlapping(rlc->chain.first, fbcoord[0], fbcoord[1], 1e-5)) {
- return rlc->chain.first;
+ if (lineart_point_overlapping(ec->chain.first, fbcoord[0], fbcoord[1], 1e-5)) {
+ return ec->chain.first;
}
- rlci = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartLineChainItem));
+ eci = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdgeChainItem));
- copy_v2_v2(rlci->pos, fbcoord);
- copy_v3_v3(rlci->gpos, gpos);
- rlci->index = index;
- copy_v3_v3(rlci->normal, normal);
- rlci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
- rlci->occlusion = level;
- rlci->transparency_mask = transparency_mask;
- BLI_addhead(&rlc->chain, rlci);
+ copy_v2_v2(eci->pos, fbcoord);
+ copy_v3_v3(eci->gpos, gpos);
+ eci->index = index;
+ copy_v3_v3(eci->normal, normal);
+ eci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
+ eci->occlusion = level;
+ eci->transparency_mask = transparency_mask;
+ BLI_addhead(&ec->chain, eci);
- return rlci;
+ return eci;
}
void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
{
- LineartLineChain *rlc;
- LineartLineChainItem *rlci;
+ LineartEdgeChain *ec;
+ LineartEdgeChainItem *eci;
LineartBoundingArea *ba;
- LineartLineSegment *rls;
+ LineartEdgeSegment *es;
int last_occlusion;
unsigned char last_transparency;
/* Used when converting from double. */
@@ -192,14 +192,14 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
- rlc = lineart_chain_create(rb);
+ ec = lineart_chain_create(rb);
/* One chain can only have one object_ref,
* so we assign it based on the first segment we found. */
- rlc->object_ref = e->object_ref;
+ ec->object_ref = e->object_ref;
LineartEdge *new_e = e;
- LineartVert *new_rv;
+ LineartVert *new_vt;
float N[3] = {0};
if (e->t1) {
@@ -218,19 +218,19 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
/* Step 1: grow left. */
ba = MOD_lineart_get_bounding_area(rb, e->v1->fbcoord[0], e->v1->fbcoord[1]);
- new_rv = e->v1;
- rls = e->segments.first;
- VERT_COORD_TO_FLOAT(new_rv);
+ new_vt = e->v1;
+ es = e->segments.first;
+ VERT_COORD_TO_FLOAT(new_vt);
lineart_chain_prepend_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
e->flags,
- rls->occlusion,
- rls->transparency_mask,
+ es->occlusion,
+ es->transparency_mask,
e->v1_obindex);
- while (ba && (new_e = lineart_line_get_connected(ba, new_rv, &new_rv, e->flags))) {
+ while (ba && (new_e = lineart_line_get_connected(ba, new_vt, &new_vt, e->flags))) {
new_e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
if (new_e->t1 || new_e->t2) {
@@ -248,41 +248,41 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
normalize_v3(N);
}
- if (new_rv == new_e->v1) {
- for (rls = new_e->segments.last; rls; rls = rls->prev) {
+ if (new_vt == new_e->v1) {
+ for (es = new_e->segments.last; es; es = es->prev) {
double gpos[3], lpos[3];
double *lfb = new_e->v1->fbcoord, *rfb = new_e->v2->fbcoord;
- double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
- interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, rls->at);
+ double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
+ interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
POS_TO_FLOAT(lpos, gpos)
lineart_chain_prepend_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
new_e->flags,
- rls->occlusion,
- rls->transparency_mask,
+ es->occlusion,
+ es->transparency_mask,
new_e->v1_obindex);
- last_occlusion = rls->occlusion;
- last_transparency = rls->transparency_mask;
+ last_occlusion = es->occlusion;
+ last_transparency = es->transparency_mask;
}
}
- else if (new_rv == new_e->v2) {
- rls = new_e->segments.first;
- last_occlusion = rls->occlusion;
- last_transparency = rls->transparency_mask;
- rls = rls->next;
- for (; rls; rls = rls->next) {
+ else if (new_vt == new_e->v2) {
+ es = new_e->segments.first;
+ last_occlusion = es->occlusion;
+ last_transparency = es->transparency_mask;
+ es = es->next;
+ for (; es; es = es->next) {
double gpos[3], lpos[3];
double *lfb = new_e->v1->fbcoord, *rfb = new_e->v2->fbcoord;
- double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
- interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, rls->at);
+ double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
+ interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
POS_TO_FLOAT(lpos, gpos)
lineart_chain_prepend_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
@@ -290,12 +290,12 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
last_occlusion,
last_transparency,
new_e->v2_obindex);
- last_occlusion = rls->occlusion;
- last_transparency = rls->transparency_mask;
+ last_occlusion = es->occlusion;
+ last_transparency = es->transparency_mask;
}
VERT_COORD_TO_FLOAT(new_e->v2);
lineart_chain_prepend_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
@@ -304,7 +304,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
last_transparency,
new_e->v2_obindex);
}
- ba = MOD_lineart_get_bounding_area(rb, new_rv->fbcoord[0], new_rv->fbcoord[1]);
+ ba = MOD_lineart_get_bounding_area(rb, new_vt->fbcoord[0], new_vt->fbcoord[1]);
}
/* Restore normal value. */
@@ -324,31 +324,31 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
}
/* Step 2: Adding all cuts from the given line, so we can continue connecting the right side
* of the line. */
- rls = e->segments.first;
- last_occlusion = ((LineartLineSegment *)rls)->occlusion;
- last_transparency = ((LineartLineSegment *)rls)->transparency_mask;
- for (rls = rls->next; rls; rls = rls->next) {
+ es = e->segments.first;
+ last_occlusion = ((LineartEdgeSegment *)es)->occlusion;
+ last_transparency = ((LineartEdgeSegment *)es)->transparency_mask;
+ for (es = es->next; es; es = es->next) {
double gpos[3], lpos[3];
double *lfb = e->v1->fbcoord, *rfb = e->v2->fbcoord;
- double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
- interp_v3_v3v3_db(lpos, e->v1->fbcoord, e->v2->fbcoord, rls->at);
+ double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
+ interp_v3_v3v3_db(lpos, e->v1->fbcoord, e->v2->fbcoord, es->at);
interp_v3_v3v3_db(gpos, e->v1->gloc, e->v2->gloc, global_at);
POS_TO_FLOAT(lpos, gpos)
lineart_chain_append_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
e->flags,
- rls->occlusion,
- rls->transparency_mask,
+ es->occlusion,
+ es->transparency_mask,
e->v1_obindex);
- last_occlusion = rls->occlusion;
- last_transparency = rls->transparency_mask;
+ last_occlusion = es->occlusion;
+ last_transparency = es->transparency_mask;
}
VERT_COORD_TO_FLOAT(e->v2)
lineart_chain_append_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
@@ -359,8 +359,8 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
/* Step 3: grow right. */
ba = MOD_lineart_get_bounding_area(rb, e->v2->fbcoord[0], e->v2->fbcoord[1]);
- new_rv = e->v2;
- while (ba && (new_e = lineart_line_get_connected(ba, new_rv, &new_rv, e->flags))) {
+ new_vt = e->v2;
+ while (ba && (new_e = lineart_line_get_connected(ba, new_vt, &new_vt, e->flags))) {
new_e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
if (new_e->t1 || new_e->t2) {
@@ -379,27 +379,27 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
}
/* Fix leading vertex type. */
- rlci = rlc->chain.last;
- rlci->line_type = new_e->flags & LRT_EDGE_FLAG_ALL_TYPE;
+ eci = ec->chain.last;
+ eci->line_type = new_e->flags & LRT_EDGE_FLAG_ALL_TYPE;
- if (new_rv == new_e->v1) {
- rls = new_e->segments.last;
- last_occlusion = rls->occlusion;
- last_transparency = rls->transparency_mask;
+ if (new_vt == new_e->v1) {
+ es = new_e->segments.last;
+ last_occlusion = es->occlusion;
+ last_transparency = es->transparency_mask;
/* Fix leading vertex occlusion. */
- rlci->occlusion = last_occlusion;
- rlci->transparency_mask = last_transparency;
- for (rls = new_e->segments.last; rls; rls = rls->prev) {
+ eci->occlusion = last_occlusion;
+ eci->transparency_mask = last_transparency;
+ for (es = new_e->segments.last; es; es = es->prev) {
double gpos[3], lpos[3];
double *lfb = new_e->v1->fbcoord, *rfb = new_e->v2->fbcoord;
- double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
- interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, rls->at);
+ double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
+ interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
- last_occlusion = rls->prev ? rls->prev->occlusion : last_occlusion;
- last_transparency = rls->prev ? rls->prev->transparency_mask : last_transparency;
+ last_occlusion = es->prev ? es->prev->occlusion : last_occlusion;
+ last_transparency = es->prev ? es->prev->transparency_mask : last_transparency;
POS_TO_FLOAT(lpos, gpos)
lineart_chain_append_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
@@ -409,35 +409,35 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
new_e->v1_obindex);
}
}
- else if (new_rv == new_e->v2) {
- rls = new_e->segments.first;
- last_occlusion = rls->occlusion;
- last_transparency = rls->transparency_mask;
- rlci->occlusion = last_occlusion;
- rlci->transparency_mask = last_transparency;
- rls = rls->next;
- for (; rls; rls = rls->next) {
+ else if (new_vt == new_e->v2) {
+ es = new_e->segments.first;
+ last_occlusion = es->occlusion;
+ last_transparency = es->transparency_mask;
+ eci->occlusion = last_occlusion;
+ eci->transparency_mask = last_transparency;
+ es = es->next;
+ for (; es; es = es->next) {
double gpos[3], lpos[3];
double *lfb = new_e->v1->fbcoord, *rfb = new_e->v2->fbcoord;
- double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
- interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, rls->at);
+ double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
+ interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
POS_TO_FLOAT(lpos, gpos)
lineart_chain_append_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
new_e->flags,
- rls->occlusion,
- rls->transparency_mask,
+ es->occlusion,
+ es->transparency_mask,
new_e->v2_obindex);
- last_occlusion = rls->occlusion;
- last_transparency = rls->transparency_mask;
+ last_occlusion = es->occlusion;
+ last_transparency = es->transparency_mask;
}
VERT_COORD_TO_FLOAT(new_e->v2)
lineart_chain_append_point(rb,
- rlc,
+ ec,
use_fbcoord,
use_gpos,
N,
@@ -446,57 +446,57 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
last_transparency,
new_e->v2_obindex);
}
- ba = MOD_lineart_get_bounding_area(rb, new_rv->fbcoord[0], new_rv->fbcoord[1]);
+ ba = MOD_lineart_get_bounding_area(rb, new_vt->fbcoord[0], new_vt->fbcoord[1]);
}
if (rb->fuzzy_everything) {
- rlc->type = LRT_EDGE_FLAG_CONTOUR;
+ ec->type = LRT_EDGE_FLAG_CONTOUR;
}
else {
- rlc->type = (e->flags & LRT_EDGE_FLAG_ALL_TYPE);
+ ec->type = (e->flags & LRT_EDGE_FLAG_ALL_TYPE);
}
}
LRT_ITER_ALL_LINES_END
}
-static LineartBoundingArea *lineart_bounding_area_get_rlci_recursive(LineartRenderBuffer *rb,
- LineartBoundingArea *root,
- LineartLineChainItem *rlci)
+static LineartBoundingArea *lineart_bounding_area_get_eci_recursive(LineartRenderBuffer *rb,
+ LineartBoundingArea *root,
+ LineartEdgeChainItem *eci)
{
if (root->child == NULL) {
return root;
}
LineartBoundingArea *ch = root->child;
-#define IN_BOUND(ba, rlci) \
- ba.l <= rlci->pos[0] && ba.r >= rlci->pos[0] && ba.b <= rlci->pos[1] && ba.u >= rlci->pos[1]
+#define IN_BOUND(ba, eci) \
+ ba.l <= eci->pos[0] && ba.r >= eci->pos[0] && ba.b <= eci->pos[1] && ba.u >= eci->pos[1]
- if (IN_BOUND(ch[0], rlci)) {
- return lineart_bounding_area_get_rlci_recursive(rb, &ch[0], rlci);
+ if (IN_BOUND(ch[0], eci)) {
+ return lineart_bounding_area_get_eci_recursive(rb, &ch[0], eci);
}
- if (IN_BOUND(ch[1], rlci)) {
- return lineart_bounding_area_get_rlci_recursive(rb, &ch[1], rlci);
+ if (IN_BOUND(ch[1], eci)) {
+ return lineart_bounding_area_get_eci_recursive(rb, &ch[1], eci);
}
- if (IN_BOUND(ch[2], rlci)) {
- return lineart_bounding_area_get_rlci_recursive(rb, &ch[2], rlci);
+ if (IN_BOUND(ch[2], eci)) {
+ return lineart_bounding_area_get_eci_recursive(rb, &ch[2], eci);
}
- if (IN_BOUND(ch[3], rlci)) {
- return lineart_bounding_area_get_rlci_recursive(rb, &ch[3], rlci);
+ if (IN_BOUND(ch[3], eci)) {
+ return lineart_bounding_area_get_eci_recursive(rb, &ch[3], eci);
}
#undef IN_BOUND
return NULL;
}
static LineartBoundingArea *lineart_bounding_area_get_end_point(LineartRenderBuffer *rb,
- LineartLineChainItem *rlci)
+ LineartEdgeChainItem *eci)
{
- if (!rlci) {
+ if (!eci) {
return NULL;
}
- LineartBoundingArea *root = MOD_lineart_get_parent_bounding_area(rb, rlci->pos[0], rlci->pos[1]);
+ LineartBoundingArea *root = MOD_lineart_get_parent_bounding_area(rb, eci->pos[0], eci->pos[1]);
if (root == NULL) {
return NULL;
}
- return lineart_bounding_area_get_rlci_recursive(rb, root, rlci);
+ return lineart_bounding_area_get_eci_recursive(rb, root, eci);
}
/**
@@ -507,61 +507,61 @@ static LineartBoundingArea *lineart_bounding_area_get_end_point(LineartRenderBuf
*/
static void lineart_bounding_area_link_point_recursive(LineartRenderBuffer *rb,
LineartBoundingArea *root,
- LineartLineChain *rlc,
- LineartLineChainItem *rlci)
+ LineartEdgeChain *ec,
+ LineartEdgeChainItem *eci)
{
if (root->child == NULL) {
LineartChainRegisterEntry *cre = lineart_list_append_pointer_pool_sized(
- &root->linked_chains, &rb->render_data_pool, rlc, sizeof(LineartChainRegisterEntry));
+ &root->linked_chains, &rb->render_data_pool, ec, sizeof(LineartChainRegisterEntry));
- cre->rlci = rlci;
+ cre->eci = eci;
- if (rlci == rlc->chain.first) {
+ if (eci == ec->chain.first) {
cre->is_left = 1;
}
}
else {
LineartBoundingArea *ch = root->child;
-#define IN_BOUND(ba, rlci) \
- ba.l <= rlci->pos[0] && ba.r >= rlci->pos[0] && ba.b <= rlci->pos[1] && ba.u >= rlci->pos[1]
+#define IN_BOUND(ba, eci) \
+ ba.l <= eci->pos[0] && ba.r >= eci->pos[0] && ba.b <= eci->pos[1] && ba.u >= eci->pos[1]
- if (IN_BOUND(ch[0], rlci)) {
- lineart_bounding_area_link_point_recursive(rb, &ch[0], rlc, rlci);
+ if (IN_BOUND(ch[0], eci)) {
+ lineart_bounding_area_link_point_recursive(rb, &ch[0], ec, eci);
}
- else if (IN_BOUND(ch[1], rlci)) {
- lineart_bounding_area_link_point_recursive(rb, &ch[1], rlc, rlci);
+ else if (IN_BOUND(ch[1], eci)) {
+ lineart_bounding_area_link_point_recursive(rb, &ch[1], ec, eci);
}
- else if (IN_BOUND(ch[2], rlci)) {
- lineart_bounding_area_link_point_recursive(rb, &ch[2], rlc, rlci);
+ else if (IN_BOUND(ch[2], eci)) {
+ lineart_bounding_area_link_point_recursive(rb, &ch[2], ec, eci);
}
- else if (IN_BOUND(ch[3], rlci)) {
- lineart_bounding_area_link_point_recursive(rb, &ch[3], rlc, rlci);
+ else if (IN_BOUND(ch[3], eci)) {
+ lineart_bounding_area_link_point_recursive(rb, &ch[3], ec, eci);
}
#undef IN_BOUND
}
}
-static void lineart_bounding_area_link_chain(LineartRenderBuffer *rb, LineartLineChain *rlc)
+static void lineart_bounding_area_link_chain(LineartRenderBuffer *rb, LineartEdgeChain *ec)
{
- LineartLineChainItem *pl = rlc->chain.first;
- LineartLineChainItem *pr = rlc->chain.last;
+ LineartEdgeChainItem *pl = ec->chain.first;
+ LineartEdgeChainItem *pr = ec->chain.last;
LineartBoundingArea *ba1 = MOD_lineart_get_parent_bounding_area(rb, pl->pos[0], pl->pos[1]);
LineartBoundingArea *ba2 = MOD_lineart_get_parent_bounding_area(rb, pr->pos[0], pr->pos[1]);
if (ba1) {
- lineart_bounding_area_link_point_recursive(rb, ba1, rlc, pl);
+ lineart_bounding_area_link_point_recursive(rb, ba1, ec, pl);
}
if (ba2) {
- lineart_bounding_area_link_point_recursive(rb, ba2, rlc, pr);
+ lineart_bounding_area_link_point_recursive(rb, ba2, ec, pr);
}
}
void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
{
- LineartLineChain *rlc, *new_rlc;
- LineartLineChainItem *rlci, *next_rlci;
+ LineartEdgeChain *ec, *new_rlc;
+ LineartEdgeChainItem *eci, *next_rlci;
ListBase swap = {0};
swap.first = rb->chains.first;
@@ -569,59 +569,59 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
rb->chains.last = rb->chains.first = NULL;
- while ((rlc = BLI_pophead(&swap)) != NULL) {
- rlc->next = rlc->prev = NULL;
- BLI_addtail(&rb->chains, rlc);
- LineartLineChainItem *first_rlci = (LineartLineChainItem *)rlc->chain.first;
+ while ((ec = BLI_pophead(&swap)) != NULL) {
+ ec->next = ec->prev = NULL;
+ BLI_addtail(&rb->chains, ec);
+ LineartEdgeChainItem *first_rlci = (LineartEdgeChainItem *)ec->chain.first;
int fixed_occ = first_rlci->occlusion;
unsigned char fixed_mask = first_rlci->transparency_mask;
- rlc->level = fixed_occ;
- rlc->transparency_mask = fixed_mask;
- for (rlci = first_rlci->next; rlci; rlci = next_rlci) {
- next_rlci = rlci->next;
- if (rlci->occlusion != fixed_occ || rlci->transparency_mask != fixed_mask) {
+ ec->level = fixed_occ;
+ ec->transparency_mask = fixed_mask;
+ for (eci = first_rlci->next; eci; eci = next_rlci) {
+ next_rlci = eci->next;
+ if (eci->occlusion != fixed_occ || eci->transparency_mask != fixed_mask) {
if (next_rlci) {
- if (lineart_point_overlapping(next_rlci, rlci->pos[0], rlci->pos[1], 1e-5)) {
+ if (lineart_point_overlapping(next_rlci, eci->pos[0], eci->pos[1], 1e-5)) {
continue;
}
}
else {
/* Set the same occlusion level for the end vertex, so when further connection is needed
* the backwards occlusion info is also correct. */
- rlci->occlusion = fixed_occ;
- rlci->transparency_mask = fixed_mask;
+ eci->occlusion = fixed_occ;
+ eci->transparency_mask = fixed_mask;
/* No need to split at the last point anyway. */
break;
}
new_rlc = lineart_chain_create(rb);
- new_rlc->chain.first = rlci;
- new_rlc->chain.last = rlc->chain.last;
- rlc->chain.last = rlci->prev;
- ((LineartLineChainItem *)rlc->chain.last)->next = 0;
- rlci->prev = 0;
+ new_rlc->chain.first = eci;
+ new_rlc->chain.last = ec->chain.last;
+ ec->chain.last = eci->prev;
+ ((LineartEdgeChainItem *)ec->chain.last)->next = 0;
+ eci->prev = 0;
/* End the previous one. */
lineart_chain_append_point(rb,
- rlc,
- rlci->pos,
- rlci->gpos,
- rlci->normal,
- rlci->line_type,
+ ec,
+ eci->pos,
+ eci->gpos,
+ eci->normal,
+ eci->line_type,
fixed_occ,
fixed_mask,
- rlci->index);
- new_rlc->object_ref = rlc->object_ref;
- new_rlc->type = rlc->type;
- rlc = new_rlc;
- fixed_occ = rlci->occlusion;
- fixed_mask = rlci->transparency_mask;
- rlc->level = fixed_occ;
- rlc->transparency_mask = fixed_mask;
+ eci->index);
+ new_rlc->object_ref = ec->object_ref;
+ new_rlc->type = ec->type;
+ ec = new_rlc;
+ fixed_occ = eci->occlusion;
+ fixed_mask = eci->transparency_mask;
+ ec->level = fixed_occ;
+ ec->transparency_mask = fixed_mask;
}
}
}
- LISTBASE_FOREACH (LineartLineChain *, irlc, &rb->chains) {
- lineart_bounding_area_link_chain(rb, irlc);
+ LISTBASE_FOREACH (LineartEdgeChain *, iec, &rb->chains) {
+ lineart_bounding_area_link_chain(rb, iec);
}
}
@@ -629,12 +629,12 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
* Note: segment type (crease/material/contour...) is ambiguous after this.
*/
static void lineart_chain_connect(LineartRenderBuffer *UNUSED(rb),
- LineartLineChain *onto,
- LineartLineChain *sub,
+ LineartEdgeChain *onto,
+ LineartEdgeChain *sub,
int reverse_1,
int reverse_2)
{
- LineartLineChainItem *rlci;
+ LineartEdgeChainItem *eci;
if (onto->type == LRT_EDGE_FLAG_INTERSECTION) {
if (sub->object_ref) {
onto->object_ref = sub->object_ref;
@@ -650,38 +650,38 @@ static void lineart_chain_connect(LineartRenderBuffer *UNUSED(rb),
if (reverse_2) { /* L--R R-L. */
BLI_listbase_reverse(&sub->chain);
}
- rlci = sub->chain.first;
- if (lineart_point_overlapping(onto->chain.last, rlci->pos[0], rlci->pos[1], 1e-5)) {
+ eci = sub->chain.first;
+ if (lineart_point_overlapping(onto->chain.last, eci->pos[0], eci->pos[1], 1e-5)) {
BLI_pophead(&sub->chain);
if (sub->chain.first == NULL) {
return;
}
}
- ((LineartLineChainItem *)onto->chain.last)->next = sub->chain.first;
- ((LineartLineChainItem *)sub->chain.first)->prev = onto->chain.last;
+ ((LineartEdgeChainItem *)onto->chain.last)->next = sub->chain.first;
+ ((LineartEdgeChainItem *)sub->chain.first)->prev = onto->chain.last;
onto->chain.last = sub->chain.last;
}
else { /* L-R L--R. */
if (!reverse_2) { /* R-L L--R. */
BLI_listbase_reverse(&sub->chain);
}
- rlci = onto->chain.first;
- if (lineart_point_overlapping(sub->chain.last, rlci->pos[0], rlci->pos[1], 1e-5)) {
+ eci = onto->chain.first;
+ if (lineart_point_overlapping(sub->chain.last, eci->pos[0], eci->pos[1], 1e-5)) {
BLI_pophead(&onto->chain);
if (onto->chain.first == NULL) {
return;
}
}
- ((LineartLineChainItem *)sub->chain.last)->next = onto->chain.first;
- ((LineartLineChainItem *)onto->chain.first)->prev = sub->chain.last;
+ ((LineartEdgeChainItem *)sub->chain.last)->next = onto->chain.first;
+ ((LineartEdgeChainItem *)onto->chain.first)->prev = sub->chain.last;
onto->chain.first = sub->chain.first;
}
}
static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuffer *rb,
LineartBoundingArea *ba,
- LineartLineChain *rlc,
- LineartLineChainItem *rlci,
+ LineartEdgeChain *ec,
+ LineartEdgeChainItem *eci,
int occlusion,
unsigned char transparency_mask,
float dist,
@@ -694,12 +694,12 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
/* Keep using for loop because `cre` could be removed from the iteration before getting to the
* next one. */
LISTBASE_FOREACH_MUTABLE (LineartChainRegisterEntry *, cre, &ba->linked_chains) {
- if (cre->rlc->object_ref != rlc->object_ref) {
+ if (cre->ec->object_ref != ec->object_ref) {
if (!rb->fuzzy_everything) {
if (rb->fuzzy_intersections) {
/* If none of those are intersection lines... */
- if ((!(cre->rlc->type & LRT_EDGE_FLAG_INTERSECTION)) &&
- (!(rlc->type & LRT_EDGE_FLAG_INTERSECTION))) {
+ if ((!(cre->ec->type & LRT_EDGE_FLAG_INTERSECTION)) &&
+ (!(ec->type & LRT_EDGE_FLAG_INTERSECTION))) {
continue; /* We don't want to chain along different objects at the moment. */
}
}
@@ -708,18 +708,18 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
}
}
}
- if (cre->rlc->picked || cre->picked) {
+ if (cre->ec->picked || cre->picked) {
continue;
}
- if (cre->rlc == rlc || (!cre->rlc->chain.first) || (cre->rlc->level != occlusion) ||
- (cre->rlc->transparency_mask != transparency_mask)) {
+ if (cre->ec == ec || (!cre->ec->chain.first) || (cre->ec->level != occlusion) ||
+ (cre->ec->transparency_mask != transparency_mask)) {
continue;
}
if (!rb->fuzzy_everything) {
- if (cre->rlc->type != rlc->type) {
+ if (cre->ec->type != ec->type) {
if (rb->fuzzy_intersections) {
- if (!(cre->rlc->type == LRT_EDGE_FLAG_INTERSECTION ||
- rlc->type == LRT_EDGE_FLAG_INTERSECTION)) {
+ if (!(cre->ec->type == LRT_EDGE_FLAG_INTERSECTION ||
+ ec->type == LRT_EDGE_FLAG_INTERSECTION)) {
continue; /* Fuzzy intersections but no intersection line found. */
}
}
@@ -729,7 +729,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
}
}
- float new_len = len_v2v2(cre->rlci->pos, rlci->pos);
+ float new_len = len_v2v2(cre->eci->pos, eci->pos);
if (new_len < dist) {
closest_cre = cre;
dist = new_len;
@@ -748,7 +748,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
LISTBASE_FOREACH (LinkData *, ld, list) { \
LineartBoundingArea *sba = (LineartBoundingArea *)ld->data; \
adjacent_closest = lineart_chain_get_closest_cre( \
- rb, sba, rlc, rlci, occlusion, transparency_mask, dist, &adjacent_new_len, ba); \
+ rb, sba, ec, eci, occlusion, transparency_mask, dist, &adjacent_new_len, ba); \
if (adjacent_new_len < dist) { \
dist = adjacent_new_len; \
closest_cre = adjacent_closest; \
@@ -756,10 +756,10 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
} \
}
if (!caller_ba) {
- LRT_TEST_ADJACENT_AREAS(rlci->pos[0] - ba->l, &ba->lp);
- LRT_TEST_ADJACENT_AREAS(ba->r - rlci->pos[0], &ba->rp);
- LRT_TEST_ADJACENT_AREAS(ba->u - rlci->pos[1], &ba->up);
- LRT_TEST_ADJACENT_AREAS(rlci->pos[1] - ba->b, &ba->bp);
+ LRT_TEST_ADJACENT_AREAS(eci->pos[0] - ba->l, &ba->lp);
+ LRT_TEST_ADJACENT_AREAS(ba->r - eci->pos[0], &ba->rp);
+ LRT_TEST_ADJACENT_AREAS(ba->u - eci->pos[1], &ba->up);
+ LRT_TEST_ADJACENT_AREAS(eci->pos[1] - ba->b, &ba->bp);
}
if (result_new_len) {
(*result_new_len) = dist;
@@ -774,8 +774,8 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
*/
void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
{
- LineartLineChain *rlc;
- LineartLineChainItem *rlci_l, *rlci_r;
+ LineartEdgeChain *ec;
+ LineartEdgeChainItem *rlci_l, *rlci_r;
LineartBoundingArea *ba_l, *ba_r;
LineartChainRegisterEntry *closest_cre_l, *closest_cre_r, *closest_cre;
float dist = rb->chaining_image_threshold;
@@ -793,24 +793,24 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
rb->chains.last = rb->chains.first = NULL;
- while ((rlc = BLI_pophead(&swap)) != NULL) {
- rlc->next = rlc->prev = NULL;
- if (rlc->picked) {
+ while ((ec = BLI_pophead(&swap)) != NULL) {
+ ec->next = ec->prev = NULL;
+ if (ec->picked) {
continue;
}
- BLI_addtail(&rb->chains, rlc);
+ BLI_addtail(&rb->chains, ec);
- occlusion = rlc->level;
- transparency_mask = rlc->transparency_mask;
+ occlusion = ec->level;
+ transparency_mask = ec->transparency_mask;
- rlci_l = rlc->chain.first;
- rlci_r = rlc->chain.last;
+ rlci_l = ec->chain.first;
+ rlci_r = ec->chain.last;
while ((ba_l = lineart_bounding_area_get_end_point(rb, rlci_l)) &&
(ba_r = lineart_bounding_area_get_end_point(rb, rlci_r))) {
closest_cre_l = lineart_chain_get_closest_cre(
- rb, ba_l, rlc, rlci_l, occlusion, transparency_mask, dist, &dist_l, NULL);
+ rb, ba_l, ec, rlci_l, occlusion, transparency_mask, dist, &dist_l, NULL);
closest_cre_r = lineart_chain_get_closest_cre(
- rb, ba_r, rlc, rlci_r, occlusion, transparency_mask, dist, &dist_r, NULL);
+ rb, ba_r, ec, rlci_r, occlusion, transparency_mask, dist, &dist_r, NULL);
if (closest_cre_l && closest_cre_r) {
if (dist_l < dist_r) {
closest_cre = closest_cre_l;
@@ -834,56 +834,56 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
break;
}
closest_cre->picked = 1;
- closest_cre->rlc->picked = 1;
+ closest_cre->ec->picked = 1;
if (closest_cre->is_left) {
- lineart_chain_connect(rb, rlc, closest_cre->rlc, reverse_main, 0);
+ lineart_chain_connect(rb, ec, closest_cre->ec, reverse_main, 0);
}
else {
- lineart_chain_connect(rb, rlc, closest_cre->rlc, reverse_main, 1);
+ lineart_chain_connect(rb, ec, closest_cre->ec, reverse_main, 1);
}
- BLI_remlink(&swap, closest_cre->rlc);
- rlci_l = rlc->chain.first;
- rlci_r = rlc->chain.last;
+ BLI_remlink(&swap, closest_cre->ec);
+ rlci_l = ec->chain.first;
+ rlci_r = ec->chain.last;
}
- rlc->picked = 1;
+ ec->picked = 1;
}
}
/**
* Length is in image space.
*/
-float MOD_lineart_chain_compute_length(LineartLineChain *rlc)
+float MOD_lineart_chain_compute_length(LineartEdgeChain *ec)
{
- LineartLineChainItem *rlci;
+ LineartEdgeChainItem *eci;
float offset_accum = 0;
float dist;
float last_point[2];
- rlci = rlc->chain.first;
- copy_v2_v2(last_point, rlci->pos);
- for (rlci = rlc->chain.first; rlci; rlci = rlci->next) {
- dist = len_v2v2(rlci->pos, last_point);
+ eci = ec->chain.first;
+ copy_v2_v2(last_point, eci->pos);
+ for (eci = ec->chain.first; eci; eci = eci->next) {
+ dist = len_v2v2(eci->pos, last_point);
offset_accum += dist;
- copy_v2_v2(last_point, rlci->pos);
+ copy_v2_v2(last_point, eci->pos);
}
return offset_accum;
}
void MOD_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold)
{
- LineartLineChain *rlc, *next_rlc;
- for (rlc = rb->chains.first; rlc; rlc = next_rlc) {
- next_rlc = rlc->next;
- if (MOD_lineart_chain_compute_length(rlc) < threshold) {
- BLI_remlink(&rb->chains, rlc);
+ LineartEdgeChain *ec, *next_rlc;
+ for (ec = rb->chains.first; ec; ec = next_rlc) {
+ next_rlc = ec->next;
+ if (MOD_lineart_chain_compute_length(ec) < threshold) {
+ BLI_remlink(&rb->chains, ec);
}
}
}
-int MOD_lineart_chain_count(const LineartLineChain *rlc)
+int MOD_lineart_chain_count(const LineartEdgeChain *ec)
{
int count = 0;
- LISTBASE_FOREACH (LineartLineChainItem *, rlci, &rlc->chain) {
+ LISTBASE_FOREACH (LineartEdgeChainItem *, eci, &ec->chain) {
count++;
}
return count;
@@ -894,8 +894,8 @@ void MOD_lineart_chain_clear_picked_flag(LineartRenderBuffer *rb)
if (rb == NULL) {
return;
}
- LISTBASE_FOREACH (LineartLineChain *, rlc, &rb->chains) {
- rlc->picked = 0;
+ LISTBASE_FOREACH (LineartEdgeChain *, ec, &rb->chains) {
+ ec->picked = 0;
}
}
@@ -905,8 +905,8 @@ void MOD_lineart_chain_clear_picked_flag(LineartRenderBuffer *rb)
*/
void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad)
{
- LineartLineChain *rlc, *new_rlc;
- LineartLineChainItem *rlci, *next_rlci, *prev_rlci;
+ LineartEdgeChain *ec, *new_rlc;
+ LineartEdgeChainItem *eci, *next_rlci, *prev_rlci;
ListBase swap = {0};
swap.first = rb->chains.first;
@@ -914,43 +914,43 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol
rb->chains.last = rb->chains.first = NULL;
- while ((rlc = BLI_pophead(&swap)) != NULL) {
- rlc->next = rlc->prev = NULL;
- BLI_addtail(&rb->chains, rlc);
- LineartLineChainItem *first_rlci = (LineartLineChainItem *)rlc->chain.first;
- for (rlci = first_rlci->next; rlci; rlci = next_rlci) {
- next_rlci = rlci->next;
- prev_rlci = rlci->prev;
+ while ((ec = BLI_pophead(&swap)) != NULL) {
+ ec->next = ec->prev = NULL;
+ BLI_addtail(&rb->chains, ec);
+ LineartEdgeChainItem *first_rlci = (LineartEdgeChainItem *)ec->chain.first;
+ for (eci = first_rlci->next; eci; eci = next_rlci) {
+ next_rlci = eci->next;
+ prev_rlci = eci->prev;
float angle = M_PI;
if (next_rlci && prev_rlci) {
- angle = angle_v2v2v2(prev_rlci->pos, rlci->pos, next_rlci->pos);
+ angle = angle_v2v2v2(prev_rlci->pos, eci->pos, next_rlci->pos);
}
else {
break; /* No need to split at the last point anyway.*/
}
if (angle < angle_threshold_rad) {
new_rlc = lineart_chain_create(rb);
- new_rlc->chain.first = rlci;
- new_rlc->chain.last = rlc->chain.last;
- rlc->chain.last = rlci->prev;
- ((LineartLineChainItem *)rlc->chain.last)->next = 0;
- rlci->prev = 0;
+ new_rlc->chain.first = eci;
+ new_rlc->chain.last = ec->chain.last;
+ ec->chain.last = eci->prev;
+ ((LineartEdgeChainItem *)ec->chain.last)->next = 0;
+ eci->prev = 0;
/* End the previous one. */
lineart_chain_append_point(rb,
- rlc,
- rlci->pos,
- rlci->gpos,
- rlci->normal,
- rlci->line_type,
- rlc->level,
- rlci->transparency_mask,
- rlci->index);
- new_rlc->object_ref = rlc->object_ref;
- new_rlc->type = rlc->type;
- new_rlc->level = rlc->level;
- new_rlc->transparency_mask = rlc->transparency_mask;
- rlc = new_rlc;
+ ec,
+ eci->pos,
+ eci->gpos,
+ eci->normal,
+ eci->line_type,
+ ec->level,
+ eci->transparency_mask,
+ eci->index);
+ new_rlc->object_ref = ec->object_ref;
+ new_rlc->type = ec->type;
+ new_rlc->level = ec->level;
+ new_rlc->transparency_mask = ec->transparency_mask;
+ ec = new_rlc;
}
}
}
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 52f7d3652a7..ae8157e1a97 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -63,7 +63,7 @@
static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer *rb,
LineartEdge *e);
-static void lineart_bounding_area_link_line(LineartRenderBuffer *rb,
+static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb,
LineartBoundingArea *root_ba,
LineartEdge *e);
@@ -86,14 +86,14 @@ static bool lineart_get_edge_bounding_areas(LineartRenderBuffer *rb,
static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
LineartBoundingArea *root_ba,
- LineartTriangle *rt,
+ LineartTriangle *tri,
double *LRUB,
int recursive,
int recursive_level,
bool do_intersection);
static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl,
- const LineartTriangle *rt,
+ const LineartTriangle *tri,
const LineartEdge *e,
const double *override_camera_loc,
const bool override_cam_is_persp,
@@ -107,35 +107,35 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl,
static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e);
-static void lineart_discard_segment(LineartRenderBuffer *rb, LineartLineSegment *rls)
+static void lineart_discard_segment(LineartRenderBuffer *rb, LineartEdgeSegment *es)
{
BLI_spin_lock(&rb->lock_cuts);
- memset(rls, 0, sizeof(LineartLineSegment));
+ memset(es, 0, sizeof(LineartEdgeSegment));
/* Storing the node for potentially reuse the memory for new segment data.
* Line Art data is not freed after all calculations are done. */
- BLI_addtail(&rb->wasted_cuts, rls);
+ BLI_addtail(&rb->wasted_cuts, es);
BLI_spin_unlock(&rb->lock_cuts);
}
-static LineartLineSegment *lineart_give_segment(LineartRenderBuffer *rb)
+static LineartEdgeSegment *lineart_give_segment(LineartRenderBuffer *rb)
{
BLI_spin_lock(&rb->lock_cuts);
/* See if there is any already allocated memory we can reuse. */
if (rb->wasted_cuts.first) {
- LineartLineSegment *rls = (LineartLineSegment *)BLI_pophead(&rb->wasted_cuts);
+ LineartEdgeSegment *es = (LineartEdgeSegment *)BLI_pophead(&rb->wasted_cuts);
BLI_spin_unlock(&rb->lock_cuts);
- memset(rls, 0, sizeof(LineartLineSegment));
- return rls;
+ memset(es, 0, sizeof(LineartEdgeSegment));
+ return es;
}
BLI_spin_unlock(&rb->lock_cuts);
/* Otherwise allocate some new memory. */
- return (LineartLineSegment *)lineart_mem_acquire_thread(&rb->render_data_pool,
- sizeof(LineartLineSegment));
+ return (LineartEdgeSegment *)lineart_mem_acquire_thread(&rb->render_data_pool,
+ sizeof(LineartEdgeSegment));
}
/**
@@ -144,9 +144,9 @@ static LineartLineSegment *lineart_give_segment(LineartRenderBuffer *rb)
static void lineart_edge_cut(
LineartRenderBuffer *rb, LineartEdge *e, double start, double end, uchar transparency_mask)
{
- LineartLineSegment *rls, *irls, *next_rls, *prev_rls;
- LineartLineSegment *cut_start_before = 0, *cut_end_before = 0;
- LineartLineSegment *ns = 0, *ns2 = 0;
+ LineartEdgeSegment *es, *ies, *next_es, *prev_es;
+ LineartEdgeSegment *cut_start_before = 0, *cut_end_before = 0;
+ LineartEdgeSegment *ns = 0, *ns2 = 0;
int untouched = 0;
/* If for some reason the occlusion function may give a result that has zero length, or reversed
@@ -173,18 +173,18 @@ static void lineart_edge_cut(
/* Begin looking for starting position of the segment. */
/* Not using a list iteration macro because of it more clear when using for loops to iterate
* through the segments. */
- for (rls = e->segments.first; rls; rls = rls->next) {
- if (LRT_DOUBLE_CLOSE_ENOUGH(rls->at, start)) {
- cut_start_before = rls;
+ for (es = e->segments.first; es; es = es->next) {
+ if (LRT_DOUBLE_CLOSE_ENOUGH(es->at, start)) {
+ cut_start_before = es;
ns = cut_start_before;
break;
}
- if (rls->next == NULL) {
+ if (es->next == NULL) {
break;
}
- irls = rls->next;
- if (irls->at > start + 1e-09 && start > rls->at) {
- cut_start_before = irls;
+ ies = es->next;
+ if (ies->at > start + 1e-09 && start > es->at) {
+ cut_start_before = ies;
ns = lineart_give_segment(rb);
break;
}
@@ -192,25 +192,25 @@ static void lineart_edge_cut(
if (!cut_start_before && LRT_DOUBLE_CLOSE_ENOUGH(1, end)) {
untouched = 1;
}
- for (rls = cut_start_before; rls; rls = rls->next) {
+ for (es = cut_start_before; es; es = es->next) {
/* We tried to cut at existing cutting point (e.g. where the line's occluded by a triangle
* strip). */
- if (LRT_DOUBLE_CLOSE_ENOUGH(rls->at, end)) {
- cut_end_before = rls;
+ if (LRT_DOUBLE_CLOSE_ENOUGH(es->at, end)) {
+ cut_end_before = es;
ns2 = cut_end_before;
break;
}
- /* This check is to prevent `rls->at == 1.0` (where we don't need to cut because we are at the
+ /* This check is to prevent `es->at == 1.0` (where we don't need to cut because we are at the
* end point). */
- if (!rls->next && LRT_DOUBLE_CLOSE_ENOUGH(1, end)) {
- cut_end_before = rls;
+ if (!es->next && LRT_DOUBLE_CLOSE_ENOUGH(1, end)) {
+ cut_end_before = es;
ns2 = cut_end_before;
untouched = 1;
break;
}
/* When an actual cut is needed in the line. */
- if (rls->at > end) {
- cut_end_before = rls;
+ if (es->at > end) {
+ cut_end_before = es;
ns2 = lineart_give_segment(rb);
break;
}
@@ -233,9 +233,9 @@ static void lineart_edge_cut(
if (cut_start_before) {
if (cut_start_before != ns) {
/* Insert cutting points for when a new cut is needed. */
- irls = cut_start_before->prev ? cut_start_before->prev : NULL;
- ns->occlusion = irls ? irls->occlusion : 0;
- ns->transparency_mask = irls->transparency_mask;
+ ies = cut_start_before->prev ? cut_start_before->prev : NULL;
+ ns->occlusion = ies ? ies->occlusion : 0;
+ ns->transparency_mask = ies->transparency_mask;
BLI_insertlinkbefore(&e->segments, cut_start_before, ns);
}
/* Otherwise we already found a existing cutting point, no need to insert a new one. */
@@ -243,24 +243,24 @@ static void lineart_edge_cut(
else {
/* We have yet to reach a existing cutting point even after we searched the whole line, so we
* append the new cut to the end. */
- irls = e->segments.last;
- ns->occlusion = irls->occlusion;
- ns->transparency_mask = irls->transparency_mask;
+ ies = e->segments.last;
+ ns->occlusion = ies->occlusion;
+ ns->transparency_mask = ies->transparency_mask;
BLI_addtail(&e->segments, ns);
}
if (cut_end_before) {
/* The same manipulation as on "cut_start_before". */
if (cut_end_before != ns2) {
- irls = cut_end_before->prev ? cut_end_before->prev : NULL;
- ns2->occlusion = irls ? irls->occlusion : 0;
- ns2->transparency_mask = irls ? irls->transparency_mask : 0;
+ ies = cut_end_before->prev ? cut_end_before->prev : NULL;
+ ns2->occlusion = ies ? ies->occlusion : 0;
+ ns2->transparency_mask = ies ? ies->transparency_mask : 0;
BLI_insertlinkbefore(&e->segments, cut_end_before, ns2);
}
}
else {
- irls = e->segments.last;
- ns2->occlusion = irls->occlusion;
- ns2->transparency_mask = irls->transparency_mask;
+ ies = e->segments.last;
+ ns2->occlusion = ies->occlusion;
+ ns2->transparency_mask = ies->transparency_mask;
BLI_addtail(&e->segments, ns2);
}
@@ -276,29 +276,29 @@ static void lineart_edge_cut(
}
/* Register 1 level of occlusion for all touched segments. */
- for (rls = ns; rls && rls != ns2; rls = rls->next) {
- rls->occlusion++;
- rls->transparency_mask |= transparency_mask;
+ for (es = ns; es && es != ns2; es = es->next) {
+ es->occlusion++;
+ es->transparency_mask |= transparency_mask;
}
/* Reduce adjacent cutting points of the same level, which saves memory. */
char min_occ = 127;
- prev_rls = NULL;
- for (rls = e->segments.first; rls; rls = next_rls) {
- next_rls = rls->next;
+ prev_es = NULL;
+ for (es = e->segments.first; es; es = next_es) {
+ next_es = es->next;
- if (prev_rls && prev_rls->occlusion == rls->occlusion &&
- prev_rls->transparency_mask == rls->transparency_mask) {
- BLI_remlink(&e->segments, rls);
+ if (prev_es && prev_es->occlusion == es->occlusion &&
+ prev_es->transparency_mask == es->transparency_mask) {
+ BLI_remlink(&e->segments, es);
/* This puts the node back to the render buffer, if more cut happens, these unused nodes get
* picked first. */
- lineart_discard_segment(rb, rls);
+ lineart_discard_segment(rb, es);
continue;
}
- min_occ = MIN2(min_occ, rls->occlusion);
+ min_occ = MIN2(min_occ, es->occlusion);
- prev_rls = rls;
+ prev_es = es;
}
e->min_occ = min_occ;
}
@@ -306,12 +306,12 @@ static void lineart_edge_cut(
/**
* To see if given line is connected to an adjacent intersection line.
*/
-BLI_INLINE bool lineart_occlusion_is_adjacent_intersection(LineartEdge *e, LineartTriangle *rt)
+BLI_INLINE bool lineart_occlusion_is_adjacent_intersection(LineartEdge *e, LineartTriangle *tri)
{
LineartVertIntersection *v1 = (void *)e->v1;
LineartVertIntersection *v2 = (void *)e->v2;
- return ((v1->base.flag && v1->intersecting_with == rt) ||
- (v2->base.flag && v2->intersecting_with == rt));
+ return ((v1->base.flag && v1->intersecting_with == tri) ||
+ (v2->base.flag && v2->intersecting_with == tri));
}
static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *e, int thread_id)
@@ -319,7 +319,7 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
double x = e->v1->fbcoord[0], y = e->v1->fbcoord[1];
LineartBoundingArea *ba = lineart_edge_first_bounding_area(rb, e);
LineartBoundingArea *nba = ba;
- LineartTriangleThread *rt;
+ LineartTriangleThread *tri;
/* These values are used for marching along the line. */
double l, r;
@@ -335,15 +335,15 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
while (nba) {
LISTBASE_FOREACH (LinkData *, lip, &nba->linked_triangles) {
- rt = lip->data;
+ tri = lip->data;
/* If we are already testing the line in this thread, then don't do it. */
- if (rt->testing_e[thread_id] == e || (rt->base.flags & LRT_TRIANGLE_INTERSECTION_ONLY) ||
- lineart_occlusion_is_adjacent_intersection(e, (LineartTriangle *)rt)) {
+ if (tri->testing_e[thread_id] == e || (tri->base.flags & LRT_TRIANGLE_INTERSECTION_ONLY) ||
+ lineart_occlusion_is_adjacent_intersection(e, (LineartTriangle *)tri)) {
continue;
}
- rt->testing_e[thread_id] = e;
+ tri->testing_e[thread_id] = e;
if (lineart_triangle_edge_image_space_occlusion(&rb->lock_task,
- (const LineartTriangle *)rt,
+ (const LineartTriangle *)tri,
e,
rb->camera_pos,
rb->cam_is_persp,
@@ -354,7 +354,7 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
rb->shift_y,
&l,
&r)) {
- lineart_edge_cut(rb, e, l, r, rt->base.transparency_mask);
+ lineart_edge_cut(rb, e, l, r, tri->base.transparency_mask);
if (e->min_occ > rb->max_occlusion_level) {
/* No need to calculate any longer on this line because no level more than set value is
* going to show up in the rendered result. */
@@ -376,18 +376,18 @@ static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRend
BLI_spin_lock(&rb->lock_task);
#define LRT_ASSIGN_OCCLUSION_TASK(name) \
- if (rb->name##_managed) { \
- data = rb->name##_managed; \
- rti->name = (void *)data; \
+ if (rb->name.last) { \
+ data = rb->name.last; \
+ rti->name.first = (void *)data; \
for (i = 0; i < LRT_THREAD_EDGE_COUNT && data; i++) { \
data = data->next; \
} \
- rti->name##_end = data; \
- rb->name##_managed = data; \
+ rti->name.last = data; \
+ rb->name.last = data; \
res = 1; \
} \
else { \
- rti->name = NULL; \
+ rti->name.first = rti->name.last = NULL; \
}
LRT_ASSIGN_OCCLUSION_TASK(contour);
@@ -410,23 +410,23 @@ static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartR
while (lineart_occlusion_make_task_info(rb, rti)) {
- for (eip = rti->contour; eip && eip != rti->contour_end; eip = eip->next) {
+ for (eip = rti->contour.first; eip && eip != rti->contour.last; eip = eip->next) {
lineart_occlusion_single_line(rb, eip, rti->thread_id);
}
- for (eip = rti->crease; eip && eip != rti->crease_end; eip = eip->next) {
+ for (eip = rti->crease.first; eip && eip != rti->crease.last; eip = eip->next) {
lineart_occlusion_single_line(rb, eip, rti->thread_id);
}
- for (eip = rti->intersection; eip && eip != rti->intersection_end; eip = eip->next) {
+ for (eip = rti->intersection.first; eip && eip != rti->intersection.last; eip = eip->next) {
lineart_occlusion_single_line(rb, eip, rti->thread_id);
}
- for (eip = rti->material; eip && eip != rti->material_end; eip = eip->next) {
+ for (eip = rti->material.first; eip && eip != rti->material.last; eip = eip->next) {
lineart_occlusion_single_line(rb, eip, rti->thread_id);
}
- for (eip = rti->edge_mark; eip && eip != rti->edge_mark_end; eip = eip->next) {
+ for (eip = rti->edge_mark.first; eip && eip != rti->edge_mark.last; eip = eip->next) {
lineart_occlusion_single_line(rb, eip, rti->thread_id);
}
}
@@ -444,11 +444,13 @@ static void lineart_main_occlusion_begin(LineartRenderBuffer *rb)
"Task Pool");
int i;
- rb->contour_managed = rb->contours;
- rb->crease_managed = rb->crease_lines;
- rb->intersection_managed = rb->intersection_lines;
- rb->material_managed = rb->material_lines;
- rb->edge_mark_managed = rb->edge_marks;
+ /* The "last" entry is used to store worker progress in the whole list.
+ * These list themselves are single-direction linked, with list.first being the head. */
+ rb->contour.last = rb->contour.first;
+ rb->crease.last = rb->crease.first;
+ rb->intersection.last = rb->intersection.first;
+ rb->material.last = rb->material.first;
+ rb->edge_mark.last = rb->edge_mark.first;
TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH);
@@ -678,24 +680,24 @@ static LineartElementLinkNode *lineart_memory_get_edge_space(LineartRenderBuffer
return reln;
}
-static void lineart_triangle_post(LineartTriangle *rt, LineartTriangle *orig)
+static void lineart_triangle_post(LineartTriangle *tri, LineartTriangle *orig)
{
/* Just re-assign normal and set cull flag. */
- copy_v3_v3_db(rt->gn, orig->gn);
- rt->flags = LRT_CULL_GENERATED;
+ copy_v3_v3_db(tri->gn, orig->gn);
+ tri->flags = LRT_CULL_GENERATED;
}
-static void lineart_triangle_set_cull_flag(LineartTriangle *rt, uchar flag)
+static void lineart_triangle_set_cull_flag(LineartTriangle *tri, uchar flag)
{
- uchar intersection_only = (rt->flags & LRT_TRIANGLE_INTERSECTION_ONLY);
- rt->flags = flag;
- rt->flags |= intersection_only;
+ uchar intersection_only = (tri->flags & LRT_TRIANGLE_INTERSECTION_ONLY);
+ tri->flags = flag;
+ tri->flags |= intersection_only;
}
-static bool lineart_edge_match(LineartTriangle *rt, LineartEdge *e, int v1, int v2)
+static bool lineart_edge_match(LineartTriangle *tri, LineartEdge *e, int v1, int v2)
{
- return ((rt->v[v1] == e->v1 && rt->v[v2] == e->v2) ||
- (rt->v[v2] == e->v1 && rt->v[v1] == e->v2));
+ return ((tri->v[v1] == e->v1 && tri->v[v2] == e->v2) ||
+ (tri->v[v2] == e->v1 && tri->v[v1] == e->v2));
}
/**
@@ -703,7 +705,7 @@ static bool lineart_edge_match(LineartTriangle *rt, LineartEdge *e, int v1, int
* reversed by the caller so don't need to implement one in a different direction.
*/
static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
- LineartTriangle *rt,
+ LineartTriangle *tri,
int in0,
int in1,
int in2,
@@ -728,26 +730,26 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
char new_flag = 0;
LineartEdge *new_e, *e, *old_e;
- LineartLineSegment *rls;
- LineartTriangleAdjacent *rta;
+ LineartEdgeSegment *es;
+ LineartTriangleAdjacent *ta;
- if (rt->flags & (LRT_CULL_USED | LRT_CULL_GENERATED | LRT_CULL_DISCARD)) {
+ if (tri->flags & (LRT_CULL_USED | LRT_CULL_GENERATED | LRT_CULL_DISCARD)) {
return;
}
- /* See definition of rt->intersecting_verts and the usage in
+ /* See definition of tri->intersecting_verts and the usage in
* lineart_geometry_object_load() for details. */
- rta = (void *)rt->intersecting_verts;
+ ta = (void *)tri->intersecting_verts;
- LineartVert *rv = &((LineartVert *)v_eln->pointer)[v_count];
- LineartTriangle *rt1 = (void *)(((uchar *)t_eln->pointer) + rb->triangle_size * t_count);
- LineartTriangle *rt2 = (void *)(((uchar *)t_eln->pointer) + rb->triangle_size * (t_count + 1));
+ LineartVert *vt = &((LineartVert *)v_eln->pointer)[v_count];
+ LineartTriangle *tri1 = (void *)(((uchar *)t_eln->pointer) + rb->triangle_size * t_count);
+ LineartTriangle *tri2 = (void *)(((uchar *)t_eln->pointer) + rb->triangle_size * (t_count + 1));
new_e = &((LineartEdge *)e_eln->pointer)[e_count];
- /* Init `rl` to the last `rl` entry. */
+ /* Init `edge` to the last `edge` entry. */
e = new_e;
-#define INCREASE_RL \
+#define INCREASE_EDGE \
e_count++; \
v1_obi = e->v1_obindex; \
v2_obi = e->v2_obindex; \
@@ -755,40 +757,40 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
e = new_e; \
e->v1_obindex = v1_obi; \
e->v2_obindex = v2_obi; \
- rls = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartLineSegment)); \
- BLI_addtail(&e->segments, rls);
+ es = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdgeSegment)); \
+ BLI_addtail(&e->segments, es);
-#define SELECT_RL(e_num, v1_link, v2_link, newrt) \
- if (rta->e[e_num]) { \
- old_e = rta->e[e_num]; \
+#define SELECT_EDGE(e_num, v1_link, v2_link, new_tri) \
+ if (ta->e[e_num]) { \
+ old_e = ta->e[e_num]; \
new_flag = old_e->flags; \
old_e->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
- INCREASE_RL \
+ INCREASE_EDGE \
e->v1 = (v1_link); \
e->v2 = (v2_link); \
e->flags = new_flag; \
e->object_ref = ob; \
- e->t1 = ((old_e->t1 == rt) ? (newrt) : (old_e->t1)); \
- e->t2 = ((old_e->t2 == rt) ? (newrt) : (old_e->t2)); \
+ e->t1 = ((old_e->t1 == tri) ? (new_tri) : (old_e->t1)); \
+ e->t2 = ((old_e->t2 == tri) ? (new_tri) : (old_e->t2)); \
lineart_add_edge_to_list(rb, e); \
}
-#define RELINK_RL(e_num, newrt) \
- if (rta->e[e_num]) { \
- old_e = rta->e[e_num]; \
- old_e->t1 = ((old_e->t1 == rt) ? (newrt) : (old_e->t1)); \
- old_e->t2 = ((old_e->t2 == rt) ? (newrt) : (old_e->t2)); \
+#define RELINK_EDGE(e_num, new_tri) \
+ if (ta->e[e_num]) { \
+ old_e = ta->e[e_num]; \
+ old_e->t1 = ((old_e->t1 == tri) ? (new_tri) : (old_e->t1)); \
+ old_e->t2 = ((old_e->t2 == tri) ? (new_tri) : (old_e->t2)); \
}
-#define REMOVE_TRIANGLE_RL \
- if (rta->e[0]) { \
- rta->e[0]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
+#define REMOVE_TRIANGLE_EDGE \
+ if (ta->e[0]) { \
+ ta->e[0]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
} \
- if (rta->e[1]) { \
- rta->e[1]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
+ if (ta->e[1]) { \
+ ta->e[1]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
} \
- if (rta->e[2]) { \
- rta->e[2]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
+ if (ta->e[2]) { \
+ ta->e[2]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
}
switch (in0 + in1 + in2) {
@@ -797,13 +799,13 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
case 3:
/* Triangle completely behind near plane, throw it away
* also remove render lines form being computed. */
- lineart_triangle_set_cull_flag(rt, LRT_CULL_DISCARD);
- REMOVE_TRIANGLE_RL
+ lineart_triangle_set_cull_flag(tri, LRT_CULL_DISCARD);
+ REMOVE_TRIANGLE_EDGE
return;
case 2:
/* Two points behind near plane, cut those and
* generate 2 new points, 3 lines and 1 triangle. */
- lineart_triangle_set_cull_flag(rt, LRT_CULL_USED);
+ lineart_triangle_set_cull_flag(tri, LRT_CULL_USED);
/**
* (!in0) means "when point 0 is visible".
@@ -828,136 +830,136 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
if (!in0) {
/* Cut point for line 2---|-----0. */
- sub_v3_v3v3_db(vv1, rt->v[0]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[2]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[0]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[2]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
/* Assign it to a new point. */
- interp_v3_v3v3_db(rv[0].gloc, rt->v[0]->gloc, rt->v[2]->gloc, a);
- mul_v4_m4v3_db(rv[0].fbcoord, vp, rv[0].gloc);
- rv[0].index = rt->v[2]->index;
+ interp_v3_v3v3_db(vt[0].gloc, tri->v[0]->gloc, tri->v[2]->gloc, a);
+ mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
+ vt[0].index = tri->v[2]->index;
/* Cut point for line 1---|-----0. */
- sub_v3_v3v3_db(vv1, rt->v[0]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[1]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[0]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[1]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
/* Assign it to another new point. */
- interp_v3_v3v3_db(rv[1].gloc, rt->v[0]->gloc, rt->v[1]->gloc, a);
- mul_v4_m4v3_db(rv[1].fbcoord, vp, rv[1].gloc);
- rv[1].index = rt->v[1]->index;
+ interp_v3_v3v3_db(vt[1].gloc, tri->v[0]->gloc, tri->v[1]->gloc, a);
+ mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
+ vt[1].index = tri->v[1]->index;
/* New line connecting two new points. */
- INCREASE_RL
+ INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_prepend_edge_direct(&rb->contours, e);
+ lineart_prepend_edge_direct(&rb->contour.first, e);
}
/* NOTE: inverting `e->v1/v2` (left/right point) doesn't matter as long as
- * `rt->rl` and `rt->v` has the same sequence. and the winding direction
+ * `tri->edge` and `tri->v` has the same sequence. and the winding direction
* can be either CW or CCW but needs to be consistent throughout the calculation. */
- e->v1 = &rv[1];
- e->v2 = &rv[0];
+ e->v1 = &vt[1];
+ e->v2 = &vt[0];
/* Only one adjacent triangle, because the other side is the near plane. */
/* Use `tl` or `tr` doesn't matter. */
- e->t1 = rt1;
+ e->t1 = tri1;
e->object_ref = ob;
/* New line connecting original point 0 and a new point, only when it's a selected line. */
- SELECT_RL(2, rt->v[0], &rv[0], rt1)
+ SELECT_EDGE(2, tri->v[0], &vt[0], tri1)
/* New line connecting original point 0 and another new point. */
- SELECT_RL(0, rt->v[0], &rv[1], rt1)
+ SELECT_EDGE(0, tri->v[0], &vt[1], tri1)
/* Re-assign triangle point array to two new points. */
- rt1->v[0] = rt->v[0];
- rt1->v[1] = &rv[1];
- rt1->v[2] = &rv[0];
+ tri1->v[0] = tri->v[0];
+ tri1->v[1] = &vt[1];
+ tri1->v[2] = &vt[0];
- lineart_triangle_post(rt1, rt);
+ lineart_triangle_post(tri1, tri);
v_count += 2;
t_count += 1;
}
else if (!in2) {
- sub_v3_v3v3_db(vv1, rt->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[0]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[0].gloc, rt->v[2]->gloc, rt->v[0]->gloc, a);
- mul_v4_m4v3_db(rv[0].fbcoord, vp, rv[0].gloc);
- rv[0].index = rt->v[0]->index;
+ interp_v3_v3v3_db(vt[0].gloc, tri->v[2]->gloc, tri->v[0]->gloc, a);
+ mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
+ vt[0].index = tri->v[0]->index;
- sub_v3_v3v3_db(vv1, rt->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[1]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[1]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[1].gloc, rt->v[2]->gloc, rt->v[1]->gloc, a);
- mul_v4_m4v3_db(rv[1].fbcoord, vp, rv[1].gloc);
- rv[1].index = rt->v[1]->index;
+ interp_v3_v3v3_db(vt[1].gloc, tri->v[2]->gloc, tri->v[1]->gloc, a);
+ mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
+ vt[1].index = tri->v[1]->index;
- INCREASE_RL
+ INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_prepend_edge_direct(&rb->contours, e);
+ lineart_prepend_edge_direct(&rb->contour.first, e);
}
- e->v1 = &rv[0];
- e->v2 = &rv[1];
- e->t1 = rt1;
+ e->v1 = &vt[0];
+ e->v2 = &vt[1];
+ e->t1 = tri1;
e->object_ref = ob;
- SELECT_RL(2, rt->v[2], &rv[0], rt1)
- SELECT_RL(1, rt->v[2], &rv[1], rt1)
+ SELECT_EDGE(2, tri->v[2], &vt[0], tri1)
+ SELECT_EDGE(1, tri->v[2], &vt[1], tri1)
- rt1->v[0] = &rv[0];
- rt1->v[1] = &rv[1];
- rt1->v[2] = rt->v[2];
+ tri1->v[0] = &vt[0];
+ tri1->v[1] = &vt[1];
+ tri1->v[2] = tri->v[2];
- lineart_triangle_post(rt1, rt);
+ lineart_triangle_post(tri1, tri);
v_count += 2;
t_count += 1;
}
else if (!in1) {
- sub_v3_v3v3_db(vv1, rt->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[2]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[2]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[0].gloc, rt->v[1]->gloc, rt->v[2]->gloc, a);
- mul_v4_m4v3_db(rv[0].fbcoord, vp, rv[0].gloc);
- rv[0].index = rt->v[2]->index;
+ interp_v3_v3v3_db(vt[0].gloc, tri->v[1]->gloc, tri->v[2]->gloc, a);
+ mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
+ vt[0].index = tri->v[2]->index;
- sub_v3_v3v3_db(vv1, rt->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[0]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[1].gloc, rt->v[1]->gloc, rt->v[0]->gloc, a);
- mul_v4_m4v3_db(rv[1].fbcoord, vp, rv[1].gloc);
- rv[1].index = rt->v[0]->index;
+ interp_v3_v3v3_db(vt[1].gloc, tri->v[1]->gloc, tri->v[0]->gloc, a);
+ mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
+ vt[1].index = tri->v[0]->index;
- INCREASE_RL
+ INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_prepend_edge_direct(&rb->contours, e);
+ lineart_prepend_edge_direct(&rb->contour.first, e);
}
- e->v1 = &rv[1];
- e->v2 = &rv[0];
- e->t1 = rt1;
+ e->v1 = &vt[1];
+ e->v2 = &vt[0];
+ e->t1 = tri1;
e->object_ref = ob;
- SELECT_RL(1, rt->v[1], &rv[0], rt1)
- SELECT_RL(0, rt->v[1], &rv[1], rt1)
+ SELECT_EDGE(1, tri->v[1], &vt[0], tri1)
+ SELECT_EDGE(0, tri->v[1], &vt[1], tri1)
- rt1->v[0] = &rv[0];
- rt1->v[1] = rt->v[1];
- rt1->v[2] = &rv[1];
+ tri1->v[0] = &vt[0];
+ tri1->v[1] = tri->v[1];
+ tri1->v[2] = &vt[1];
- lineart_triangle_post(rt1, rt);
+ lineart_triangle_post(tri1, tri);
v_count += 2;
t_count += 1;
@@ -966,7 +968,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
case 1:
/* One point behind near plane, cut those and
* generate 2 new points, 4 lines and 2 triangles. */
- lineart_triangle_set_cull_flag(rt, LRT_CULL_USED);
+ lineart_triangle_set_cull_flag(tri, LRT_CULL_USED);
/**
* (in0) means "when point 0 is invisible".
@@ -993,152 +995,152 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
*/
if (in0) {
/* Cut point for line 0---|------1. */
- sub_v3_v3v3_db(vv1, rt->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[0]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot2 / (dot1 + dot2);
/* Assign to a new point. */
- interp_v3_v3v3_db(rv[0].gloc, rt->v[0]->gloc, rt->v[1]->gloc, a);
- mul_v4_m4v3_db(rv[0].fbcoord, vp, rv[0].gloc);
- rv[0].index = rt->v[0]->index;
+ interp_v3_v3v3_db(vt[0].gloc, tri->v[0]->gloc, tri->v[1]->gloc, a);
+ mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
+ vt[0].index = tri->v[0]->index;
/* Cut point for line 0---|------2. */
- sub_v3_v3v3_db(vv1, rt->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[0]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot2 / (dot1 + dot2);
/* Assign to other new point. */
- interp_v3_v3v3_db(rv[1].gloc, rt->v[0]->gloc, rt->v[2]->gloc, a);
- mul_v4_m4v3_db(rv[1].fbcoord, vp, rv[1].gloc);
- rv[1].index = rt->v[0]->index;
+ interp_v3_v3v3_db(vt[1].gloc, tri->v[0]->gloc, tri->v[2]->gloc, a);
+ mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
+ vt[1].index = tri->v[0]->index;
/* New line connects two new points. */
- INCREASE_RL
+ INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_prepend_edge_direct(&rb->contours, e);
+ lineart_prepend_edge_direct(&rb->contour.first, e);
}
- e->v1 = &rv[1];
- e->v2 = &rv[0];
- e->t1 = rt1;
+ e->v1 = &vt[1];
+ e->v2 = &vt[0];
+ e->t1 = tri1;
e->object_ref = ob;
/* New line connects new point 0 and old point 1,
* this is a border line. */
- SELECT_RL(0, rt->v[1], &rv[0], rt1)
- SELECT_RL(2, rt->v[2], &rv[1], rt2)
- RELINK_RL(1, rt2)
+ SELECT_EDGE(0, tri->v[1], &vt[0], tri1)
+ SELECT_EDGE(2, tri->v[2], &vt[1], tri2)
+ RELINK_EDGE(1, tri2)
/* We now have one triangle closed. */
- rt1->v[0] = rt->v[1];
- rt1->v[1] = &rv[1];
- rt1->v[2] = &rv[0];
+ tri1->v[0] = tri->v[1];
+ tri1->v[1] = &vt[1];
+ tri1->v[2] = &vt[0];
/* Close the second triangle. */
- rt2->v[0] = &rv[1];
- rt2->v[1] = rt->v[1];
- rt2->v[2] = rt->v[2];
+ tri2->v[0] = &vt[1];
+ tri2->v[1] = tri->v[1];
+ tri2->v[2] = tri->v[2];
- lineart_triangle_post(rt1, rt);
- lineart_triangle_post(rt2, rt);
+ lineart_triangle_post(tri1, tri);
+ lineart_triangle_post(tri2, tri);
v_count += 2;
t_count += 2;
}
else if (in1) {
- sub_v3_v3v3_db(vv1, rt->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[2]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[2]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[0].gloc, rt->v[1]->gloc, rt->v[2]->gloc, a);
- mul_v4_m4v3_db(rv[0].fbcoord, vp, rv[0].gloc);
- rv[0].index = rt->v[1]->index;
+ interp_v3_v3v3_db(vt[0].gloc, tri->v[1]->gloc, tri->v[2]->gloc, a);
+ mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
+ vt[0].index = tri->v[1]->index;
- sub_v3_v3v3_db(vv1, rt->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[0]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[1].gloc, rt->v[1]->gloc, rt->v[0]->gloc, a);
- mul_v4_m4v3_db(rv[1].fbcoord, vp, rv[1].gloc);
- rv[1].index = rt->v[1]->index;
+ interp_v3_v3v3_db(vt[1].gloc, tri->v[1]->gloc, tri->v[0]->gloc, a);
+ mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
+ vt[1].index = tri->v[1]->index;
- INCREASE_RL
+ INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_prepend_edge_direct(&rb->contours, e);
+ lineart_prepend_edge_direct(&rb->contour.first, e);
}
- e->v1 = &rv[1];
- e->v2 = &rv[0];
- e->t1 = rt1;
+ e->v1 = &vt[1];
+ e->v2 = &vt[0];
+ e->t1 = tri1;
e->object_ref = ob;
- SELECT_RL(1, rt->v[2], &rv[0], rt1)
- SELECT_RL(0, rt->v[0], &rv[1], rt2)
- RELINK_RL(2, rt2)
+ SELECT_EDGE(1, tri->v[2], &vt[0], tri1)
+ SELECT_EDGE(0, tri->v[0], &vt[1], tri2)
+ RELINK_EDGE(2, tri2)
- rt1->v[0] = rt->v[2];
- rt1->v[1] = &rv[1];
- rt1->v[2] = &rv[0];
+ tri1->v[0] = tri->v[2];
+ tri1->v[1] = &vt[1];
+ tri1->v[2] = &vt[0];
- rt2->v[0] = &rv[1];
- rt2->v[1] = rt->v[2];
- rt2->v[2] = rt->v[0];
+ tri2->v[0] = &vt[1];
+ tri2->v[1] = tri->v[2];
+ tri2->v[2] = tri->v[0];
- lineart_triangle_post(rt1, rt);
- lineart_triangle_post(rt2, rt);
+ lineart_triangle_post(tri1, tri);
+ lineart_triangle_post(tri2, tri);
v_count += 2;
t_count += 2;
}
else if (in2) {
- sub_v3_v3v3_db(vv1, rt->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[0]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[0].gloc, rt->v[2]->gloc, rt->v[0]->gloc, a);
- mul_v4_m4v3_db(rv[0].fbcoord, vp, rv[0].gloc);
- rv[0].index = rt->v[2]->index;
+ interp_v3_v3v3_db(vt[0].gloc, tri->v[2]->gloc, tri->v[0]->gloc, a);
+ mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
+ vt[0].index = tri->v[2]->index;
- sub_v3_v3v3_db(vv1, rt->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, rt->v[1]->gloc);
+ sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(vv2, cam_pos, tri->v[1]->gloc);
dot1 = dot_v3v3_db(vv1, view_dir);
dot2 = dot_v3v3_db(vv2, view_dir);
a = dot1 / (dot1 + dot2);
- interp_v3_v3v3_db(rv[1].gloc, rt->v[2]->gloc, rt->v[1]->gloc, a);
- mul_v4_m4v3_db(rv[1].fbcoord, vp, rv[1].gloc);
- rv[1].index = rt->v[2]->index;
+ interp_v3_v3v3_db(vt[1].gloc, tri->v[2]->gloc, tri->v[1]->gloc, a);
+ mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
+ vt[1].index = tri->v[2]->index;
- INCREASE_RL
+ INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_prepend_edge_direct(&rb->contours, e);
+ lineart_prepend_edge_direct(&rb->contour.first, e);
}
- e->v1 = &rv[1];
- e->v2 = &rv[0];
- e->t1 = rt1;
+ e->v1 = &vt[1];
+ e->v2 = &vt[0];
+ e->t1 = tri1;
e->object_ref = ob;
- SELECT_RL(2, rt->v[0], &rv[0], rt1)
- SELECT_RL(1, rt->v[1], &rv[1], rt2)
- RELINK_RL(0, rt2)
+ SELECT_EDGE(2, tri->v[0], &vt[0], tri1)
+ SELECT_EDGE(1, tri->v[1], &vt[1], tri2)
+ RELINK_EDGE(0, tri2)
- rt1->v[0] = rt->v[0];
- rt1->v[1] = &rv[1];
- rt1->v[2] = &rv[0];
+ tri1->v[0] = tri->v[0];
+ tri1->v[1] = &vt[1];
+ tri1->v[2] = &vt[0];
- rt2->v[0] = &rv[1];
- rt2->v[1] = rt->v[0];
- rt2->v[2] = rt->v[1];
+ tri2->v[0] = &vt[1];
+ tri2->v[1] = tri->v[0];
+ tri2->v[2] = tri->v[1];
- lineart_triangle_post(rt1, rt);
- lineart_triangle_post(rt2, rt);
+ lineart_triangle_post(tri1, tri);
+ lineart_triangle_post(tri2, tri);
v_count += 2;
t_count += 2;
@@ -1149,10 +1151,10 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
*r_e_count = e_count;
*r_t_count = t_count;
-#undef INCREASE_RL
-#undef SELECT_RL
-#undef RELINK_RL
-#undef REMOVE_TRIANGLE_RL
+#undef INCREASE_EDGE
+#undef SELECT_EDGE
+#undef RELINK_EDGE
+#undef REMOVE_TRIANGLE_EDGE
}
/**
@@ -1163,7 +1165,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
*/
static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
{
- LineartTriangle *rt;
+ LineartTriangle *tri;
LineartElementLinkNode *v_eln, *t_eln, *e_eln;
double(*vp)[4] = rb->view_projection;
int i;
@@ -1219,25 +1221,25 @@ static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
in0 = 0, in1 = 0, in2 = 0; \
if (clip_far) { \
/* Point outside far plane. */ \
- if (rt->v[0]->fbcoord[use_w] > clip_end) { \
+ if (tri->v[0]->fbcoord[use_w] > clip_end) { \
in0 = 1; \
} \
- if (rt->v[1]->fbcoord[use_w] > clip_end) { \
+ if (tri->v[1]->fbcoord[use_w] > clip_end) { \
in1 = 1; \
} \
- if (rt->v[2]->fbcoord[use_w] > clip_end) { \
+ if (tri->v[2]->fbcoord[use_w] > clip_end) { \
in2 = 1; \
} \
} \
else { \
/* Point inside near plane. */ \
- if (rt->v[0]->fbcoord[use_w] < clip_start) { \
+ if (tri->v[0]->fbcoord[use_w] < clip_start) { \
in0 = 1; \
} \
- if (rt->v[1]->fbcoord[use_w] < clip_start) { \
+ if (tri->v[1]->fbcoord[use_w] < clip_start) { \
in1 = 1; \
} \
- if (rt->v[2]->fbcoord[use_w] < clip_start) { \
+ if (tri->v[2]->fbcoord[use_w] < clip_start) { \
in2 = 1; \
} \
}
@@ -1259,12 +1261,12 @@ static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
ob = reln->object_ref;
for (i = 0; i < reln->element_count; i++) {
/* Select the triangle in the array. */
- rt = (void *)(((uchar *)reln->pointer) + rb->triangle_size * i);
+ tri = (void *)(((uchar *)reln->pointer) + rb->triangle_size * i);
LRT_CULL_DECIDE_INSIDE
LRT_CULL_ENSURE_MEMORY
lineart_triangle_cull_single(rb,
- rt,
+ tri,
in0,
in1,
in2,
@@ -1299,20 +1301,20 @@ static void lineart_main_free_adjacent_data(LineartRenderBuffer *rb)
MEM_freeN(ld->data);
}
LISTBASE_FOREACH (LineartElementLinkNode *, reln, &rb->triangle_buffer_pointers) {
- LineartTriangle *rt = reln->pointer;
+ LineartTriangle *tri = reln->pointer;
int i;
for (i = 0; i < reln->element_count; i++) {
- /* See definition of rt->intersecting_verts and the usage in
+ /* See definition of tri->intersecting_verts and the usage in
* lineart_geometry_object_load() for detailed. */
- rt->intersecting_verts = NULL;
- rt = (LineartTriangle *)(((uchar *)rt) + rb->triangle_size);
+ tri->intersecting_verts = NULL;
+ tri = (LineartTriangle *)(((uchar *)tri) + rb->triangle_size);
}
}
}
static void lineart_main_perspective_division(LineartRenderBuffer *rb)
{
- LineartVert *rv;
+ LineartVert *vt;
int i;
if (!rb->cam_is_persp) {
@@ -1320,18 +1322,18 @@ static void lineart_main_perspective_division(LineartRenderBuffer *rb)
}
LISTBASE_FOREACH (LineartElementLinkNode *, reln, &rb->vertex_buffer_pointers) {
- rv = reln->pointer;
+ vt = reln->pointer;
for (i = 0; i < reln->element_count; i++) {
/* Do not divide Z, we use Z to back transform cut points in later chaining process. */
- rv[i].fbcoord[0] /= rv[i].fbcoord[3];
- rv[i].fbcoord[1] /= rv[i].fbcoord[3];
+ vt[i].fbcoord[0] /= vt[i].fbcoord[3];
+ vt[i].fbcoord[1] /= vt[i].fbcoord[3];
/* Re-map z into (0-1) range, because we no longer need NDC (Normalized Device Coordinates)
* at the moment.
* The algorithm currently doesn't need Z for operation, we use W instead. If Z is needed in
* the future, the line below correctly transforms it to view space coordinates. */
- // `rv[i].fbcoord[2] = -2 * rv[i].fbcoord[2] / (far - near) - (far + near) / (far - near);
- rv[i].fbcoord[0] -= rb->shift_x * 2;
- rv[i].fbcoord[1] -= rb->shift_y * 2;
+ // `vt[i].fbcoord[2] = -2 * vt[i].fbcoord[2] / (far - near) - (far + near) / (far - near);
+ vt[i].fbcoord[0] -= rb->shift_x * 2;
+ vt[i].fbcoord[1] -= rb->shift_y * 2;
}
}
}
@@ -1343,10 +1345,10 @@ static void lineart_vert_transform(
BMVert *v, int index, LineartVert *RvBuf, double (*mv_mat)[4], double (*mvp_mat)[4])
{
double co[4];
- LineartVert *rv = &RvBuf[index];
+ LineartVert *vt = &RvBuf[index];
copy_v3db_v3fl(co, v->co);
- mul_v3_m4v3_db(rv->gloc, mv_mat, co);
- mul_v4_m4v3_db(rv->fbcoord, mvp_mat, co);
+ mul_v3_m4v3_db(vt->gloc, mv_mat, co);
+ mul_v4_m4v3_db(vt->fbcoord, mvp_mat, co);
}
/**
@@ -1381,12 +1383,12 @@ static char lineart_identify_feature_line(LineartRenderBuffer *rb,
return LRT_EDGE_FLAG_CONTOUR;
}
- LineartTriangle *rt1, *rt2;
+ LineartTriangle *tri1, *tri2;
LineartVert *l;
/* The mesh should already be triangulated now, so we can assume each face is a triangle. */
- rt1 = lineart_triangle_from_index(rb, rt_array, BM_elem_index_get(ll->f));
- rt2 = lineart_triangle_from_index(rb, rt_array, BM_elem_index_get(lr->f));
+ tri1 = lineart_triangle_from_index(rb, rt_array, BM_elem_index_get(ll->f));
+ tri2 = lineart_triangle_from_index(rb, rt_array, BM_elem_index_get(lr->f));
l = &rv_array[BM_elem_index_get(e->v1)];
@@ -1403,14 +1405,14 @@ static char lineart_identify_feature_line(LineartRenderBuffer *rb,
view_vector = rb->view_vector;
}
- dot_1 = dot_v3v3_db(view_vector, rt1->gn);
- dot_2 = dot_v3v3_db(view_vector, rt2->gn);
+ dot_1 = dot_v3v3_db(view_vector, tri1->gn);
+ dot_2 = dot_v3v3_db(view_vector, tri2->gn);
if ((result = dot_1 * dot_2) <= 0 && (dot_1 + dot_2)) {
return LRT_EDGE_FLAG_CONTOUR;
}
- if (rb->use_crease && (dot_v3v3_db(rt1->gn, rt2->gn) < crease_threshold)) {
+ if (rb->use_crease && (dot_v3v3_db(tri1->gn, tri2->gn) < crease_threshold)) {
if (!no_crease) {
return LRT_EDGE_FLAG_CREASE;
}
@@ -1431,35 +1433,35 @@ static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e)
{
switch (e->flags) {
case LRT_EDGE_FLAG_CONTOUR:
- lineart_prepend_edge_direct(&rb->contours, e);
+ lineart_prepend_edge_direct(&rb->contour.first, e);
break;
case LRT_EDGE_FLAG_CREASE:
- lineart_prepend_edge_direct(&rb->crease_lines, e);
+ lineart_prepend_edge_direct(&rb->crease.first, e);
break;
case LRT_EDGE_FLAG_MATERIAL:
- lineart_prepend_edge_direct(&rb->material_lines, e);
+ lineart_prepend_edge_direct(&rb->material.first, e);
break;
case LRT_EDGE_FLAG_EDGE_MARK:
- lineart_prepend_edge_direct(&rb->edge_marks, e);
+ lineart_prepend_edge_direct(&rb->edge_mark.first, e);
break;
case LRT_EDGE_FLAG_INTERSECTION:
- lineart_prepend_edge_direct(&rb->intersection_lines, e);
+ lineart_prepend_edge_direct(&rb->intersection.first, e);
break;
}
}
-static void lineart_triangle_adjacent_assign(LineartTriangle *rt,
- LineartTriangleAdjacent *rta,
+static void lineart_triangle_adjacent_assign(LineartTriangle *tri,
+ LineartTriangleAdjacent *ta,
LineartEdge *e)
{
- if (lineart_edge_match(rt, e, 0, 1)) {
- rta->e[0] = e;
+ if (lineart_edge_match(tri, e, 0, 1)) {
+ ta->e[0] = e;
}
- else if (lineart_edge_match(rt, e, 1, 2)) {
- rta->e[1] = e;
+ else if (lineart_edge_match(tri, e, 1, 2)) {
+ ta->e[1] = e;
}
- else if (lineart_edge_match(rt, e, 2, 0)) {
- rta->e[2] = e;
+ else if (lineart_edge_match(tri, e, 2, 0)) {
+ ta->e[2] = e;
}
}
@@ -1477,7 +1479,7 @@ static void lineart_geometry_object_load(Depsgraph *dg,
BMEdge *e;
BMLoop *loop;
LineartEdge *la_e;
- LineartTriangle *rt;
+ LineartTriangle *tri;
LineartTriangleAdjacent *orta;
double new_mvp[4][4], new_mv[4][4], normal[4][4];
float imat[4][4];
@@ -1621,39 +1623,39 @@ static void lineart_geometry_object_load(Depsgraph *dg,
* index to come close together. */
(*global_vindex) += bm->totvert;
- rt = ort;
+ tri = ort;
for (i = 0; i < bm->totface; i++) {
f = BM_face_at_index(bm, i);
loop = f->l_first;
- rt->v[0] = &orv[BM_elem_index_get(loop->v)];
+ tri->v[0] = &orv[BM_elem_index_get(loop->v)];
loop = loop->next;
- rt->v[1] = &orv[BM_elem_index_get(loop->v)];
+ tri->v[1] = &orv[BM_elem_index_get(loop->v)];
loop = loop->next;
- rt->v[2] = &orv[BM_elem_index_get(loop->v)];
+ tri->v[2] = &orv[BM_elem_index_get(loop->v)];
/* Transparency bit assignment. */
Material *mat = BKE_object_material_get(ob, f->mat_nr + 1);
- rt->transparency_mask = ((mat && (mat->lineart.flags & LRT_MATERIAL_TRANSPARENCY_ENABLED)) ?
- mat->lineart.transparency_mask :
- 0);
+ tri->transparency_mask = ((mat && (mat->lineart.flags & LRT_MATERIAL_TRANSPARENCY_ENABLED)) ?
+ mat->lineart.transparency_mask :
+ 0);
double gn[3];
copy_v3db_v3fl(gn, f->no);
- mul_v3_mat3_m4v3_db(rt->gn, normal, gn);
- normalize_v3_db(rt->gn);
+ mul_v3_mat3_m4v3_db(tri->gn, normal, gn);
+ normalize_v3_db(tri->gn);
if (usage == OBJECT_LRT_INTERSECTION_ONLY) {
- rt->flags |= LRT_TRIANGLE_INTERSECTION_ONLY;
+ tri->flags |= LRT_TRIANGLE_INTERSECTION_ONLY;
}
else if (ELEM(usage, OBJECT_LRT_NO_INTERSECTION, OBJECT_LRT_OCCLUSION_ONLY)) {
- rt->flags |= LRT_TRIANGLE_NO_INTERSECTION;
+ tri->flags |= LRT_TRIANGLE_NO_INTERSECTION;
}
/* Re-use this field to refer to adjacent info, will be cleared after culling stage. */
- rt->intersecting_verts = (void *)&orta[i];
+ tri->intersecting_verts = (void *)&orta[i];
- rt = (LineartTriangle *)(((uchar *)rt) + rb->triangle_size);
+ tri = (LineartTriangle *)(((uchar *)tri) + rb->triangle_size);
}
/* Use BM_ELEM_TAG in f->head.hflag to store needed faces in the first iteration. */
@@ -1707,9 +1709,9 @@ static void lineart_geometry_object_load(Depsgraph *dg,
la_e->flags = e->head.hflag;
la_e->object_ref = orig_ob;
- LineartLineSegment *rls = lineart_mem_acquire(&rb->render_data_pool,
- sizeof(LineartLineSegment));
- BLI_addtail(&la_e->segments, rls);
+ LineartEdgeSegment *es = lineart_mem_acquire(&rb->render_data_pool,
+ sizeof(LineartEdgeSegment));
+ BLI_addtail(&la_e->segments, es);
if (ELEM(usage, OBJECT_LRT_INHERIT, OBJECT_LRT_INCLUDE, OBJECT_LRT_NO_INTERSECTION)) {
lineart_add_edge_to_list(rb, la_e);
}
@@ -1875,51 +1877,51 @@ static void lineart_main_load_geometries(
* Returns the two other verts of the triangle given a vertex. Returns false if the given vertex
* doesn't belong to this triangle.
*/
-static bool lineart_triangle_get_other_verts(const LineartTriangle *rt,
- const LineartVert *rv,
+static bool lineart_triangle_get_other_verts(const LineartTriangle *tri,
+ const LineartVert *vt,
LineartVert **l,
LineartVert **r)
{
- if (rt->v[0] == rv) {
- *l = rt->v[1];
- *r = rt->v[2];
+ if (tri->v[0] == vt) {
+ *l = tri->v[1];
+ *r = tri->v[2];
return true;
}
- if (rt->v[1] == rv) {
- *l = rt->v[2];
- *r = rt->v[0];
+ if (tri->v[1] == vt) {
+ *l = tri->v[2];
+ *r = tri->v[0];
return true;
}
- if (rt->v[2] == rv) {
- *l = rt->v[0];
- *r = rt->v[1];
+ if (tri->v[2] == vt) {
+ *l = tri->v[0];
+ *r = tri->v[1];
return true;
}
return false;
}
-static bool lineart_edge_from_triangle(const LineartTriangle *rt,
+static bool lineart_edge_from_triangle(const LineartTriangle *tri,
const LineartEdge *e,
bool allow_overlapping_edges)
{
/* Normally we just determine from the pointer address. */
- if (e->t1 == rt || e->t2 == rt) {
+ if (e->t1 == tri || e->t2 == tri) {
return true;
}
/* If allows overlapping, then we compare the vertex coordinates one by one to determine if one
* edge is from specific triangle. This is slower but can handle edge split cases very well. */
if (allow_overlapping_edges) {
-#define LRT_TRI_SAME_POINT(rt, i, pt) \
- ((LRT_DOUBLE_CLOSE_ENOUGH(rt->v[i]->gloc[0], pt->gloc[0]) && \
- LRT_DOUBLE_CLOSE_ENOUGH(rt->v[i]->gloc[1], pt->gloc[1]) && \
- LRT_DOUBLE_CLOSE_ENOUGH(rt->v[i]->gloc[2], pt->gloc[2])) || \
- (LRT_DOUBLE_CLOSE_ENOUGH(rt->v[i]->gloc[0], pt->gloc[0]) && \
- LRT_DOUBLE_CLOSE_ENOUGH(rt->v[i]->gloc[1], pt->gloc[1]) && \
- LRT_DOUBLE_CLOSE_ENOUGH(rt->v[i]->gloc[2], pt->gloc[2])))
- if ((LRT_TRI_SAME_POINT(rt, 0, e->v1) || LRT_TRI_SAME_POINT(rt, 1, e->v1) ||
- LRT_TRI_SAME_POINT(rt, 2, e->v1)) &&
- (LRT_TRI_SAME_POINT(rt, 0, e->v2) || LRT_TRI_SAME_POINT(rt, 1, e->v2) ||
- LRT_TRI_SAME_POINT(rt, 2, e->v2))) {
+#define LRT_TRI_SAME_POINT(tri, i, pt) \
+ ((LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[0], pt->gloc[0]) && \
+ LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[1], pt->gloc[1]) && \
+ LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[2], pt->gloc[2])) || \
+ (LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[0], pt->gloc[0]) && \
+ LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[1], pt->gloc[1]) && \
+ LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[2], pt->gloc[2])))
+ if ((LRT_TRI_SAME_POINT(tri, 0, e->v1) || LRT_TRI_SAME_POINT(tri, 1, e->v1) ||
+ LRT_TRI_SAME_POINT(tri, 2, e->v1)) &&
+ (LRT_TRI_SAME_POINT(tri, 0, e->v2) || LRT_TRI_SAME_POINT(tri, 1, e->v2) ||
+ LRT_TRI_SAME_POINT(tri, 2, e->v2))) {
return true;
}
#undef LRT_TRI_SAME_POINT
@@ -1961,7 +1963,7 @@ static bool lineart_edge_from_triangle(const LineartTriangle *rt,
* in ratio from `e->v1` to `e->v2`. The line is later cut with these two values.
*/
static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
- const LineartTriangle *rt,
+ const LineartTriangle *tri,
const LineartEdge *e,
const double *override_camera_loc,
const bool override_cam_is_persp,
@@ -1988,8 +1990,8 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
double gloc[4], trans[4];
double cut = -1;
- double *LFBC = e->v1->fbcoord, *RFBC = e->v2->fbcoord, *FBC0 = rt->v[0]->fbcoord,
- *FBC1 = rt->v[1]->fbcoord, *FBC2 = rt->v[2]->fbcoord;
+ double *LFBC = e->v1->fbcoord, *RFBC = e->v2->fbcoord, *FBC0 = tri->v[0]->fbcoord,
+ *FBC1 = tri->v[1]->fbcoord, *FBC2 = tri->v[2]->fbcoord;
/* Overlapping not possible, return early. */
if ((MAX3(FBC0[0], FBC1[0], FBC2[0]) < MIN2(LFBC[0], RFBC[0])) ||
@@ -2001,7 +2003,7 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
}
/* If the the line is one of the edge in the triangle, then it's not occluded. */
- if (lineart_edge_from_triangle(rt, e, allow_overlapping_edges)) {
+ if (lineart_edge_from_triangle(tri, e, allow_overlapping_edges)) {
return false;
}
@@ -2013,8 +2015,8 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
/* Sort the intersection distance. */
INTERSECT_SORT_MIN_TO_MAX_3(is[0], is[1], is[2], order);
- sub_v3_v3v3_db(Lv, e->v1->gloc, rt->v[0]->gloc);
- sub_v3_v3v3_db(Rv, e->v2->gloc, rt->v[0]->gloc);
+ sub_v3_v3v3_db(Lv, e->v1->gloc, tri->v[0]->gloc);
+ sub_v3_v3v3_db(Rv, e->v2->gloc, tri->v[0]->gloc);
copy_v3_v3_db(Cv, camera_dir);
@@ -2025,12 +2027,12 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
copy_v4_v4_db(vd4, override_camera_loc);
}
if (override_cam_is_persp) {
- sub_v3_v3v3_db(Cv, vd4, rt->v[0]->gloc);
+ sub_v3_v3v3_db(Cv, vd4, tri->v[0]->gloc);
}
- dot_l = dot_v3v3_db(Lv, rt->gn);
- dot_r = dot_v3v3_db(Rv, rt->gn);
- dot_f = dot_v3v3_db(Cv, rt->gn);
+ dot_l = dot_v3v3_db(Lv, tri->gn);
+ dot_r = dot_v3v3_db(Rv, tri->gn);
+ dot_f = dot_v3v3_db(Cv, tri->gn);
if (!dot_f) {
return false;
@@ -2271,17 +2273,17 @@ static LineartVert *lineart_triangle_share_point(const LineartTriangle *l,
/**
* To save time and prevent overlapping lines when computing intersection lines.
*/
-static bool lineart_vert_already_intersected_2v(LineartVertIntersection *rv,
+static bool lineart_vert_already_intersected_2v(LineartVertIntersection *vt,
LineartVertIntersection *v1,
LineartVertIntersection *v2)
{
- return ((rv->isec1 == v1->base.index && rv->isec2 == v2->base.index) ||
- (rv->isec2 == v2->base.index && rv->isec1 == v1->base.index));
+ return ((vt->isec1 == v1->base.index && vt->isec2 == v2->base.index) ||
+ (vt->isec2 == v2->base.index && vt->isec1 == v1->base.index));
}
-static void lineart_vert_set_intersection_2v(LineartVert *rv, LineartVert *v1, LineartVert *v2)
+static void lineart_vert_set_intersection_2v(LineartVert *vt, LineartVert *v1, LineartVert *v2)
{
- LineartVertIntersection *irv = (LineartVertIntersection *)rv;
+ LineartVertIntersection *irv = (LineartVertIntersection *)vt;
irv->isec1 = v1->index;
irv->isec2 = v2->index;
}
@@ -2294,7 +2296,7 @@ static void lineart_vert_set_intersection_2v(LineartVert *rv, LineartVert *v1, L
static LineartVert *lineart_triangle_2v_intersection_test(LineartRenderBuffer *rb,
LineartVert *v1,
LineartVert *v2,
- LineartTriangle *rt,
+ LineartTriangle *tri,
LineartTriangle *testing,
LineartVert *last)
{
@@ -2306,11 +2308,11 @@ static LineartVert *lineart_triangle_2v_intersection_test(LineartRenderBuffer *r
LineartVert *l = v1, *r = v2;
for (LinkNode *ln = (void *)testing->intersecting_verts; ln; ln = ln->next) {
- LineartVertIntersection *rv = ln->link;
- if (rv->intersecting_with == rt &&
+ LineartVertIntersection *vt = ln->link;
+ if (vt->intersecting_with == tri &&
lineart_vert_already_intersected_2v(
- rv, (LineartVertIntersection *)l, (LineartVertIntersection *)r)) {
- return (LineartVert *)rv;
+ vt, (LineartVertIntersection *)l, (LineartVertIntersection *)r)) {
+ return (LineartVert *)vt;
}
}
@@ -2360,7 +2362,7 @@ static LineartVert *lineart_triangle_2v_intersection_test(LineartRenderBuffer *r
* Test if two triangles intersect. Generates one intersection line if the check succeeds.
*/
static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
- LineartTriangle *rt,
+ LineartTriangle *tri,
LineartTriangle *testing)
{
LineartVert *v1 = 0, *v2 = 0;
@@ -2379,14 +2381,14 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
ZMax = rb->far_clip;
ZMin = rb->near_clip;
copy_v3_v3_db(cl, rb->camera_pos);
- LineartVert *share = lineart_triangle_share_point(testing, rt);
+ LineartVert *share = lineart_triangle_share_point(testing, tri);
if (share) {
/* If triangles have sharing points like `abc` and `acd`, then we only need to detect `bc`
* against `acd` or `cd` against `abc`. */
LineartVert *new_share;
- lineart_triangle_get_other_verts(rt, share, &sv1, &sv2);
+ lineart_triangle_get_other_verts(tri, share, &sv1, &sv2);
v1 = new_share = lineart_mem_acquire(&rb->render_data_pool, (sizeof(LineartVertIntersection)));
@@ -2394,47 +2396,47 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
copy_v3_v3_db(new_share->gloc, share->gloc);
- v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, rt, testing, 0);
+ v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, tri, testing, 0);
if (v2 == NULL) {
lineart_triangle_get_other_verts(testing, share, &sv1, &sv2);
- v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, testing, rt, 0);
+ v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, testing, tri, 0);
if (v2 == NULL) {
return 0;
}
lineart_prepend_pool(&testing->intersecting_verts, &rb->render_data_pool, new_share);
}
else {
- lineart_prepend_pool(&rt->intersecting_verts, &rb->render_data_pool, new_share);
+ lineart_prepend_pool(&tri->intersecting_verts, &rb->render_data_pool, new_share);
}
}
else {
/* If not sharing any points, then we need to try all the possibilities. */
- E0T = lineart_triangle_2v_intersection_test(rb, rt->v[0], rt->v[1], rt, testing, 0);
+ E0T = lineart_triangle_2v_intersection_test(rb, tri->v[0], tri->v[1], tri, testing, 0);
if (E0T && (!(*next))) {
(*next) = E0T;
- lineart_vert_set_intersection_2v((*next), rt->v[0], rt->v[1]);
+ lineart_vert_set_intersection_2v((*next), tri->v[0], tri->v[1]);
next = &v2;
}
- E1T = lineart_triangle_2v_intersection_test(rb, rt->v[1], rt->v[2], rt, testing, v1);
+ E1T = lineart_triangle_2v_intersection_test(rb, tri->v[1], tri->v[2], tri, testing, v1);
if (E1T && (!(*next))) {
(*next) = E1T;
- lineart_vert_set_intersection_2v((*next), rt->v[1], rt->v[2]);
+ lineart_vert_set_intersection_2v((*next), tri->v[1], tri->v[2]);
next = &v2;
}
if (!(*next)) {
- E2T = lineart_triangle_2v_intersection_test(rb, rt->v[2], rt->v[0], rt, testing, v1);
+ E2T = lineart_triangle_2v_intersection_test(rb, tri->v[2], tri->v[0], tri, testing, v1);
}
if (E2T && (!(*next))) {
(*next) = E2T;
- lineart_vert_set_intersection_2v((*next), rt->v[2], rt->v[0]);
+ lineart_vert_set_intersection_2v((*next), tri->v[2], tri->v[0]);
next = &v2;
}
if (!(*next)) {
TE0 = lineart_triangle_2v_intersection_test(
- rb, testing->v[0], testing->v[1], testing, rt, v1);
+ rb, testing->v[0], testing->v[1], testing, tri, v1);
}
if (TE0 && (!(*next))) {
(*next) = TE0;
@@ -2443,7 +2445,7 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
}
if (!(*next)) {
TE1 = lineart_triangle_2v_intersection_test(
- rb, testing->v[1], testing->v[2], testing, rt, v1);
+ rb, testing->v[1], testing->v[2], testing, tri, v1);
}
if (TE1 && (!(*next))) {
(*next) = TE1;
@@ -2452,7 +2454,7 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
}
if (!(*next)) {
TE2 = lineart_triangle_2v_intersection_test(
- rb, testing->v[2], testing->v[0], testing, rt, v1);
+ rb, testing->v[2], testing->v[0], testing, tri, v1);
}
if (TE2 && (!(*next))) {
(*next) = TE2;
@@ -2484,53 +2486,51 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
v1->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v1->fbcoord[2]) * (ZMax - ZMin));
v2->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v2->fbcoord[2]) * (ZMax - ZMin));
- ((LineartVertIntersection *)v1)->intersecting_with = rt;
+ ((LineartVertIntersection *)v1)->intersecting_with = tri;
((LineartVertIntersection *)v2)->intersecting_with = testing;
result = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge));
result->v1 = v1;
result->v2 = v2;
- result->t1 = rt;
+ result->t1 = tri;
result->t2 = testing;
- LineartLineSegment *rls = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartLineSegment));
- BLI_addtail(&result->segments, rls);
+ LineartEdgeSegment *es = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdgeSegment));
+ BLI_addtail(&result->segments, es);
/* Don't need to OR flags right now, just a type mark. */
result->flags = LRT_EDGE_FLAG_INTERSECTION;
- lineart_prepend_edge_direct(&rb->intersection_lines, result);
+ lineart_prepend_edge_direct(&rb->intersection.first, result);
int r1, r2, c1, c2, row, col;
if (lineart_get_edge_bounding_areas(rb, result, &r1, &r2, &c1, &c2)) {
for (row = r1; row != r2 + 1; row++) {
for (col = c1; col != c2 + 1; col++) {
- lineart_bounding_area_link_line(
+ lineart_bounding_area_link_edge(
rb, &rb->initial_bounding_areas[row * LRT_BA_ROWS + col], result);
}
}
}
- rb->intersection_count++;
-
return result;
}
static void lineart_triangle_intersect_in_bounding_area(LineartRenderBuffer *rb,
- LineartTriangle *rt,
+ LineartTriangle *tri,
LineartBoundingArea *ba)
{
/* Testing_triangle->testing[0] is used to store pairing triangle reference.
* See definition of LineartTriangleThread for more info. */
LineartTriangle *testing_triangle;
- LineartTriangleThread *rtt;
+ LineartTriangleThread *tt;
LinkData *lip, *next_lip;
- double *G0 = rt->v[0]->gloc, *G1 = rt->v[1]->gloc, *G2 = rt->v[2]->gloc;
+ double *G0 = tri->v[0]->gloc, *G1 = tri->v[1]->gloc, *G2 = tri->v[2]->gloc;
/* If this is not the smallest subdiv bounding area.*/
if (ba->child) {
- lineart_triangle_intersect_in_bounding_area(rb, rt, &ba->child[0]);
- lineart_triangle_intersect_in_bounding_area(rb, rt, &ba->child[1]);
- lineart_triangle_intersect_in_bounding_area(rb, rt, &ba->child[2]);
- lineart_triangle_intersect_in_bounding_area(rb, rt, &ba->child[3]);
+ lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[0]);
+ lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[1]);
+ lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[2]);
+ lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[3]);
return;
}
@@ -2538,16 +2538,16 @@ static void lineart_triangle_intersect_in_bounding_area(LineartRenderBuffer *rb,
for (lip = ba->linked_triangles.first; lip; lip = next_lip) {
next_lip = lip->next;
testing_triangle = lip->data;
- rtt = (LineartTriangleThread *)testing_triangle;
+ tt = (LineartTriangleThread *)testing_triangle;
- if (testing_triangle == rt || rtt->testing_e[0] == (LineartEdge *)rt) {
+ if (testing_triangle == tri || tt->testing_e[0] == (LineartEdge *)tri) {
continue;
}
- rtt->testing_e[0] = (LineartEdge *)rt;
+ tt->testing_e[0] = (LineartEdge *)tri;
if ((testing_triangle->flags & LRT_TRIANGLE_NO_INTERSECTION) ||
((testing_triangle->flags & LRT_TRIANGLE_INTERSECTION_ONLY) &&
- (rt->flags & LRT_TRIANGLE_INTERSECTION_ONLY))) {
+ (tri->flags & LRT_TRIANGLE_INTERSECTION_ONLY))) {
continue;
}
@@ -2561,12 +2561,12 @@ static void lineart_triangle_intersect_in_bounding_area(LineartRenderBuffer *rb,
(MAX3(G0[0], G1[0], G2[0]) < MIN3(RG0[0], RG1[0], RG2[0])) ||
(MIN3(G0[1], G1[1], G2[1]) > MAX3(RG0[1], RG1[1], RG2[1])) ||
(MAX3(G0[1], G1[1], G2[1]) < MIN3(RG0[1], RG1[1], RG2[1])) ||
- lineart_triangle_share_edge(rt, testing_triangle)) {
+ lineart_triangle_share_edge(tri, testing_triangle)) {
continue;
}
/* If we do need to compute intersection, then finally do it. */
- lineart_triangle_intersect(rb, rt, testing_triangle);
+ lineart_triangle_intersect(rb, tri, testing_triangle);
}
}
@@ -2598,22 +2598,11 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb)
return;
}
- rb->contour_count = 0;
- rb->contour_managed = NULL;
- rb->intersection_count = 0;
- rb->intersection_managed = NULL;
- rb->material_line_count = 0;
- rb->material_managed = NULL;
- rb->crease_count = 0;
- rb->crease_managed = NULL;
- rb->edge_mark_count = 0;
- rb->edge_mark_managed = NULL;
-
- rb->contours = NULL;
- rb->intersection_lines = NULL;
- rb->crease_lines = NULL;
- rb->material_lines = NULL;
- rb->edge_marks = NULL;
+ memset(&rb->contour, 0, sizeof(ListBase));
+ memset(&rb->crease, 0, sizeof(ListBase));
+ memset(&rb->intersection, 0, sizeof(ListBase));
+ memset(&rb->edge_mark, 0, sizeof(ListBase));
+ memset(&rb->material, 0, sizeof(ListBase));
BLI_listbase_clear(&rb->chains);
BLI_listbase_clear(&rb->wasted_cuts);
@@ -2925,7 +2914,7 @@ static void lineart_bounding_area_split(LineartRenderBuffer *rb,
{
LineartBoundingArea *ba = lineart_mem_acquire(&rb->render_data_pool,
sizeof(LineartBoundingArea) * 4);
- LineartTriangle *rt;
+ LineartTriangle *tri;
LineartEdge *e;
ba[0].l = root->cx;
@@ -2960,35 +2949,35 @@ static void lineart_bounding_area_split(LineartRenderBuffer *rb,
lineart_bounding_areas_connect_new(rb, root);
- while ((rt = lineart_list_pop_pointer_no_free(&root->linked_triangles)) != NULL) {
+ while ((tri = lineart_list_pop_pointer_no_free(&root->linked_triangles)) != NULL) {
LineartBoundingArea *cba = root->child;
double b[4];
- b[0] = MIN3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]);
- b[1] = MAX3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]);
- b[2] = MAX3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]);
- b[3] = MIN3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]);
+ b[0] = MIN3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]);
+ b[1] = MAX3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]);
+ b[2] = MAX3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]);
+ b[3] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]);
if (LRT_BOUND_AREA_CROSSES(b, &cba[0].l)) {
- lineart_bounding_area_link_triangle(rb, &cba[0], rt, b, 0, recursive_level + 1, false);
+ lineart_bounding_area_link_triangle(rb, &cba[0], tri, b, 0, recursive_level + 1, false);
}
if (LRT_BOUND_AREA_CROSSES(b, &cba[1].l)) {
- lineart_bounding_area_link_triangle(rb, &cba[1], rt, b, 0, recursive_level + 1, false);
+ lineart_bounding_area_link_triangle(rb, &cba[1], tri, b, 0, recursive_level + 1, false);
}
if (LRT_BOUND_AREA_CROSSES(b, &cba[2].l)) {
- lineart_bounding_area_link_triangle(rb, &cba[2], rt, b, 0, recursive_level + 1, false);
+ lineart_bounding_area_link_triangle(rb, &cba[2], tri, b, 0, recursive_level + 1, false);
}
if (LRT_BOUND_AREA_CROSSES(b, &cba[3].l)) {
- lineart_bounding_area_link_triangle(rb, &cba[3], rt, b, 0, recursive_level + 1, false);
+ lineart_bounding_area_link_triangle(rb, &cba[3], tri, b, 0, recursive_level + 1, false);
}
}
- while ((e = lineart_list_pop_pointer_no_free(&root->linked_lines)) != NULL) {
- lineart_bounding_area_link_line(rb, root, e);
+ while ((e = lineart_list_pop_pointer_no_free(&root->linked_edges)) != NULL) {
+ lineart_bounding_area_link_edge(rb, root, e);
}
rb->bounding_area_count += 3;
}
-static bool lineart_bounding_area_line_intersect(LineartRenderBuffer *UNUSED(fb),
+static bool lineart_bounding_area_edge_intersect(LineartRenderBuffer *UNUSED(fb),
const double l[2],
const double r[2],
LineartBoundingArea *ba)
@@ -3032,11 +3021,11 @@ static bool lineart_bounding_area_line_intersect(LineartRenderBuffer *UNUSED(fb)
}
static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb,
- LineartTriangle *rt,
+ LineartTriangle *tri,
LineartBoundingArea *ba)
{
double p1[2], p2[2], p3[2], p4[2];
- double *FBC1 = rt->v[0]->fbcoord, *FBC2 = rt->v[1]->fbcoord, *FBC3 = rt->v[2]->fbcoord;
+ double *FBC1 = tri->v[0]->fbcoord, *FBC2 = tri->v[1]->fbcoord, *FBC3 = tri->v[2]->fbcoord;
p3[0] = p1[0] = (double)ba->l;
p2[1] = p1[1] = (double)ba->b;
@@ -3056,9 +3045,9 @@ static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb,
return true;
}
- if ((lineart_bounding_area_line_intersect(fb, FBC1, FBC2, ba)) ||
- (lineart_bounding_area_line_intersect(fb, FBC2, FBC3, ba)) ||
- (lineart_bounding_area_line_intersect(fb, FBC3, FBC1, ba))) {
+ if ((lineart_bounding_area_edge_intersect(fb, FBC1, FBC2, ba)) ||
+ (lineart_bounding_area_edge_intersect(fb, FBC2, FBC3, ba)) ||
+ (lineart_bounding_area_edge_intersect(fb, FBC3, FBC1, ba))) {
return true;
}
@@ -3071,17 +3060,17 @@ static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb,
*/
static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
LineartBoundingArea *root_ba,
- LineartTriangle *rt,
+ LineartTriangle *tri,
double *LRUB,
int recursive,
int recursive_level,
bool do_intersection)
{
- if (!lineart_bounding_area_triangle_intersect(rb, rt, root_ba)) {
+ if (!lineart_bounding_area_triangle_intersect(rb, tri, root_ba)) {
return;
}
if (root_ba->child == NULL) {
- lineart_list_append_pointer_pool(&root_ba->linked_triangles, &rb->render_data_pool, rt);
+ lineart_list_append_pointer_pool(&root_ba->linked_triangles, &rb->render_data_pool, tri);
root_ba->triangle_count++;
/* If splitting doesn't improve triangle separation, then shouldn't allow splitting anymore.
* Here we use recursive limit. This is especially useful in orthographic render,
@@ -3091,7 +3080,7 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
lineart_bounding_area_split(rb, root_ba, recursive_level);
}
if (recursive && do_intersection && rb->use_intersections) {
- lineart_triangle_intersect_in_bounding_area(rb, rt, root_ba);
+ lineart_triangle_intersect_in_bounding_area(rb, tri, root_ba);
}
}
else {
@@ -3099,54 +3088,54 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
double *B1 = LRUB;
double b[4];
if (!LRUB) {
- b[0] = MIN3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]);
- b[1] = MAX3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]);
- b[2] = MAX3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]);
- b[3] = MIN3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]);
+ b[0] = MIN3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]);
+ b[1] = MAX3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]);
+ b[2] = MAX3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]);
+ b[3] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]);
B1 = b;
}
if (LRT_BOUND_AREA_CROSSES(B1, &ba[0].l)) {
lineart_bounding_area_link_triangle(
- rb, &ba[0], rt, B1, recursive, recursive_level + 1, do_intersection);
+ rb, &ba[0], tri, B1, recursive, recursive_level + 1, do_intersection);
}
if (LRT_BOUND_AREA_CROSSES(B1, &ba[1].l)) {
lineart_bounding_area_link_triangle(
- rb, &ba[1], rt, B1, recursive, recursive_level + 1, do_intersection);
+ rb, &ba[1], tri, B1, recursive, recursive_level + 1, do_intersection);
}
if (LRT_BOUND_AREA_CROSSES(B1, &ba[2].l)) {
lineart_bounding_area_link_triangle(
- rb, &ba[2], rt, B1, recursive, recursive_level + 1, do_intersection);
+ rb, &ba[2], tri, B1, recursive, recursive_level + 1, do_intersection);
}
if (LRT_BOUND_AREA_CROSSES(B1, &ba[3].l)) {
lineart_bounding_area_link_triangle(
- rb, &ba[3], rt, B1, recursive, recursive_level + 1, do_intersection);
+ rb, &ba[3], tri, B1, recursive, recursive_level + 1, do_intersection);
}
}
}
-static void lineart_bounding_area_link_line(LineartRenderBuffer *rb,
+static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb,
LineartBoundingArea *root_ba,
LineartEdge *e)
{
if (root_ba->child == NULL) {
- lineart_list_append_pointer_pool(&root_ba->linked_lines, &rb->render_data_pool, e);
+ lineart_list_append_pointer_pool(&root_ba->linked_edges, &rb->render_data_pool, e);
}
else {
- if (lineart_bounding_area_line_intersect(
+ if (lineart_bounding_area_edge_intersect(
rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[0])) {
- lineart_bounding_area_link_line(rb, &root_ba->child[0], e);
+ lineart_bounding_area_link_edge(rb, &root_ba->child[0], e);
}
- if (lineart_bounding_area_line_intersect(
+ if (lineart_bounding_area_edge_intersect(
rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[1])) {
- lineart_bounding_area_link_line(rb, &root_ba->child[1], e);
+ lineart_bounding_area_link_edge(rb, &root_ba->child[1], e);
}
- if (lineart_bounding_area_line_intersect(
+ if (lineart_bounding_area_edge_intersect(
rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[2])) {
- lineart_bounding_area_link_line(rb, &root_ba->child[2], e);
+ lineart_bounding_area_link_edge(rb, &root_ba->child[2], e);
}
- if (lineart_bounding_area_line_intersect(
+ if (lineart_bounding_area_edge_intersect(
rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[3])) {
- lineart_bounding_area_link_line(rb, &root_ba->child[3], e);
+ lineart_bounding_area_link_edge(rb, &root_ba->child[3], e);
}
}
}
@@ -3162,7 +3151,7 @@ static void lineart_main_link_lines(LineartRenderBuffer *rb)
if (lineart_get_edge_bounding_areas(rb, e, &r1, &r2, &c1, &c2)) {
for (row = r1; row != r2 + 1; row++) {
for (col = c1; col != c2 + 1; col++) {
- lineart_bounding_area_link_line(
+ lineart_bounding_area_link_edge(
rb, &rb->initial_bounding_areas[row * LRT_BA_ROWS + col], e);
}
}
@@ -3172,7 +3161,7 @@ static void lineart_main_link_lines(LineartRenderBuffer *rb)
}
static bool lineart_get_triangle_bounding_areas(LineartRenderBuffer *rb,
- LineartTriangle *rt,
+ LineartTriangle *tri,
int *rowbegin,
int *rowend,
int *colbegin,
@@ -3181,14 +3170,14 @@ static bool lineart_get_triangle_bounding_areas(LineartRenderBuffer *rb,
double sp_w = rb->width_per_tile, sp_h = rb->height_per_tile;
double b[4];
- if (!rt->v[0] || !rt->v[1] || !rt->v[2]) {
+ if (!tri->v[0] || !tri->v[1] || !tri->v[2]) {
return false;
}
- b[0] = MIN3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]);
- b[1] = MAX3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]);
- b[2] = MIN3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]);
- b[3] = MAX3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]);
+ b[0] = MIN3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]);
+ b[1] = MAX3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]);
+ b[2] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]);
+ b[3] = MAX3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]);
if (b[0] > 1 || b[1] < -1 || b[2] > 1 || b[3] < -1) {
return false;
@@ -3355,33 +3344,33 @@ LineartBoundingArea *MOD_lineart_get_bounding_area(LineartRenderBuffer *rb, doub
*/
static void lineart_main_add_triangles(LineartRenderBuffer *rb)
{
- LineartTriangle *rt;
+ LineartTriangle *tri;
int i, lim;
int x1, x2, y1, y2;
int r, co;
LISTBASE_FOREACH (LineartElementLinkNode *, reln, &rb->triangle_buffer_pointers) {
- rt = reln->pointer;
+ tri = reln->pointer;
lim = reln->element_count;
for (i = 0; i < lim; i++) {
- if ((rt->flags & LRT_CULL_USED) || (rt->flags & LRT_CULL_DISCARD)) {
- rt = (void *)(((uchar *)rt) + rb->triangle_size);
+ if ((tri->flags & LRT_CULL_USED) || (tri->flags & LRT_CULL_DISCARD)) {
+ tri = (void *)(((uchar *)tri) + rb->triangle_size);
continue;
}
- if (lineart_get_triangle_bounding_areas(rb, rt, &y1, &y2, &x1, &x2)) {
+ if (lineart_get_triangle_bounding_areas(rb, tri, &y1, &y2, &x1, &x2)) {
for (co = x1; co <= x2; co++) {
for (r = y1; r <= y2; r++) {
lineart_bounding_area_link_triangle(rb,
&rb->initial_bounding_areas[r * LRT_BA_ROWS + co],
- rt,
+ tri,
0,
1,
0,
- (!(rt->flags & LRT_TRIANGLE_NO_INTERSECTION)));
+ (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)));
}
}
} /* Else throw away. */
- rt = (void *)(((uchar *)rt) + rb->triangle_size);
+ tri = (void *)(((uchar *)tri) + rb->triangle_size);
}
}
}
@@ -3656,6 +3645,8 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModif
Scene *scene = DEG_get_evaluated_scene(depsgraph);
int intersections_only = 0; /* Not used right now, but preserve for future. */
+ BKE_scene_camera_switch_update(scene);
+
if (!scene->camera) {
return false;
}
@@ -3815,52 +3806,52 @@ static void lineart_gpencil_generate(LineartRenderBuffer *rb,
bool invert_input = modifier_flags & LRT_GPENCIL_INVERT_SOURCE_VGROUP;
bool match_output = modifier_flags & LRT_GPENCIL_MATCH_OUTPUT_VGROUP;
- LISTBASE_FOREACH (LineartLineChain *, rlc, &rb->chains) {
+ LISTBASE_FOREACH (LineartEdgeChain *, ec, &rb->chains) {
- if (rlc->picked) {
+ if (ec->picked) {
continue;
}
- if (!(rlc->type & (types & enabled_types))) {
+ if (!(ec->type & (types & enabled_types))) {
continue;
}
- if (rlc->level > level_end || rlc->level < level_start) {
+ if (ec->level > level_end || ec->level < level_start) {
continue;
}
- if (orig_ob && orig_ob != rlc->object_ref) {
+ if (orig_ob && orig_ob != ec->object_ref) {
continue;
}
- if (orig_col && rlc->object_ref) {
- if (!BKE_collection_has_object_recursive_instanced(orig_col, (Object *)rlc->object_ref)) {
+ if (orig_col && ec->object_ref) {
+ if (!BKE_collection_has_object_recursive_instanced(orig_col, (Object *)ec->object_ref)) {
continue;
}
}
if (transparency_flags & LRT_GPENCIL_TRANSPARENCY_ENABLE) {
if (transparency_flags & LRT_GPENCIL_TRANSPARENCY_MATCH) {
- if (rlc->transparency_mask != transparency_mask) {
+ if (ec->transparency_mask != transparency_mask) {
continue;
}
}
else {
- if (!(rlc->transparency_mask & transparency_mask)) {
+ if (!(ec->transparency_mask & transparency_mask)) {
continue;
}
}
}
/* Preserved: If we ever do asynchronous generation, this picked flag should be set here. */
- // rlc->picked = 1;
+ // ec->picked = 1;
int array_idx = 0;
- int count = MOD_lineart_chain_count(rlc);
+ int count = MOD_lineart_chain_count(ec);
bGPDstroke *gps = BKE_gpencil_stroke_add(gpf, color_idx, count, thickness, false);
float *stroke_data = MEM_callocN(sizeof(float) * count * GP_PRIM_DATABUF_SIZE,
"line art add stroke");
- LISTBASE_FOREACH (LineartLineChainItem *, rlci, &rlc->chain) {
- stroke_data[array_idx] = rlci->gpos[0];
- stroke_data[array_idx + 1] = rlci->gpos[1];
- stroke_data[array_idx + 2] = rlci->gpos[2];
+ LISTBASE_FOREACH (LineartEdgeChainItem *, eci, &ec->chain) {
+ stroke_data[array_idx] = eci->gpos[0];
+ stroke_data[array_idx + 1] = eci->gpos[1];
+ stroke_data[array_idx + 2] = eci->gpos[2];
mul_m4_v3(gp_obmat_inverse, &stroke_data[array_idx]);
stroke_data[array_idx + 3] = 1; /* thickness. */
stroke_data[array_idx + 4] = opacity; /* hardness?. */
@@ -3874,7 +3865,7 @@ static void lineart_gpencil_generate(LineartRenderBuffer *rb,
MEM_freeN(stroke_data);
if (source_vgname && vgname) {
- Object *eval_ob = DEG_get_evaluated_object(depsgraph, rlc->object_ref);
+ Object *eval_ob = DEG_get_evaluated_object(depsgraph, ec->object_ref);
int gpdg = -1;
if ((match_output || (gpdg = BKE_object_defgroup_name_index(gpencil_object, vgname)) >= 0)) {
if (eval_ob && eval_ob->type == OB_MESH) {
@@ -3890,8 +3881,8 @@ static void lineart_gpencil_generate(LineartRenderBuffer *rb,
}
}
int sindex = 0, vindex;
- LISTBASE_FOREACH (LineartLineChainItem *, rlci, &rlc->chain) {
- vindex = rlci->index;
+ LISTBASE_FOREACH (LineartEdgeChainItem *, eci, &ec->chain) {
+ vindex = eci->index;
if (vindex >= me->totvert) {
break;
}
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
index 47ca6e45bd5..9ed98b38f07 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
@@ -58,7 +58,7 @@ void *lineart_mem_acquire(struct LineartStaticMemPool *smp, size_t size);
void *lineart_mem_acquire_thread(struct LineartStaticMemPool *smp, size_t size);
void lineart_mem_destroy(struct LineartStaticMemPool *smp);
-void lineart_prepend_edge_direct(struct LineartEdge **first, void *node);
+void lineart_prepend_edge_direct(void **list_head, void *node);
void lineart_prepend_pool(LinkNode **first, struct LineartStaticMemPool *smp, void *link);
void lineart_matrix_ortho_44d(double (*mProjection)[4],
@@ -76,29 +76,42 @@ int lineart_count_intersection_segment_count(struct LineartRenderBuffer *rb);
void lineart_count_and_print_render_buffer_memory(struct LineartRenderBuffer *rb);
#define LRT_ITER_ALL_LINES_BEGIN \
- LineartEdge *e, *next_e, **current_list; \
- e = rb->contours; \
- for (current_list = &rb->contours; e; e = next_e) { \
+ LineartEdge *e, *next_e; \
+ void **current_head; \
+ e = rb->contour.first; \
+ if (!e) { \
+ e = rb->crease.first; \
+ } \
+ if (!e) { \
+ e = rb->material.first; \
+ } \
+ if (!e) { \
+ e = rb->edge_mark.first; \
+ } \
+ if (!e) { \
+ e = rb->intersection.first; \
+ } \
+ for (current_head = &rb->contour.first; e; e = next_e) { \
next_e = e->next;
#define LRT_ITER_ALL_LINES_NEXT \
while (!next_e) { \
- if (current_list == &rb->contours) { \
- current_list = &rb->crease_lines; \
+ if (current_head == &rb->contour.first) { \
+ current_head = &rb->crease.first; \
} \
- else if (current_list == &rb->crease_lines) { \
- current_list = &rb->material_lines; \
+ else if (current_head == &rb->crease.first) { \
+ current_head = &rb->material.first; \
} \
- else if (current_list == &rb->material_lines) { \
- current_list = &rb->edge_marks; \
+ else if (current_head == &rb->material.first) { \
+ current_head = &rb->edge_mark.first; \
} \
- else if (current_list == &rb->edge_marks) { \
- current_list = &rb->intersection_lines; \
+ else if (current_head == &rb->edge_mark.first) { \
+ current_head = &rb->intersection.first; \
} \
else { \
break; \
} \
- next_e = *current_list; \
+ next_e = *current_head; \
}
#define LRT_ITER_ALL_LINES_END \
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c
index dcb1f9cde5d..d05f931f75d 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c
@@ -135,11 +135,11 @@ void lineart_mem_destroy(LineartStaticMemPool *smp)
}
}
-void lineart_prepend_edge_direct(LineartEdge **first, void *node)
+void lineart_prepend_edge_direct(void **list_head, void *node)
{
LineartEdge *e_n = (LineartEdge *)node;
- e_n->next = (*first);
- (*first) = e_n;
+ e_n->next = (*list_head);
+ (*list_head) = e_n;
}
void lineart_prepend_pool(LinkNode **first, LineartStaticMemPool *smp, void *link)
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc
index e79a2bc98ff..a2c1b8f5af6 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc
@@ -41,6 +41,7 @@
#include "BKE_gpencil_geom.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_scene.h"
#include "UI_view2d.h"
@@ -69,18 +70,21 @@ GpencilIO::GpencilIO(const GpencilIOParams *iparams)
cfra_ = iparams->frame_cur;
/* Calculate camera matrix. */
- prepare_camera_params(iparams);
+ prepare_camera_params(scene_, iparams);
}
-void GpencilIO::prepare_camera_params(const GpencilIOParams *iparams)
+void GpencilIO::prepare_camera_params(Scene *scene, const GpencilIOParams *iparams)
{
params_ = *iparams;
const bool is_pdf = params_.mode == GP_EXPORT_TO_PDF;
const bool any_camera = (params_.v3d->camera != nullptr);
const bool force_camera_view = is_pdf && any_camera;
+ /* Ensure camera switch is applied. */
+ BKE_scene_camera_switch_update(scene);
+
/* Calculate camera matrix. */
- Object *cam_ob = params_.v3d->camera;
+ Object *cam_ob = scene->camera;
if (cam_ob != nullptr) {
/* Set up parameters. */
CameraParams params;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.hh b/source/blender/io/gpencil/intern/gpencil_io_base.hh
index 2e1e1707c78..c3c6f1156bb 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh
@@ -50,7 +50,7 @@ class GpencilIO {
GpencilIO(const GpencilIOParams *iparams);
void frame_number_set(const int value);
- void prepare_camera_params(const GpencilIOParams *iparams);
+ void prepare_camera_params(Scene *scene, const GpencilIOParams *iparams);
protected:
GpencilIOParams params_;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_capi.cc b/source/blender/io/gpencil/intern/gpencil_io_capi.cc
index 8093ec3c52d..544c51e0b4f 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_capi.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_capi.cc
@@ -121,7 +121,7 @@ static bool gpencil_io_export_pdf(Depsgraph *depsgraph,
CFRA = i;
BKE_scene_graph_update_for_newframe(depsgraph);
- exporter->prepare_camera_params(iparams);
+ exporter->prepare_camera_params(scene, iparams);
exporter->frame_number_set(i);
exporter->add_newpage();
exporter->add_body();
@@ -130,10 +130,11 @@ static bool gpencil_io_export_pdf(Depsgraph *depsgraph,
/* Back to original frame. */
exporter->frame_number_set(iparams->frame_cur);
CFRA = iparams->frame_cur;
+ BKE_scene_camera_switch_update(scene);
BKE_scene_graph_update_for_newframe(depsgraph);
}
else {
- exporter->prepare_camera_params(iparams);
+ exporter->prepare_camera_params(scene, iparams);
exporter->add_newpage();
exporter->add_body();
result = exporter->write();
@@ -146,6 +147,7 @@ static bool gpencil_io_export_pdf(Depsgraph *depsgraph,
/* Export current frame in SVG. */
#ifdef WITH_PUGIXML
static bool gpencil_io_export_frame_svg(GpencilExporterSVG *exporter,
+ Scene *scene,
const GpencilIOParams *iparams,
const bool newpage,
const bool body,
@@ -153,7 +155,7 @@ static bool gpencil_io_export_frame_svg(GpencilExporterSVG *exporter,
{
bool result = false;
exporter->frame_number_set(iparams->frame_cur);
- exporter->prepare_camera_params(iparams);
+ exporter->prepare_camera_params(scene, iparams);
if (newpage) {
result |= exporter->add_newpage();
@@ -189,7 +191,7 @@ bool gpencil_io_export(const char *filename, GpencilIOParams *iparams)
#ifdef WITH_PUGIXML
case GP_EXPORT_TO_SVG: {
GpencilExporterSVG exporter = GpencilExporterSVG(filename, iparams);
- return gpencil_io_export_frame_svg(&exporter, iparams, true, true, true);
+ return gpencil_io_export_frame_svg(&exporter, scene_, iparams, true, true, true);
break;
}
#endif
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 63375bca575..6655e5a17ad 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -112,6 +112,8 @@ typedef enum eGPDspoint_Flag {
GP_SPOINT_TAG = (1 << 1),
/* stroke point is temp tagged (for some editing operation) */
GP_SPOINT_TEMP_TAG = (1 << 2),
+ /* stroke point is temp tagged (for some editing operation) */
+ GP_SPOINT_TEMP_TAG2 = (1 << 3),
} eGPSPoint_Flag;
/* ***************************************** */
diff --git a/source/blender/makesdna/DNA_view3d_defaults.h b/source/blender/makesdna/DNA_view3d_defaults.h
index 10d0bafec61..9dfc37e57b1 100644
--- a/source/blender/makesdna/DNA_view3d_defaults.h
+++ b/source/blender/makesdna/DNA_view3d_defaults.h
@@ -70,6 +70,7 @@
\
.gpencil_paper_opacity = 0.5f, \
.gpencil_grid_opacity = 0.9f, \
+ .gpencil_vertex_paint_opacity = 1.0f, \
}
#define _DNA_DEFAULT_View3DCursor \
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 5c0691f0320..2818f251085 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -1137,7 +1137,7 @@ static void rna_ImagePreview_icon_reload(PreviewImage *prv)
static PointerRNA rna_IDPreview_get(PointerRNA *ptr)
{
ID *id = (ID *)ptr->data;
- PreviewImage *prv_img = BKE_previewimg_id_ensure(id);
+ PreviewImage *prv_img = BKE_previewimg_id_get(id);
return rna_pointer_inherit_refine(ptr, &RNA_ImagePreview, prv_img);
}
@@ -1707,12 +1707,12 @@ static void rna_def_ID(BlenderRNA *brna)
srna, "override_library", "IDOverrideLibrary", "Library Override", "Library override data");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- prop = RNA_def_pointer(
- srna,
- "preview",
- "ImagePreview",
- "Preview",
- "Preview image and icon of this data-block (None if not supported for this type of data)");
+ prop = RNA_def_pointer(srna,
+ "preview",
+ "ImagePreview",
+ "Preview",
+ "Preview image and icon of this data-block (always None if not supported "
+ "for this type of data)");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_pointer_funcs(prop, "rna_IDPreview_get", NULL, NULL, NULL);
@@ -1826,6 +1826,13 @@ static void rna_def_ID(BlenderRNA *brna)
"e.g. when calling :class:`bpy.types.Scene.update`");
RNA_def_enum_flag(func, "refresh", update_flag_items, 0, "", "Type of updates to perform");
+ func = RNA_def_function(srna, "preview_ensure", "BKE_previewimg_id_ensure");
+ RNA_def_function_ui_description(func,
+ "Ensure that this ID has preview data (if ID type supports it)");
+ parm = RNA_def_pointer(
+ func, "preview_image", "ImagePreview", "", "The existing or created preview");
+ RNA_def_function_return(func, parm);
+
# ifdef WITH_PYTHON
RNA_def_struct_register_funcs(srna, NULL, NULL, "rna_ID_instance");
# endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index c2512ea33ae..11f5ff0441a 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1423,6 +1423,7 @@ static void rna_NodeTree_socket_remove(bNodeTree *ntree,
ntreeRemoveSocketInterface(ntree, sock);
ntreeUpdateTree(bmain, ntree);
+ DEG_id_tag_update(&ntree->id, 0);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 1dc7519258b..b339682222c 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1502,11 +1502,6 @@ static PointerRNA rna_Object_field_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
- /* weak */
- if (!ob->pd) {
- ob->pd = BKE_partdeflect_new(0);
- }
-
return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, ob->pd);
}
@@ -1518,11 +1513,6 @@ static PointerRNA rna_Object_collision_get(PointerRNA *ptr)
return PointerRNA_NULL;
}
- /* weak */
- if (!ob->pd) {
- ob->pd = BKE_partdeflect_new(0);
- }
-
return rna_pointer_inherit_refine(ptr, &RNA_CollisionSettings, ob->pd);
}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index d94e68a6808..7ff2a82a465 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -1413,24 +1413,12 @@ static const EnumPropertyItem *rna_Particle_ren_as_itemf(bContext *UNUSED(C),
static PointerRNA rna_Particle_field1_get(PointerRNA *ptr)
{
ParticleSettings *part = (ParticleSettings *)ptr->owner_id;
-
- /* weak */
- if (!part->pd) {
- part->pd = BKE_partdeflect_new(0);
- }
-
return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd);
}
static PointerRNA rna_Particle_field2_get(PointerRNA *ptr)
{
ParticleSettings *part = (ParticleSettings *)ptr->owner_id;
-
- /* weak */
- if (!part->pd2) {
- part->pd2 = BKE_partdeflect_new(0);
- }
-
return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd2);
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index aa07ff4006a..d744f67c6f6 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -4492,7 +4492,6 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
prop = RNA_def_property(srna, "gpencil_vertex_paint_opacity", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "overlay.gpencil_vertex_paint_opacity");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Opacity", "Vertex Paint mix factor");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPencil_update");
}
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index ac5249b40a2..a5c6d0abce0 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -175,7 +175,7 @@ enum class NodeScheduleState {
struct NodeState {
/**
- * Needs to be locked when any data in this state is accessed that is not explicitely marked as
+ * Needs to be locked when any data in this state is accessed that is not explicitly marked as
* otherwise.
*/
std::mutex mutex;
@@ -192,12 +192,12 @@ struct NodeState {
MutableSpan<OutputState> outputs;
/**
- * Nodes that don't support lazyness have some special handling the first time they are executed.
+ * Nodes that don't support laziness have some special handling the first time they are executed.
*/
bool non_lazy_node_is_initialized = false;
/**
- * Used to check that nodes that don't support lazyness do not run more than once.
+ * Used to check that nodes that don't support laziness do not run more than once.
*/
bool has_been_executed = false;
@@ -309,9 +309,9 @@ static const CPPType *get_socket_cpp_type(const SocketRef &socket)
return nodes::socket_cpp_type_get(*socket.typeinfo());
}
-static bool node_supports_lazyness(const DNode node)
+static bool node_supports_laziness(const DNode node)
{
- return node->typeinfo()->geometry_node_execute_supports_lazyness;
+ return node->typeinfo()->geometry_node_execute_supports_laziness;
}
/** Implements the callbacks that might be called when a node is executed. */
@@ -644,10 +644,10 @@ class GeometryNodesEvaluator {
if (!this->prepare_node_outputs_for_execution(locked_node)) {
return false;
}
- /* Initialize nodes that don't support lazyness. This is done after at least one output is
+ /* Initialize nodes that don't support laziness. This is done after at least one output is
* required and before we check that all required inputs are provided. This reduces the
* number of "round-trips" through the task pool by one for most nodes. */
- if (!node_state.non_lazy_node_is_initialized && !node_supports_lazyness(node)) {
+ if (!node_state.non_lazy_node_is_initialized && !node_supports_laziness(node)) {
this->initialize_non_lazy_node(locked_node);
node_state.non_lazy_node_is_initialized = true;
}
@@ -722,7 +722,7 @@ class GeometryNodesEvaluator {
/* Ignore unavailable/non-data sockets. */
continue;
}
- /* Nodes that don't support lazyness require all inputs. */
+ /* Nodes that don't support laziness require all inputs. */
const DInputSocket input_socket = locked_node.node.input(i);
this->set_input_required(locked_node, input_socket);
}
@@ -789,8 +789,8 @@ class GeometryNodesEvaluator {
const bNode &bnode = *node->bnode();
if (node_state.has_been_executed) {
- if (!node_supports_lazyness(node)) {
- /* Nodes that don't support lazyness must not be executed more than once. */
+ if (!node_supports_laziness(node)) {
+ /* Nodes that don't support laziness must not be executed more than once. */
BLI_assert_unreachable();
}
}
@@ -923,12 +923,12 @@ class GeometryNodesEvaluator {
return;
}
- const bool supports_lazyness = node_supports_lazyness(locked_node.node);
+ const bool supports_laziness = node_supports_laziness(locked_node.node);
/* Iterating over sockets instead of the states directly, because that makes it easier to
* figure out which socket is missing when one of the asserts is hit. */
for (const OutputSocketRef *socket_ref : locked_node.node->outputs()) {
OutputState &output_state = locked_node.node_state.outputs[socket_ref->index()];
- if (supports_lazyness) {
+ if (supports_laziness) {
/* Expected that at least all required sockets have been computed. If more outputs become
* required later, the node will be executed again. */
if (output_state.output_usage_for_execution == ValueUsage::Required) {
@@ -1025,7 +1025,7 @@ class GeometryNodesEvaluator {
/* Get all origin sockets, because we have to tag those as required as well. */
Vector<DSocket> origin_sockets;
input_socket.foreach_origin_socket(
- [&, this](const DSocket origin_socket) { origin_sockets.append(origin_socket); });
+ [&](const DSocket origin_socket) { origin_sockets.append(origin_socket); });
if (origin_sockets.is_empty()) {
/* If there are no origin sockets, just load the value from the socket directly. */
@@ -1078,7 +1078,7 @@ class GeometryNodesEvaluator {
}
/* Notify origin nodes that might want to set its inputs as unused as well. */
- socket.foreach_origin_socket([&, this](const DSocket origin_socket) {
+ socket.foreach_origin_socket([&](const DSocket origin_socket) {
if (origin_socket->is_input()) {
/* Values from these sockets are loaded directly from the sockets, so there is no node to
* notify. */
@@ -1511,7 +1511,7 @@ void NodeParamsProvider::set_output(StringRef identifier, GMutablePointer value)
bool NodeParamsProvider::lazy_require_input(StringRef identifier)
{
- BLI_assert(node_supports_lazyness(this->dnode));
+ BLI_assert(node_supports_laziness(this->dnode));
const DInputSocket socket = get_input_by_identifier(this->dnode, identifier);
BLI_assert(socket);
@@ -1547,7 +1547,7 @@ bool NodeParamsProvider::output_is_required(StringRef identifier) const
bool NodeParamsProvider::lazy_output_is_required(StringRef identifier) const
{
- BLI_assert(node_supports_lazyness(this->dnode));
+ BLI_assert(node_supports_laziness(this->dnode));
const DOutputSocket socket = get_output_by_identifier(this->dnode, identifier);
BLI_assert(socket);
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 33b56fd0de0..9d21ff19f46 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -219,7 +219,7 @@ set(SRC
shader/nodes/node_shader_camera.c
shader/nodes/node_shader_clamp.cc
shader/nodes/node_shader_common.c
- shader/nodes/node_shader_curves.c
+ shader/nodes/node_shader_curves.cc
shader/nodes/node_shader_displacement.c
shader/nodes/node_shader_eevee_specular.c
shader/nodes/node_shader_emission.c
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index 52d7e097f0d..7b176b2f395 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -200,7 +200,7 @@ class GeoNodeExecParams {
/**
* Returns true when the output has to be computed.
- * Nodes that support lazyness could use the #lazy_output_is_required variant to possibly avoid
+ * Nodes that support laziness could use the #lazy_output_is_required variant to possibly avoid
* some computations.
*/
bool output_is_required(StringRef identifier) const
@@ -212,7 +212,7 @@ class GeoNodeExecParams {
* Tell the evaluator that a specific input is required.
* This returns true when the input will only be available in the next execution.
* False is returned if the input is available already.
- * This can only be used when the node supports lazyness.
+ * This can only be used when the node supports laziness.
*/
bool lazy_require_input(StringRef identifier)
{
@@ -222,7 +222,7 @@ class GeoNodeExecParams {
/**
* Asks the evaluator if a specific output is required right now. If this returns false, the
* value might still need to be computed later.
- * This can only be used when the node supports lazyness.
+ * This can only be used when the node supports laziness.
*/
bool lazy_output_is_required(StringRef identifier)
{
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
index 21538db5455..71643df1cb6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
@@ -101,9 +101,12 @@ template<> inline float3 clamp_value(const float3 val, const float3 min, const f
return tmp;
}
-template<> inline Color4f clamp_value(const Color4f val, const Color4f min, const Color4f max)
+template<>
+inline ColorGeometry4f clamp_value(const ColorGeometry4f val,
+ const ColorGeometry4f min,
+ const ColorGeometry4f max)
{
- Color4f tmp;
+ ColorGeometry4f tmp;
tmp.r = std::min(std::max(val.r, min.r), max.r);
tmp.g = std::min(std::max(val.g, min.g), max.g);
tmp.b = std::min(std::max(val.b, min.b), max.b);
@@ -214,8 +217,8 @@ static void clamp_attribute(GeometryComponent &component, const GeoNodeExecParam
break;
}
case CD_PROP_COLOR: {
- Color4f min = params.get_input<Color4f>("Min_003");
- Color4f max = params.get_input<Color4f>("Max_003");
+ ColorGeometry4f min = params.get_input<ColorGeometry4f>("Min_003");
+ ColorGeometry4f max = params.get_input<ColorGeometry4f>("Max_003");
if (operation == NODE_CLAMP_RANGE) {
if (min.r > max.r) {
std::swap(min.r, max.r);
@@ -230,8 +233,9 @@ static void clamp_attribute(GeometryComponent &component, const GeoNodeExecParam
std::swap(min.a, max.a);
}
}
- MutableSpan<Color4f> results = attribute_result.as_span<Color4f>();
- clamp_attribute<Color4f>(attribute_input->typed<Color4f>(), results, min, max);
+ MutableSpan<ColorGeometry4f> results = attribute_result.as_span<ColorGeometry4f>();
+ clamp_attribute<ColorGeometry4f>(
+ attribute_input->typed<ColorGeometry4f>(), results, min, max);
break;
}
default: {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
index b13e82e676d..5293dd8c876 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
@@ -83,8 +83,8 @@ static void execute_on_component(const GeoNodeExecParams &params, GeometryCompon
* currently. */
const AttributeDomain result_domain = get_result_domain(component, input_name, result_name);
- OutputAttribute_Typed<Color4f> attribute_result =
- component.attribute_try_get_for_output_only<Color4f>(result_name, result_domain);
+ OutputAttribute_Typed<ColorGeometry4f> attribute_result =
+ component.attribute_try_get_for_output_only<ColorGeometry4f>(result_name, result_domain);
if (!attribute_result) {
return;
}
@@ -92,7 +92,7 @@ static void execute_on_component(const GeoNodeExecParams &params, GeometryCompon
GVArray_Typed<float> attribute_in = component.attribute_get_for_read<float>(
input_name, result_domain, 0.0f);
- MutableSpan<Color4f> results = attribute_result.as_span();
+ MutableSpan<ColorGeometry4f> results = attribute_result.as_span();
ColorBand *color_ramp = &node_storage->color_ramp;
parallel_for(IndexRange(attribute_in.size()), 512, [&](IndexRange range) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
index a2ff1668a06..57ac68b4cd4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
@@ -131,16 +131,16 @@ static void do_equal_operation_float3(const VArray<float3> &input_a,
}
}
-static void do_equal_operation_color4f(const VArray<Color4f> &input_a,
- const VArray<Color4f> &input_b,
+static void do_equal_operation_color4f(const VArray<ColorGeometry4f> &input_a,
+ const VArray<ColorGeometry4f> &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const float threshold_squared = pow2f(threshold);
const int size = input_a.size();
for (const int i : IndexRange(size)) {
- const Color4f a = input_a[i];
- const Color4f b = input_b[i];
+ const ColorGeometry4f a = input_a[i];
+ const ColorGeometry4f b = input_b[i];
span_result[i] = len_squared_v4v4(a, b) < threshold_squared;
}
}
@@ -185,16 +185,16 @@ static void do_not_equal_operation_float3(const VArray<float3> &input_a,
}
}
-static void do_not_equal_operation_color4f(const VArray<Color4f> &input_a,
- const VArray<Color4f> &input_b,
+static void do_not_equal_operation_color4f(const VArray<ColorGeometry4f> &input_a,
+ const VArray<ColorGeometry4f> &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const float threshold_squared = pow2f(threshold);
const int size = input_a.size();
for (const int i : IndexRange(size)) {
- const Color4f a = input_a[i];
- const Color4f b = input_b[i];
+ const ColorGeometry4f a = input_a[i];
+ const ColorGeometry4f b = input_b[i];
span_result[i] = len_squared_v4v4(a, b) >= threshold_squared;
}
}
@@ -287,8 +287,10 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
attribute_a->typed<float3>(), attribute_b->typed<float3>(), threshold, result_span);
}
else if (input_data_type == CD_PROP_COLOR) {
- do_equal_operation_color4f(
- attribute_a->typed<Color4f>(), attribute_b->typed<Color4f>(), threshold, result_span);
+ do_equal_operation_color4f(attribute_a->typed<ColorGeometry4f>(),
+ attribute_b->typed<ColorGeometry4f>(),
+ threshold,
+ result_span);
}
else if (input_data_type == CD_PROP_BOOL) {
do_equal_operation_bool(
@@ -305,8 +307,10 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
attribute_a->typed<float3>(), attribute_b->typed<float3>(), threshold, result_span);
}
else if (input_data_type == CD_PROP_COLOR) {
- do_not_equal_operation_color4f(
- attribute_a->typed<Color4f>(), attribute_b->typed<Color4f>(), threshold, result_span);
+ do_not_equal_operation_color4f(attribute_a->typed<ColorGeometry4f>(),
+ attribute_b->typed<ColorGeometry4f>(),
+ threshold,
+ result_span);
}
else if (input_data_type == CD_PROP_BOOL) {
do_not_equal_operation_bool(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_curve_map.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_curve_map.cc
index 2fc86269797..599c9e58e52 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_curve_map.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_curve_map.cc
@@ -165,9 +165,10 @@ static void execute_on_component(const GeoNodeExecParams &params, GeometryCompon
}
case CD_PROP_COLOR: {
const CurveMapping *cumap = (CurveMapping *)node_storage.curve_rgb;
- GVArray_Typed<Color4f> attribute_in = component.attribute_get_for_read<Color4f>(
- input_name, result_domain, Color4f(0.0f, 0.0f, 0.0f, 1.0f));
- MutableSpan<Color4f> results = attribute_result.as_span<Color4f>();
+ GVArray_Typed<ColorGeometry4f> attribute_in =
+ component.attribute_get_for_read<ColorGeometry4f>(
+ input_name, result_domain, ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f));
+ MutableSpan<ColorGeometry4f> results = attribute_result.as_span<ColorGeometry4f>();
parallel_for(IndexRange(attribute_in.size()), 512, [&](IndexRange range) {
for (const int i : range) {
BKE_curvemapping_evaluateRGBF(cumap, results[i], attribute_in[i]);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
index 60522fd0f72..389abe3b2aa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
@@ -110,7 +110,7 @@ static void fill_attribute(GeometryComponent &component, const GeoNodeExecParams
break;
}
case CD_PROP_COLOR: {
- const Color4f value = params.get_input<Color4f>("Value_002");
+ const ColorGeometry4f value = params.get_input<ColorGeometry4f>("Value_002");
attribute->fill(&value);
break;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
index e502a183ef5..a6bd6c0ee32 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
@@ -120,16 +120,16 @@ static void do_mix_operation_float3(const int blend_mode,
static void do_mix_operation_color4f(const int blend_mode,
const VArray<float> &factors,
- const VArray<Color4f> &inputs_a,
- const VArray<Color4f> &inputs_b,
- VMutableArray<Color4f> &results)
+ const VArray<ColorGeometry4f> &inputs_a,
+ const VArray<ColorGeometry4f> &inputs_b,
+ VMutableArray<ColorGeometry4f> &results)
{
const int size = results.size();
parallel_for(IndexRange(size), 512, [&](IndexRange range) {
for (const int i : range) {
const float factor = factors[i];
- Color4f a = inputs_a[i];
- const Color4f b = inputs_b[i];
+ ColorGeometry4f a = inputs_a[i];
+ const ColorGeometry4f b = inputs_b[i];
ramp_blend(blend_mode, a, factor, b);
results.set(i, a);
}
@@ -160,9 +160,9 @@ static void do_mix_operation(const CustomDataType result_type,
else if (result_type == CD_PROP_COLOR) {
do_mix_operation_color4f(blend_mode,
attribute_factor,
- attribute_a.typed<Color4f>(),
- attribute_b.typed<Color4f>(),
- attribute_result.typed<Color4f>());
+ attribute_a.typed<ColorGeometry4f>(),
+ attribute_b.typed<ColorGeometry4f>(),
+ attribute_result.typed<ColorGeometry4f>());
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
index aa558314b9e..d6b1ad3e9e0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
@@ -79,8 +79,9 @@ static void execute_on_component(GeometryComponent &component, const GeoNodeExec
const AttributeDomain result_domain = get_result_domain(
component, result_attribute_name, mapping_name);
- OutputAttribute_Typed<Color4f> attribute_out =
- component.attribute_try_get_for_output_only<Color4f>(result_attribute_name, result_domain);
+ OutputAttribute_Typed<ColorGeometry4f> attribute_out =
+ component.attribute_try_get_for_output_only<ColorGeometry4f>(result_attribute_name,
+ result_domain);
if (!attribute_out) {
return;
}
@@ -88,7 +89,7 @@ static void execute_on_component(GeometryComponent &component, const GeoNodeExec
GVArray_Typed<float3> mapping_attribute = component.attribute_get_for_read<float3>(
mapping_name, result_domain, {0, 0, 0});
- MutableSpan<Color4f> colors = attribute_out.as_span();
+ MutableSpan<ColorGeometry4f> colors = attribute_out.as_span();
parallel_for(IndexRange(mapping_attribute.size()), 128, [&](IndexRange range) {
for (const int i : range) {
TexResult texture_result = {0};
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_separate.cc b/source/blender/nodes/geometry/nodes/node_geo_point_separate.cc
index d2b024b208c..ff7e95e0221 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_separate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_separate.cc
@@ -167,6 +167,6 @@ void register_node_type_geo_point_separate()
geo_node_type_base(&ntype, GEO_NODE_POINT_SEPARATE, "Point Separate", NODE_CLASS_GEOMETRY, 0);
node_type_socket_templates(&ntype, geo_node_point_instance_in, geo_node_point_instance_out);
ntype.geometry_node_execute = blender::nodes::geo_node_point_separate_exec;
- ntype.geometry_node_execute_supports_lazyness = true;
+ ntype.geometry_node_execute_supports_laziness = true;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
index bb0a20f4561..049ba5d3143 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
@@ -134,7 +134,7 @@ static void geo_node_switch_exec(GeoNodeExecParams params)
break;
}
case SOCK_RGBA: {
- output_input<Color4f>(params, input, "_004", "Output_004");
+ output_input<ColorGeometry4f>(params, input, "_004", "Output_004");
break;
}
case SOCK_STRING: {
@@ -171,7 +171,7 @@ void register_node_type_geo_switch()
node_type_update(&ntype, blender::nodes::geo_node_switch_update);
node_type_storage(&ntype, "NodeSwitch", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_switch_exec;
- ntype.geometry_node_execute_supports_lazyness = true;
+ ntype.geometry_node_execute_supports_laziness = true;
ntype.draw_buttons = geo_node_switch_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index 73a702c753a..188d198e159 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -104,9 +104,10 @@ GVArrayPtr GeoNodeExecParams::get_input_attribute(const StringRef name,
return std::make_unique<fn::GVArray_For_SingleValue>(*cpp_type, domain_size, buffer);
}
if (found_socket->type == SOCK_RGBA) {
- const Color4f value = this->get_input<Color4f>(found_socket->identifier);
+ const ColorGeometry4f value = this->get_input<ColorGeometry4f>(found_socket->identifier);
BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer);
- conversions.convert_to_uninitialized(CPPType::get<Color4f>(), *cpp_type, &value, buffer);
+ conversions.convert_to_uninitialized(
+ CPPType::get<ColorGeometry4f>(), *cpp_type, &value, buffer);
return std::make_unique<fn::GVArray_For_SingleValue>(*cpp_type, domain_size, buffer);
}
BLI_assert(false);
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index ce2848b52a0..783a7a9b3d8 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -637,9 +637,9 @@ static bNodeSocketType *make_socket_type_vector(PropertySubType subtype)
static bNodeSocketType *make_socket_type_rgba()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_RGBA, PROP_NONE);
- socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<blender::Color4f>(); };
+ socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<blender::ColorGeometry4f>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
- *(blender::Color4f *)r_value = ((bNodeSocketValueRGBA *)socket.default_value)->value;
+ *(blender::ColorGeometry4f *)r_value = ((bNodeSocketValueRGBA *)socket.default_value)->value;
};
return socktype;
}
diff --git a/source/blender/nodes/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc
index 5c0bc0b5ebc..8699736e543 100644
--- a/source/blender/nodes/intern/node_tree_ref.cc
+++ b/source/blender/nodes/intern/node_tree_ref.cc
@@ -297,6 +297,12 @@ void OutputSocketRef::foreach_logical_target(
skipped_fn.call_safe(target);
for (const InternalLinkRef *internal_link : target_node.internal_links()) {
if (&internal_link->from() == &target) {
+ /* The internal link only forwards the first incoming link. */
+ if (target.is_multi_input_socket()) {
+ if (target.directly_linked_links()[0] != link) {
+ continue;
+ }
+ }
const OutputSocketRef &mute_output = internal_link->to();
skipped_fn.call_safe(target);
skipped_fn.call_safe(mute_output);
diff --git a/source/blender/nodes/intern/type_conversions.cc b/source/blender/nodes/intern/type_conversions.cc
index 63f7b8a9ee8..220e5ea9046 100644
--- a/source/blender/nodes/intern/type_conversions.cc
+++ b/source/blender/nodes/intern/type_conversions.cc
@@ -66,9 +66,9 @@ static bool float_to_bool(const float &a)
{
return a > 0.0f;
}
-static Color4f float_to_color(const float &a)
+static ColorGeometry4f float_to_color(const float &a)
{
- return Color4f(a, a, a, 1.0f);
+ return ColorGeometry4f(a, a, a, 1.0f);
}
static float3 float2_to_float3(const float2 &a)
@@ -87,9 +87,9 @@ static bool float2_to_bool(const float2 &a)
{
return !is_zero_v2(a);
}
-static Color4f float2_to_color(const float2 &a)
+static ColorGeometry4f float2_to_color(const float2 &a)
{
- return Color4f(a.x, a.y, 0.0f, 1.0f);
+ return ColorGeometry4f(a.x, a.y, 0.0f, 1.0f);
}
static bool float3_to_bool(const float3 &a)
@@ -108,9 +108,9 @@ static float2 float3_to_float2(const float3 &a)
{
return float2(a);
}
-static Color4f float3_to_color(const float3 &a)
+static ColorGeometry4f float3_to_color(const float3 &a)
{
- return Color4f(a.x, a.y, a.z, 1.0f);
+ return ColorGeometry4f(a.x, a.y, a.z, 1.0f);
}
static bool int_to_bool(const int32_t &a)
@@ -129,9 +129,9 @@ static float3 int_to_float3(const int32_t &a)
{
return float3((float)a);
}
-static Color4f int_to_color(const int32_t &a)
+static ColorGeometry4f int_to_color(const int32_t &a)
{
- return Color4f((float)a, (float)a, (float)a, 1.0f);
+ return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f);
}
static float bool_to_float(const bool &a)
@@ -150,28 +150,28 @@ static float3 bool_to_float3(const bool &a)
{
return (a) ? float3(1.0f) : float3(0.0f);
}
-static Color4f bool_to_color(const bool &a)
+static ColorGeometry4f bool_to_color(const bool &a)
{
- return (a) ? Color4f(1.0f, 1.0f, 1.0f, 1.0f) : Color4f(0.0f, 0.0f, 0.0f, 1.0f);
+ return (a) ? ColorGeometry4f(1.0f, 1.0f, 1.0f, 1.0f) : ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f);
}
-static bool color_to_bool(const Color4f &a)
+static bool color_to_bool(const ColorGeometry4f &a)
{
return rgb_to_grayscale(a) > 0.0f;
}
-static float color_to_float(const Color4f &a)
+static float color_to_float(const ColorGeometry4f &a)
{
return rgb_to_grayscale(a);
}
-static int32_t color_to_int(const Color4f &a)
+static int32_t color_to_int(const ColorGeometry4f &a)
{
return (int)rgb_to_grayscale(a);
}
-static float2 color_to_float2(const Color4f &a)
+static float2 color_to_float2(const ColorGeometry4f &a)
{
return float2(a.r, a.g);
}
-static float3 color_to_float3(const Color4f &a)
+static float3 color_to_float3(const ColorGeometry4f &a)
{
return float3(a.r, a.g, a.b);
}
@@ -184,37 +184,37 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<float, float3, float_to_float3>(conversions);
add_implicit_conversion<float, int32_t, float_to_int>(conversions);
add_implicit_conversion<float, bool, float_to_bool>(conversions);
- add_implicit_conversion<float, Color4f, float_to_color>(conversions);
+ add_implicit_conversion<float, ColorGeometry4f, float_to_color>(conversions);
add_implicit_conversion<float2, float3, float2_to_float3>(conversions);
add_implicit_conversion<float2, float, float2_to_float>(conversions);
add_implicit_conversion<float2, int32_t, float2_to_int>(conversions);
add_implicit_conversion<float2, bool, float2_to_bool>(conversions);
- add_implicit_conversion<float2, Color4f, float2_to_color>(conversions);
+ add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions);
add_implicit_conversion<float3, bool, float3_to_bool>(conversions);
add_implicit_conversion<float3, float, float3_to_float>(conversions);
add_implicit_conversion<float3, int32_t, float3_to_int>(conversions);
add_implicit_conversion<float3, float2, float3_to_float2>(conversions);
- add_implicit_conversion<float3, Color4f, float3_to_color>(conversions);
+ add_implicit_conversion<float3, ColorGeometry4f, float3_to_color>(conversions);
add_implicit_conversion<int32_t, bool, int_to_bool>(conversions);
add_implicit_conversion<int32_t, float, int_to_float>(conversions);
add_implicit_conversion<int32_t, float2, int_to_float2>(conversions);
add_implicit_conversion<int32_t, float3, int_to_float3>(conversions);
- add_implicit_conversion<int32_t, Color4f, int_to_color>(conversions);
+ add_implicit_conversion<int32_t, ColorGeometry4f, int_to_color>(conversions);
add_implicit_conversion<bool, float, bool_to_float>(conversions);
add_implicit_conversion<bool, int32_t, bool_to_int>(conversions);
add_implicit_conversion<bool, float2, bool_to_float2>(conversions);
add_implicit_conversion<bool, float3, bool_to_float3>(conversions);
- add_implicit_conversion<bool, Color4f, bool_to_color>(conversions);
+ add_implicit_conversion<bool, ColorGeometry4f, bool_to_color>(conversions);
- add_implicit_conversion<Color4f, bool, color_to_bool>(conversions);
- add_implicit_conversion<Color4f, float, color_to_float>(conversions);
- add_implicit_conversion<Color4f, int32_t, color_to_int>(conversions);
- add_implicit_conversion<Color4f, float2, color_to_float2>(conversions);
- add_implicit_conversion<Color4f, float3, color_to_float3>(conversions);
+ add_implicit_conversion<ColorGeometry4f, bool, color_to_bool>(conversions);
+ add_implicit_conversion<ColorGeometry4f, float, color_to_float>(conversions);
+ add_implicit_conversion<ColorGeometry4f, int32_t, color_to_int>(conversions);
+ add_implicit_conversion<ColorGeometry4f, float2, color_to_float2>(conversions);
+ add_implicit_conversion<ColorGeometry4f, float3, color_to_float3>(conversions);
return conversions;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.cc
index 42299a193e2..f1d5040a292 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc
@@ -47,7 +47,7 @@ static void node_shader_exec_curve_vec(void *UNUSED(data),
/* stack order input: vec */
/* stack order output: vec */
nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
- BKE_curvemapping_evaluate3F(node->storage, out[0]->vec, vec);
+ BKE_curvemapping_evaluate3F((CurveMapping *)node->storage, out[0]->vec, vec);
}
static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node)
@@ -64,7 +64,7 @@ static int gpu_shader_curve_vec(GPUMaterial *mat,
float *array, layer;
int size;
- CurveMapping *cumap = node->storage;
+ CurveMapping *cumap = (CurveMapping *)node->storage;
BKE_curvemapping_table_RGBA(cumap, &array, &size);
GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
@@ -104,17 +104,65 @@ static int gpu_shader_curve_vec(GPUMaterial *mat,
GPU_uniform(ext_xyz[2]));
}
+class CurveVecFunction : public blender::fn::MultiFunction {
+ private:
+ const CurveMapping &cumap_;
+
+ public:
+ CurveVecFunction(const CurveMapping &cumap) : cumap_(cumap)
+ {
+ static blender::fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static blender::fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Curve Vec"};
+ signature.single_input<float>("Fac");
+ signature.single_input<blender::float3>("Vector");
+ signature.single_output<blender::float3>("Vector");
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ const blender::VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
+ const blender::VArray<blender::float3> &vec_in = params.readonly_single_input<blender::float3>(
+ 1, "Vector");
+ blender::MutableSpan<blender::float3> vec_out =
+ params.uninitialized_single_output<blender::float3>(2, "Vector");
+
+ for (int64_t i : mask) {
+ BKE_curvemapping_evaluate3F(&cumap_, vec_out[i], vec_in[i]);
+ if (fac[i] != 1.0f) {
+ interp_v3_v3v3(vec_out[i], vec_in[i], vec_out[i], fac[i]);
+ }
+ }
+ }
+};
+
+static void sh_node_curve_vec_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ bNode &bnode = builder.bnode();
+ CurveMapping *cumap = (CurveMapping *)bnode.storage;
+ BKE_curvemapping_init(cumap);
+ builder.construct_and_set_matching_fn<CurveVecFunction>(*cumap);
+}
+
void register_node_type_sh_curve_vec(void)
{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, 0);
+ sh_fn_node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, 0);
node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out);
node_type_init(&ntype, node_shader_init_curve_vec);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_exec(&ntype, node_initexec_curves, NULL, node_shader_exec_curve_vec);
+ node_type_exec(&ntype, node_initexec_curves, nullptr, node_shader_exec_curve_vec);
node_type_gpu(&ntype, gpu_shader_curve_vec);
+ ntype.expand_in_mf_network = sh_node_curve_vec_expand_in_mf_network;
nodeRegisterType(&ntype);
}
@@ -145,7 +193,7 @@ static void node_shader_exec_curve_rgb(void *UNUSED(data),
/* stack order output: vec */
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
- BKE_curvemapping_evaluateRGBF(node->storage, out[0]->vec, vec);
+ BKE_curvemapping_evaluateRGBF((CurveMapping *)node->storage, out[0]->vec, vec);
if (fac != 1.0f) {
interp_v3_v3v3(out[0]->vec, vec, out[0]->vec, fac);
}
@@ -166,7 +214,7 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
int size;
bool use_opti = true;
- CurveMapping *cumap = node->storage;
+ CurveMapping *cumap = (CurveMapping *)node->storage;
BKE_curvemapping_init(cumap);
BKE_curvemapping_table_RGBA(cumap, &array, &size);
@@ -230,17 +278,65 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
GPU_uniform(ext_rgba[3]));
}
+class CurveRGBFunction : public blender::fn::MultiFunction {
+ private:
+ const CurveMapping &cumap_;
+
+ public:
+ CurveRGBFunction(const CurveMapping &cumap) : cumap_(cumap)
+ {
+ static blender::fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static blender::fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Curve RGB"};
+ signature.single_input<float>("Fac");
+ signature.single_input<blender::ColorGeometry4f>("Color");
+ signature.single_output<blender::ColorGeometry4f>("Color");
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ const blender::VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
+ const blender::VArray<blender::ColorGeometry4f> &col_in =
+ params.readonly_single_input<blender::ColorGeometry4f>(1, "Color");
+ blender::MutableSpan<blender::ColorGeometry4f> col_out =
+ params.uninitialized_single_output<blender::ColorGeometry4f>(2, "Color");
+
+ for (int64_t i : mask) {
+ BKE_curvemapping_evaluateRGBF(&cumap_, col_out[i], col_in[i]);
+ if (fac[i] != 1.0f) {
+ interp_v3_v3v3(col_out[i], col_in[i], col_out[i], fac[i]);
+ }
+ }
+ }
+};
+
+static void sh_node_curve_rgb_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ bNode &bnode = builder.bnode();
+ CurveMapping *cumap = (CurveMapping *)bnode.storage;
+ BKE_curvemapping_init(cumap);
+ builder.construct_and_set_matching_fn<CurveRGBFunction>(*cumap);
+}
+
void register_node_type_sh_curve_rgb(void)
{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, 0);
+ sh_fn_node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out);
node_type_init(&ntype, node_shader_init_curve_rgb);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_exec(&ntype, node_initexec_curves, NULL, node_shader_exec_curve_rgb);
+ node_type_exec(&ntype, node_initexec_curves, nullptr, node_shader_exec_curve_rgb);
node_type_gpu(&ntype, gpu_shader_curve_rgb);
+ ntype.expand_in_mf_network = sh_node_curve_rgb_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
index 8ca4a6bab5f..a7239154633 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
@@ -70,7 +70,7 @@ class SeparateRGBFunction : public blender::fn::MultiFunction {
static blender::fn::MFSignature create_signature()
{
blender::fn::MFSignatureBuilder signature{"Separate RGB"};
- signature.single_input<blender::Color4f>("Color");
+ signature.single_input<blender::ColorGeometry4f>("Color");
signature.single_output<float>("R");
signature.single_output<float>("G");
signature.single_output<float>("B");
@@ -81,14 +81,14 @@ class SeparateRGBFunction : public blender::fn::MultiFunction {
blender::fn::MFParams params,
blender::fn::MFContext UNUSED(context)) const override
{
- const blender::VArray<blender::Color4f> &colors =
- params.readonly_single_input<blender::Color4f>(0, "Color");
+ const blender::VArray<blender::ColorGeometry4f> &colors =
+ params.readonly_single_input<blender::ColorGeometry4f>(0, "Color");
blender::MutableSpan<float> rs = params.uninitialized_single_output<float>(1, "R");
blender::MutableSpan<float> gs = params.uninitialized_single_output<float>(2, "G");
blender::MutableSpan<float> bs = params.uninitialized_single_output<float>(3, "B");
for (int64_t i : mask) {
- blender::Color4f color = colors[i];
+ blender::ColorGeometry4f color = colors[i];
rs[i] = color.r;
gs[i] = color.g;
bs[i] = color.b;
@@ -155,8 +155,9 @@ static int gpu_shader_combrgb(GPUMaterial *mat,
static void sh_node_combrgb_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
{
- static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, blender::Color4f> fn{
- "Combine RGB", [](float r, float g, float b) { return blender::Color4f(r, g, b, 1.0f); }};
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, blender::ColorGeometry4f> fn{
+ "Combine RGB",
+ [](float r, float g, float b) { return blender::ColorGeometry4f(r, g, b, 1.0f); }};
builder.set_matching_fn(fn);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
index 90e8161c09f..5b2eb300aac 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
@@ -140,7 +140,7 @@ class ColorBandFunction : public blender::fn::MultiFunction {
{
blender::fn::MFSignatureBuilder signature{"Color Band"};
signature.single_input<float>("Value");
- signature.single_output<blender::Color4f>("Color");
+ signature.single_output<blender::ColorGeometry4f>("Color");
signature.single_output<float>("Alpha");
return signature.build();
}
@@ -150,12 +150,12 @@ class ColorBandFunction : public blender::fn::MultiFunction {
blender::fn::MFContext UNUSED(context)) const override
{
const blender::VArray<float> &values = params.readonly_single_input<float>(0, "Value");
- blender::MutableSpan<blender::Color4f> colors =
- params.uninitialized_single_output<blender::Color4f>(1, "Color");
+ blender::MutableSpan<blender::ColorGeometry4f> colors =
+ params.uninitialized_single_output<blender::ColorGeometry4f>(1, "Color");
blender::MutableSpan<float> alphas = params.uninitialized_single_output<float>(2, "Alpha");
for (int64_t i : mask) {
- blender::Color4f color;
+ blender::ColorGeometry4f color;
BKE_colorband_evaluate(&color_band_, values[i], color);
colors[i] = color;
alphas[i] = color.a;
diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h
index 4f49b8cb58f..63df886d31f 100644
--- a/source/blender/sequencer/SEQ_sequencer.h
+++ b/source/blender/sequencer/SEQ_sequencer.h
@@ -52,6 +52,7 @@ enum {
#define SEQ_DUPE_IS_RECURSIVE_CALL (1 << 4)
struct SequencerToolSettings *SEQ_tool_settings_init(void);
+struct SequencerToolSettings *SEQ_tool_settings_ensure(struct Scene *scene);
void SEQ_tool_settings_free(struct SequencerToolSettings *tool_settings);
eSeqImageFitMethod SEQ_tool_settings_fit_method_get(struct Scene *scene);
void SEQ_tool_settings_fit_method_set(struct Scene *scene, eSeqImageFitMethod fit_method);
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index f3cea273fdf..d881c90a1e0 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -273,15 +273,6 @@ static bool seq_is_effect_of(const Sequence *seq_effect, const Sequence *possibl
* Order of applying these conditions is important. */
static bool must_render_strip(const Sequence *seq, SeqCollection *strips_under_playhead)
{
- /* Sound strips are not rendered. */
- if (seq->type == SEQ_TYPE_SOUND_RAM) {
- return false;
- }
- /* Muted strips are not rendered. */
- if ((seq->flag & SEQ_MUTE) != 0) {
- return false;
- }
-
bool seq_have_effect_in_stack = false;
Sequence *seq_iter;
SEQ_ITERATOR_FOREACH (seq_iter, strips_under_playhead) {
@@ -340,6 +331,15 @@ static void collection_filter_channel_up_to_incl(SeqCollection *collection, cons
static void collection_filter_rendered_strips(SeqCollection *collection)
{
Sequence *seq;
+
+ /* Remove sound strips and muted strips from collection, because these are not rendered.
+ * Function must_render_strip() don't have to check for these strips anymore. */
+ SEQ_ITERATOR_FOREACH (seq, collection) {
+ if (seq->type == SEQ_TYPE_SOUND_RAM || (seq->flag & SEQ_MUTE) != 0) {
+ SEQ_collection_remove_strip(seq, collection);
+ }
+ }
+
SEQ_ITERATOR_FOREACH (seq, collection) {
if (must_render_strip(seq, collection)) {
continue;
diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c
index 55c14944a23..4acb6a206be 100644
--- a/source/blender/sequencer/intern/sequencer.c
+++ b/source/blender/sequencer/intern/sequencer.c
@@ -313,6 +313,17 @@ SequencerToolSettings *SEQ_tool_settings_init(void)
return tool_settings;
}
+SequencerToolSettings *SEQ_tool_settings_ensure(Scene *scene)
+{
+ SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
+ if (tool_settings == NULL) {
+ scene->toolsettings->sequencer_tool_settings = SEQ_tool_settings_init();
+ tool_settings = scene->toolsettings->sequencer_tool_settings;
+ }
+
+ return tool_settings;
+}
+
void SEQ_tool_settings_free(SequencerToolSettings *tool_settings)
{
MEM_freeN(tool_settings);
@@ -320,13 +331,13 @@ void SEQ_tool_settings_free(SequencerToolSettings *tool_settings)
eSeqImageFitMethod SEQ_tool_settings_fit_method_get(Scene *scene)
{
- const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
+ const SequencerToolSettings *tool_settings = SEQ_tool_settings_ensure(scene);
return tool_settings->fit_method;
}
void SEQ_tool_settings_fit_method_set(Scene *scene, eSeqImageFitMethod fit_method)
{
- SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
+ SequencerToolSettings *tool_settings = SEQ_tool_settings_ensure(scene);
tool_settings->fit_method = fit_method;
}