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:
authorHans Goudey <h.goudey@me.com>2021-07-19 02:29:49 +0300
committerHans Goudey <h.goudey@me.com>2021-07-19 02:29:49 +0300
commitdb384d4df6c0aca209554573e2fe85efa9f0cd0d (patch)
treeccc35afe7000942113d8f700ae5f4fdc3bf61bfe /source/blender
parent20ddb64207a1b06df56b6666574843fa6d9b3374 (diff)
parent83883ae66ad3231840d483ff091727b33d2f355b (diff)
Merge branch 'master' into temp-geometry-nodes-curve-sample
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/BKE_deform.h2
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h2
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh4
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h10
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h8
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/action_mirror.c5
-rw-r--r--source/blender/blenkernel/intern/armature_deform.c8
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c2
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc5
-rw-r--r--source/blender/blenkernel/intern/gpencil.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.cc (renamed from source/blender/blenkernel/intern/gpencil_geom.c)478
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c4
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/node.cc7
-rw-r--r--source/blender/blenkernel/intern/spline_base.cc2
-rw-r--r--source/blender/blenlib/BLI_delaunay_2d.h8
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.cc355
-rw-r--r--source/blender/blenlib/intern/mesh_intersect.cc65
-rw-r--r--source/blender/blenlib/intern/system.c2
-rw-r--r--source/blender/blenlib/intern/task_iterator.c19
-rw-r--r--source/blender/blenlib/tests/BLI_delaunay_2d_test.cc103
-rw-r--r--source/blender/blenloader/intern/versioning_300.c31
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect_concave.c8
-rw-r--r--source/blender/bmesh/operators/bmo_edgenet.c2
-rw-r--r--source/blender/bmesh/operators/bmo_fill_grid.c16
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide_edgering.c8
-rw-r--r--source/blender/compositor/nodes/COM_IDMaskNode.cc26
-rw-r--r--source/blender/compositor/operations/COM_SMAAOperation.cc7
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc12
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc1
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.cc16
-rw-r--r--source/blender/editors/asset/asset_edit.cc6
-rw-r--r--source/blender/editors/asset/asset_list.cc8
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c11
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c2
-rw-r--r--source/blender/editors/include/ED_anim_api.h2
-rw-r--r--source/blender/editors/include/ED_armature.h6
-rw-r--r--source/blender/editors/include/ED_asset.h2
-rw-r--r--source/blender/editors/include/ED_node.h2
-rw-r--r--source/blender/editors/include/ED_particle.h2
-rw-r--r--source/blender/editors/include/ED_spreadsheet.h10
-rw-r--r--source/blender/editors/interface/interface.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c8
-rw-r--r--source/blender/editors/interface/interface_region_search.c8
-rw-r--r--source/blender/editors/interface/interface_template_asset_view.cc6
-rw-r--r--source/blender/editors/interface/interface_utils.c2
-rw-r--r--source/blender/editors/io/io_gpencil.h2
-rw-r--r--source/blender/editors/object/object_data_transfer.c87
-rw-r--r--source/blender/editors/object/object_vgroup.c6
-rw-r--r--source/blender/editors/render/render_preview.c11
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c9
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h2
-rw-r--r--source/blender/editors/space_graph/graph_select.c2
-rw-r--r--source/blender/editors/space_image/image_buttons.c16
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_draw.hh4
-rw-r--r--source/blender/editors/space_text/text_format_lua.c6
-rw-r--r--source/blender/editors/space_text/text_format_osl.c10
-rw-r--r--source/blender/editors/space_text/text_format_pov.c10
-rw-r--r--source/blender/editors/space_text/text_format_pov_ini.c4
-rw-r--r--source/blender/editors/space_text/text_format_py.c8
-rw-r--r--source/blender/editors/transform/transform.c2
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c8
-rw-r--r--source/blender/editors/undo/ed_undo.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c14
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp2
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h6
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c6
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h4
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc8
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c2
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc2
-rw-r--r--source/blender/imbuf/IMB_imbuf.h2
-rw-r--r--source/blender/imbuf/intern/scaling.c494
-rw-r--r--source/blender/io/gpencil/gpencil_io.h2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.hh2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_import_svg.hh4
-rw-r--r--source/blender/makesdna/DNA_curve_types.h2
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_defaults.h3
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h12
-rw-r--r--source/blender/makesdna/DNA_node_types.h14
-rw-r--r--source/blender/makesdna/DNA_screen_types.h2
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h2
-rw-r--r--source/blender/makesdna/intern/dna_rename_defs.h1
-rw-r--r--source/blender/makesrna/intern/rna_asset.c2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c9
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c26
-rw-r--r--source/blender/makesrna/intern/rna_object.c31
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c38
-rw-r--r--source/blender/makesrna/intern/rna_space.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c2
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c99
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_geometry.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_antialiasing.c6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc408
-rw-r--r--source/blender/python/BPY_extern.h2
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.c2
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c2
-rw-r--r--source/blender/python/intern/bpy_props.c2
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c2
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c25
-rw-r--r--source/blender/sequencer/SEQ_iterator.h2
-rw-r--r--source/blender/sequencer/SEQ_proxy.h2
-rw-r--r--source/blender/sequencer/SEQ_sequencer.h2
-rw-r--r--source/blender/sequencer/SEQ_transform.h2
-rw-r--r--source/blender/sequencer/intern/strip_edit.c2
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c1
-rw-r--r--source/blender/windowmanager/intern/wm_uilist_type.c4
129 files changed, 1869 insertions, 925 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 1f9e304c7a3..e13475fd78c 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -28,7 +28,6 @@ extern "C" {
#endif
struct AnimationEvalContext;
-struct bAction;
struct BMEditMesh;
struct Bone;
struct Depsgraph;
@@ -39,6 +38,7 @@ struct Mesh;
struct Object;
struct PoseTree;
struct Scene;
+struct bAction;
struct bArmature;
struct bConstraint;
struct bGPDstroke;
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 0ab126a70ae..f4221d57428 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -30,6 +30,7 @@ extern "C" {
struct BlendDataReader;
struct BlendWriter;
+struct ID;
struct ListBase;
struct MDeformVert;
struct MEdge;
@@ -37,7 +38,6 @@ struct MLoop;
struct MPoly;
struct Object;
struct bDeformGroup;
-struct ID;
bool BKE_object_supports_vertex_groups(const struct Object *ob);
const struct ListBase *BKE_object_defgroup_list(const struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index ce7df62389f..ffd8ac42c63 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -32,8 +32,8 @@ extern "C" {
#endif
struct BMLoop;
-struct BMesh;
struct BMPartialUpdate;
+struct BMesh;
struct BMeshCalcTessellation_Params;
struct BoundBox;
struct Depsgraph;
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 77e827bf6f2..42e9ce82278 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -35,12 +35,12 @@
#include "BKE_geometry_set.h"
struct Collection;
+struct Curve;
+struct CurveEval;
struct Mesh;
struct Object;
struct PointCloud;
struct Volume;
-struct Curve;
-struct CurveEval;
enum class GeometryOwnershipType {
/* The geometry is owned. This implies that it can be changed. */
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 1f9c3e766aa..92e70b41e7b 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -49,22 +49,22 @@ struct bGPDlayer_Mask;
struct bGPDstroke;
struct bGPdata;
-#define GPENCIL_SIMPLIFY(scene) ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE))
+#define GPENCIL_SIMPLIFY(scene) (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE)
#define GPENCIL_SIMPLIFY_ONPLAY(playing) \
(((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || \
((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0))
#define GPENCIL_SIMPLIFY_FILL(scene, playing) \
- ((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
+ ((GPENCIL_SIMPLIFY_ONPLAY(playing) && GPENCIL_SIMPLIFY(scene) && \
(scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL)))
#define GPENCIL_SIMPLIFY_MODIF(scene) \
((GPENCIL_SIMPLIFY(scene) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER)))
#define GPENCIL_SIMPLIFY_FX(scene, playing) \
- ((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
+ ((GPENCIL_SIMPLIFY_ONPLAY(playing) && GPENCIL_SIMPLIFY(scene) && \
(scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FX)))
#define GPENCIL_SIMPLIFY_TINT(scene) \
- ((GPENCIL_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_TINT))
+ (GPENCIL_SIMPLIFY(scene) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_TINT))
#define GPENCIL_SIMPLIFY_AA(scene) \
- ((GPENCIL_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_AA))
+ (GPENCIL_SIMPLIFY(scene) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_AA))
/* Vertex Color macros. */
#define GPENCIL_USE_VERTEX_COLOR(toolsettings) \
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 27076d908e7..c6658ff424a 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -42,8 +42,8 @@
extern "C" {
#endif
-struct Collection;
struct BlendFileReadReport;
+struct Collection;
struct ID;
struct IDOverrideLibrary;
struct IDOverrideLibraryProperty;
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 5e977fbc0cd..39024445808 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1274,6 +1274,11 @@ void ntreeGPUMaterialNodes(struct bNodeTree *localtree,
#define CMP_CRYPTOMATTE_SRC_RENDER 0
#define CMP_CRYPTOMATTE_SRC_IMAGE 1
+/* Default SMAA configuration values. */
+#define CMP_DEFAULT_SMAA_THRESHOLD 1.0f
+#define CMP_DEFAULT_SMAA_CONTRAST_LIMIT 0.2f
+#define CMP_DEFAULT_SMAA_CORNER_ROUNDING 0.25f
+
/* API */
void ntreeCompositExecTree(struct Scene *scene,
struct bNodeTree *ntree,
@@ -1459,7 +1464,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_CURVE_PRIMITIVE_LINE 1068
#define GEO_NODE_CURVE_ENDPOINTS 1069
#define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070
-#define GEO_NODE_CURVE_SAMPLE 1071
+#define GEO_NODE_CURVE_TRIM 1071
+#define GEO_NODE_CURVE_SAMPLE 1072
/** \} */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2c25b940578..527996ee46d 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -143,7 +143,7 @@ set(SRC
intern/geometry_set_instances.cc
intern/gpencil.c
intern/gpencil_curve.c
- intern/gpencil_geom.c
+ intern/gpencil_geom.cc
intern/gpencil_modifier.c
intern/hair.c
intern/icons.cc
diff --git a/source/blender/blenkernel/intern/action_mirror.c b/source/blender/blenkernel/intern/action_mirror.c
index ba041388981..48472dfc9b3 100644
--- a/source/blender/blenkernel/intern/action_mirror.c
+++ b/source/blender/blenkernel/intern/action_mirror.c
@@ -324,8 +324,9 @@ static void action_flip_pchan(Object *ob_arm,
/* The rest pose having an X-axis that is not mapping to a left/right direction (so aligned
* with the Y or Z axis) creates issues when flipping the pose. Instead of a negative scale on
- * the X-axis, it turns into a 180 degree rotation over the Y-axis. This has only been observed
- * with non-flippable bones, hence the check for `pchan_flip`. */
+ * the X-axis, it turns into a 180 degree rotation over the Y-axis.
+ * This has only been observed with bones that can't be flipped,
+ * hence the check for `pchan_flip`. */
const float unit_x[4] = {1.0f, 0.0f, 0.0f, 0.0f};
const bool is_problematic = pchan_flip == NULL &&
fabsf(dot_v4v4(pchan->bone->arm_mat[0], unit_x)) <= 1e-6;
diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c
index 5e9259f05bb..5f721b49361 100644
--- a/source/blender/blenkernel/intern/armature_deform.c
+++ b/source/blender/blenkernel/intern/armature_deform.c
@@ -501,7 +501,7 @@ static void armature_deform_coords_impl(const Object *ob_arm,
BLI_assert(0);
}
- if (ELEM(ob_target->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
+ if (BKE_object_supports_vertex_groups(ob_target)) {
/* get the def_nr for the overall armature vertex group if present */
armature_def_nr = BKE_object_defgroup_name_index(ob_target, defgrp_name);
@@ -529,11 +529,9 @@ static void armature_deform_coords_impl(const Object *ob_arm,
dverts_len = gps_target->totpoints;
}
}
- }
- /* get a vertex-deform-index to posechannel array */
- if (deformflag & ARM_DEF_VGROUP) {
- if (ELEM(ob_target->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
+ /* get a vertex-deform-index to posechannel array */
+ if (deformflag & ARM_DEF_VGROUP) {
/* if we have a Mesh, only use dverts if it has them */
if (em_target) {
cd_dvert_offset = CustomData_get_offset(&em_target->bm->vdata, CD_MDEFORMVERT);
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index dbd48005e9e..641c003d456 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -688,7 +688,7 @@ static float fcm_cycles_time(
ofs = lastkey[0];
}
}
- if ((ELEM(0, side, mode))) {
+ if (ELEM(0, side, mode)) {
return evaltime;
}
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 47c8df03375..90a97264c8f 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -565,6 +565,7 @@ static PointCloud *join_pointcloud_position_attribute(Span<GeometryInstanceGroup
}
PointCloud *new_pointcloud = BKE_pointcloud_new_nomain(totpoint);
+ MutableSpan new_positions{(float3 *)new_pointcloud->co, new_pointcloud->totpoint};
/* Transform each instance's point locations into the new point cloud. */
int offset = 0;
@@ -576,9 +577,7 @@ static PointCloud *join_pointcloud_position_attribute(Span<GeometryInstanceGroup
}
for (const float4x4 &transform : set_group.transforms) {
for (const int i : IndexRange(pointcloud->totpoint)) {
- const float3 old_position = pointcloud->co[i];
- const float3 new_position = transform * old_position;
- copy_v3_v3(new_pointcloud->co[offset + i], new_position);
+ new_positions[offset + i] = transform * float3(pointcloud->co[i]);
}
offset += pointcloud->totpoint;
}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index e13b9d543d7..38397f8f307 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -2730,7 +2730,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
int cfra)
{
bGPdata *gpd = (bGPdata *)ob->data;
- const bool is_multiedit = ((GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) && (!GPENCIL_PLAY_ON(gpd)));
+ const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && (!GPENCIL_PLAY_ON(gpd)));
const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
const bool is_drawing = (gpd->runtime.sbuffer_used > 0);
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.cc
index 4dcd94fdeec..785f63a7ba2 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -21,22 +21,24 @@
* \ingroup bke
*/
-#include <math.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cmath>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "CLG_log.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_float3.hh"
#include "BLI_ghash.h"
#include "BLI_hash.h"
#include "BLI_heap.h"
#include "BLI_math_vector.h"
#include "BLI_polyfill_2d.h"
+#include "BLI_span.hh"
#include "BLT_translation.h"
@@ -61,6 +63,9 @@
#include "DEG_depsgraph_query.h"
+using blender::float3;
+using blender::Span;
+
/* GP Object - Boundbox Support */
/**
*Get min/max coordinate bounds for single stroke.
@@ -75,20 +80,26 @@ bool BKE_gpencil_stroke_minmax(const bGPDstroke *gps,
float r_min[3],
float r_max[3])
{
- const bGPDspoint *pt;
- int i;
- bool changed = false;
-
- if (ELEM(NULL, gps, r_min, r_max)) {
+ if (gps == nullptr) {
return false;
}
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if ((use_select == false) || (pt->flag & GP_SPOINT_SELECT)) {
- minmax_v3v3_v3(r_min, r_max, &pt->x);
+ bool changed = false;
+ if (use_select) {
+ for (const bGPDspoint &pt : Span(gps->points, gps->totpoints)) {
+ if (pt.flag & GP_SPOINT_SELECT) {
+ minmax_v3v3_v3(r_min, r_max, &pt.x);
+ changed = true;
+ }
+ }
+ }
+ else {
+ for (const bGPDspoint &pt : Span(gps->points, gps->totpoints)) {
+ minmax_v3v3_v3(r_min, r_max, &pt.x);
changed = true;
}
}
+
return changed;
}
@@ -105,14 +116,14 @@ bool BKE_gpencil_data_minmax(const bGPdata *gpd, float r_min[3], float r_max[3])
INIT_MINMAX(r_min, r_max);
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return changed;
}
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
bGPDframe *gpf = gpl->actframe;
- if (gpf != NULL) {
+ if (gpf != nullptr) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
changed |= BKE_gpencil_stroke_minmax(gps, false, r_min, r_max);
}
@@ -129,11 +140,11 @@ bool BKE_gpencil_data_minmax(const bGPdata *gpd, float r_min[3], float r_max[3])
*/
void BKE_gpencil_centroid_3d(bGPdata *gpd, float r_centroid[3])
{
- float min[3], max[3], tot[3];
-
+ float3 min;
+ float3 max;
BKE_gpencil_data_minmax(gpd, min, max);
- add_v3_v3v3(tot, min, max);
+ const float3 tot = min + max;
mul_v3_v3fl(r_centroid, tot, 0.5f);
}
@@ -153,20 +164,18 @@ void BKE_gpencil_stroke_boundingbox_calc(bGPDstroke *gps)
*/
static void boundbox_gpencil(Object *ob)
{
- BoundBox *bb;
- bGPdata *gpd;
- float min[3], max[3];
-
- if (ob->runtime.bb == NULL) {
- ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox");
+ if (ob->runtime.bb == nullptr) {
+ ob->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), "GPencil boundbox");
}
- bb = ob->runtime.bb;
- gpd = ob->data;
+ BoundBox *bb = ob->runtime.bb;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ float3 min;
+ float3 max;
if (!BKE_gpencil_data_minmax(gpd, min, max)) {
- min[0] = min[1] = min[2] = -1.0f;
- max[0] = max[1] = max[2] = 1.0f;
+ min = float3(-1);
+ max = float3(1);
}
BKE_boundbox_init_from_minmax(bb, min, max);
@@ -181,8 +190,8 @@ static void boundbox_gpencil(Object *ob)
*/
BoundBox *BKE_gpencil_boundbox_get(Object *ob)
{
- if (ELEM(NULL, ob, ob->data)) {
- return NULL;
+ if (ELEM(nullptr, ob, ob->data)) {
+ return nullptr;
}
bGPdata *gpd = (bGPdata *)ob->data;
@@ -196,9 +205,9 @@ BoundBox *BKE_gpencil_boundbox_get(Object *ob)
/* Update orig object's boundbox with re-computed evaluated values. This function can be
* called with the evaluated object and need update the original object bound box data
* to keep both values synchronized. */
- if (!ELEM(ob_orig, NULL, ob)) {
- if (ob_orig->runtime.bb == NULL) {
- ob_orig->runtime.bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox");
+ if (!ELEM(ob_orig, nullptr, ob)) {
+ if (ob_orig->runtime.bb == nullptr) {
+ ob_orig->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), "GPencil boundbox");
}
for (int i = 0; i < 8; i++) {
copy_v3_v3(ob_orig->runtime.bb->vec[i], ob->runtime.bb->vec[i]);
@@ -227,7 +236,7 @@ static int stroke_march_next_point(const bGPDstroke *gps,
float step_start[3];
float point[3];
int next_point_index = index_next_pt;
- bGPDspoint *pt = NULL;
+ bGPDspoint *pt = nullptr;
if (!(next_point_index < gps->totpoints)) {
return -1;
@@ -295,7 +304,7 @@ static int stroke_march_next_point_no_interp(const bGPDstroke *gps,
float step_start[3];
float point[3];
int next_point_index = index_next_pt;
- bGPDspoint *pt = NULL;
+ bGPDspoint *pt = nullptr;
if (!(next_point_index < gps->totpoints)) {
return -1;
@@ -336,7 +345,7 @@ static int stroke_march_count(const bGPDstroke *gps, const float dist)
int point_count = 0;
float point[3];
int next_point_index = 1;
- bGPDspoint *pt = NULL;
+ bGPDspoint *pt = nullptr;
pt = &gps->points[0];
copy_v3_v3(point, &pt->x);
@@ -369,14 +378,14 @@ static void stroke_defvert_create_nr_list(MDeformVert *dv_list,
for (j = 0; j < dv->totweight; j++) {
bool found = false;
dw = &dv->dw[j];
- for (ld = result->first; ld; ld = ld->next) {
+ for (ld = (LinkData *)result->first; ld; ld = ld->next) {
if (ld->data == POINTER_FROM_INT(dw->def_nr)) {
found = true;
break;
}
}
if (!found) {
- ld = MEM_callocN(sizeof(LinkData), "def_nr_item");
+ ld = (LinkData *)MEM_callocN(sizeof(LinkData), "def_nr_item");
ld->data = POINTER_FROM_INT(dw->def_nr);
BLI_addtail(result, ld);
tw++;
@@ -391,14 +400,15 @@ static MDeformVert *stroke_defvert_new_count(int count, int totweight, ListBase
{
int i, j;
LinkData *ld;
- MDeformVert *dst = MEM_mallocN(count * sizeof(MDeformVert), "new_deformVert");
+ MDeformVert *dst = (MDeformVert *)MEM_mallocN(count * sizeof(MDeformVert), "new_deformVert");
for (i = 0; i < count; i++) {
- dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * totweight, "new_deformWeight");
+ dst[i].dw = (MDeformWeight *)MEM_mallocN(sizeof(MDeformWeight) * totweight,
+ "new_deformWeight");
dst[i].totweight = totweight;
j = 0;
/* re-assign deform groups */
- for (ld = def_nr_list->first; ld; ld = ld->next) {
+ for (ld = (LinkData *)def_nr_list->first; ld; ld = ld->next) {
dst[i].dw[j].def_nr = POINTER_AS_INT(ld->data);
j++;
}
@@ -429,10 +439,10 @@ static void stroke_interpolate_deform_weights(
bool BKE_gpencil_stroke_sample(bGPdata *gpd, bGPDstroke *gps, const float dist, const bool select)
{
bGPDspoint *pt = gps->points;
- bGPDspoint *pt1 = NULL;
- bGPDspoint *pt2 = NULL;
+ bGPDspoint *pt1 = nullptr;
+ bGPDspoint *pt2 = nullptr;
LinkData *ld;
- ListBase def_nr_list = {0};
+ ListBase def_nr_list = {nullptr};
if (gps->totpoints < 2 || dist < FLT_EPSILON) {
return false;
@@ -440,12 +450,13 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, bGPDstroke *gps, const float dist,
/* TODO: Implement feature point preservation. */
int count = stroke_march_count(gps, dist);
- bGPDspoint *new_pt = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points_sampled");
- MDeformVert *new_dv = NULL;
+ bGPDspoint *new_pt = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * count,
+ "gp_stroke_points_sampled");
+ MDeformVert *new_dv = nullptr;
int result_totweight;
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
stroke_defvert_create_nr_list(gps->dvert, gps->totpoints, &def_nr_list, &result_totweight);
new_dv = stroke_defvert_new_count(count, result_totweight, &def_nr_list);
}
@@ -513,7 +524,7 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, bGPDstroke *gps, const float dist,
/* Free original weight data. */
BKE_gpencil_free_stroke_weights(gps);
MEM_freeN(gps->dvert);
- while ((ld = BLI_pophead(&def_nr_list))) {
+ while ((ld = (LinkData *)BLI_pophead(&def_nr_list))) {
MEM_freeN(ld);
}
@@ -610,26 +621,27 @@ bool BKE_gpencil_stroke_trim_points(bGPDstroke *gps, const int index_from, const
if (new_count == 1) {
BKE_gpencil_free_stroke_weights(gps);
MEM_freeN(gps->points);
- gps->points = NULL;
- gps->dvert = NULL;
+ gps->points = nullptr;
+ gps->dvert = nullptr;
gps->totpoints = 0;
return false;
}
- new_pt = MEM_callocN(sizeof(bGPDspoint) * new_count, "gp_stroke_points_trimmed");
+ new_pt = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * new_count, "gp_stroke_points_trimmed");
for (int i = 0; i < new_count; i++) {
memcpy(&new_pt[i], &pt[i + index_from], sizeof(bGPDspoint));
}
if (gps->dvert) {
- new_dv = MEM_callocN(sizeof(MDeformVert) * new_count, "gp_stroke_dverts_trimmed");
+ new_dv = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * new_count,
+ "gp_stroke_dverts_trimmed");
for (int i = 0; i < new_count; i++) {
dv = &gps->dvert[i + index_from];
new_dv[i].flag = dv->flag;
new_dv[i].totweight = dv->totweight;
- new_dv[i].dw = MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
- "gp_stroke_dverts_dw_trimmed");
+ new_dv[i].dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
+ "gp_stroke_dverts_dw_trimmed");
for (int j = 0; j < dv->totweight; j++) {
new_dv[i].dw[j].weight = dv->dw[j].weight;
new_dv[i].dw[j].def_nr = dv->dw[j].def_nr;
@@ -685,14 +697,14 @@ bool BKE_gpencil_stroke_split(bGPdata *gpd,
}
if (gps->dvert) {
- new_dv = MEM_callocN(sizeof(MDeformVert) * new_count,
- "gp_stroke_dverts_remaining(MDeformVert)");
+ new_dv = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * new_count,
+ "gp_stroke_dverts_remaining(MDeformVert)");
for (int i = 0; i < new_count; i++) {
dv = &gps->dvert[i + before_index];
new_dv[i].flag = dv->flag;
new_dv[i].totweight = dv->totweight;
- new_dv[i].dw = MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
- "gp_stroke_dverts_dw_remaining(MDeformWeight)");
+ new_dv[i].dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
+ "gp_stroke_dverts_dw_remaining(MDeformWeight)");
for (int j = 0; j < dv->totweight; j++) {
new_dv[i].dw[j].weight = dv->dw[j].weight;
new_dv[i].dw[j].def_nr = dv->dw[j].def_nr;
@@ -1301,11 +1313,12 @@ void BKE_gpencil_stroke_fill_triangulate(bGPDstroke *gps)
/* allocate memory for temporary areas */
gps->tot_triangles = gps->totpoints - 2;
- uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles,
- "GP Stroke temp triangulation");
- float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints,
- "GP Stroke temp 2d points");
- float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data");
+ uint(*tmp_triangles)[3] = (uint(*)[3])MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles,
+ "GP Stroke temp triangulation");
+ float(*points2d)[2] = (float(*)[2])MEM_mallocN(sizeof(*points2d) * gps->totpoints,
+ "GP Stroke temp 2d points");
+ float(*uv)[2] = (float(*)[2])MEM_mallocN(sizeof(*uv) * gps->totpoints,
+ "GP Stroke temp 2d uv data");
int direction = 0;
@@ -1326,8 +1339,8 @@ void BKE_gpencil_stroke_fill_triangulate(bGPDstroke *gps)
/* Save triangulation data. */
if (gps->tot_triangles > 0) {
MEM_SAFE_FREE(gps->triangles);
- gps->triangles = MEM_callocN(sizeof(*gps->triangles) * gps->tot_triangles,
- "GP Stroke triangulation");
+ gps->triangles = (bGPDtriangle *)MEM_callocN(sizeof(*gps->triangles) * gps->tot_triangles,
+ "GP Stroke triangulation");
for (int i = 0; i < gps->tot_triangles; i++) {
memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3]));
@@ -1344,7 +1357,7 @@ void BKE_gpencil_stroke_fill_triangulate(bGPDstroke *gps)
MEM_freeN(gps->triangles);
}
- gps->triangles = NULL;
+ gps->triangles = nullptr;
}
/* clear memory */
@@ -1359,7 +1372,7 @@ void BKE_gpencil_stroke_fill_triangulate(bGPDstroke *gps)
*/
void BKE_gpencil_stroke_uv_update(bGPDstroke *gps)
{
- if (gps == NULL || gps->totpoints == 0) {
+ if (gps == nullptr || gps->totpoints == 0) {
return;
}
@@ -1379,11 +1392,11 @@ void BKE_gpencil_stroke_uv_update(bGPDstroke *gps)
*/
void BKE_gpencil_stroke_geometry_update(bGPdata *gpd, bGPDstroke *gps)
{
- if (gps == NULL) {
+ if (gps == nullptr) {
return;
}
- if (gps->editcurve != NULL) {
+ if (gps->editcurve != nullptr) {
if (GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd)) {
/* curve geometry was updated: stroke needs recalculation */
if (gps->flag & GP_STROKE_NEEDS_CURVE_UPDATE) {
@@ -1519,20 +1532,20 @@ bool BKE_gpencil_stroke_trim(bGPdata *gpd, bGPDstroke *gps)
if (intersect) {
/* save points */
- bGPDspoint *old_points = MEM_dupallocN(gps->points);
- MDeformVert *old_dvert = NULL;
- MDeformVert *dvert_src = NULL;
+ bGPDspoint *old_points = (bGPDspoint *)MEM_dupallocN(gps->points);
+ MDeformVert *old_dvert = nullptr;
+ MDeformVert *dvert_src = nullptr;
- if (gps->dvert != NULL) {
- old_dvert = MEM_dupallocN(gps->dvert);
+ if (gps->dvert != nullptr) {
+ old_dvert = (MDeformVert *)MEM_dupallocN(gps->dvert);
}
/* resize gps */
int newtot = end - start + 1;
- gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
- if (gps->dvert != NULL) {
- gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
+ gps->points = (bGPDspoint *)MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
+ if (gps->dvert != nullptr) {
+ gps->dvert = (MDeformVert *)MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
}
for (int i = 0; i < newtot; i++) {
@@ -1540,7 +1553,7 @@ bool BKE_gpencil_stroke_trim(bGPdata *gpd, bGPDstroke *gps)
bGPDspoint *pt_src = &old_points[idx];
bGPDspoint *pt_new = &gps->points[i];
memcpy(pt_new, pt_src, sizeof(bGPDspoint));
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert_src = &old_dvert[idx];
MDeformVert *dvert = &gps->dvert[i];
memcpy(dvert, dvert_src, sizeof(MDeformVert));
@@ -1570,8 +1583,8 @@ bool BKE_gpencil_stroke_trim(bGPdata *gpd, bGPDstroke *gps)
*/
bool BKE_gpencil_stroke_close(bGPDstroke *gps)
{
- bGPDspoint *pt1 = NULL;
- bGPDspoint *pt2 = NULL;
+ bGPDspoint *pt1 = nullptr;
+ bGPDspoint *pt2 = nullptr;
/* Only can close a stroke with 3 points or more. */
if (gps->totpoints < 3) {
@@ -1605,9 +1618,9 @@ bool BKE_gpencil_stroke_close(bGPDstroke *gps)
/* Resize stroke array. */
int old_tot = gps->totpoints;
gps->totpoints += tot_newpoints;
- gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints);
- if (gps->dvert != NULL) {
- gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
+ gps->points = (bGPDspoint *)MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints);
+ if (gps->dvert != nullptr) {
+ gps->dvert = (MDeformVert *)MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
}
/* Generate new points */
@@ -1629,7 +1642,7 @@ bool BKE_gpencil_stroke_close(bGPDstroke *gps)
interp_v4_v4v4(pt->vert_color, pt1->vert_color, pt2->vert_color, step);
/* Set weights. */
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
MDeformVert *dvert1 = &gps->dvert[old_tot - 1];
MDeformWeight *dw1 = BKE_defvert_ensure_index(dvert1, 0);
float weight_1 = dw1 ? dw1->weight : 0.0f;
@@ -1663,7 +1676,7 @@ bool BKE_gpencil_stroke_close(bGPDstroke *gps)
void BKE_gpencil_dissolve_points(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps, const short tag)
{
bGPDspoint *pt;
- MDeformVert *dvert = NULL;
+ MDeformVert *dvert = nullptr;
int i;
int tot = gps->totpoints; /* number of points in new buffer */
@@ -1693,30 +1706,32 @@ void BKE_gpencil_dissolve_points(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps,
}
else {
/* just copy all points to keep into a smaller buffer */
- bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy");
+ bGPDspoint *new_points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * tot,
+ "new gp stroke points copy");
bGPDspoint *npt = new_points;
- MDeformVert *new_dvert = NULL;
- MDeformVert *ndvert = NULL;
+ MDeformVert *new_dvert = nullptr;
+ MDeformVert *ndvert = nullptr;
- if (gps->dvert != NULL) {
- new_dvert = MEM_callocN(sizeof(MDeformVert) * tot, "new gp stroke weights copy");
+ if (gps->dvert != nullptr) {
+ new_dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * tot,
+ "new gp stroke weights copy");
ndvert = new_dvert;
}
- (gps->dvert != NULL) ? dvert = gps->dvert : NULL;
+ (gps->dvert != nullptr) ? dvert = gps->dvert : nullptr;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if ((pt->flag & tag) == 0) {
*npt = *pt;
npt++;
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
*ndvert = *dvert;
- ndvert->dw = MEM_dupallocN(dvert->dw);
+ ndvert->dw = (MDeformWeight *)MEM_dupallocN(dvert->dw);
ndvert++;
}
}
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert++;
}
}
@@ -1789,15 +1804,15 @@ void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3])
*/
void BKE_gpencil_stroke_simplify_adaptive(bGPdata *gpd, bGPDstroke *gps, float epsilon)
{
- bGPDspoint *old_points = MEM_dupallocN(gps->points);
+ bGPDspoint *old_points = (bGPDspoint *)MEM_dupallocN(gps->points);
int totpoints = gps->totpoints;
- char *marked = NULL;
+ char *marked = nullptr;
char work;
int start = 0;
int end = gps->totpoints - 1;
- marked = MEM_callocN(totpoints, "GP marked array");
+ marked = (char *)MEM_callocN(totpoints, "GP marked array");
marked[start] = 1;
marked[end] = 1;
@@ -1849,11 +1864,11 @@ void BKE_gpencil_stroke_simplify_adaptive(bGPdata *gpd, bGPDstroke *gps, float e
}
/* adding points marked */
- MDeformVert *old_dvert = NULL;
- MDeformVert *dvert_src = NULL;
+ MDeformVert *old_dvert = nullptr;
+ MDeformVert *dvert_src = nullptr;
- if (gps->dvert != NULL) {
- old_dvert = MEM_dupallocN(gps->dvert);
+ if (gps->dvert != nullptr) {
+ old_dvert = (MDeformVert *)MEM_dupallocN(gps->dvert);
}
/* resize gps */
int j = 0;
@@ -1863,7 +1878,7 @@ void BKE_gpencil_stroke_simplify_adaptive(bGPdata *gpd, bGPDstroke *gps, float e
if ((marked[i]) || (i == 0) || (i == totpoints - 1)) {
memcpy(pt, pt_src, sizeof(bGPDspoint));
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert_src = &old_dvert[i];
MDeformVert *dvert = &gps->dvert[j];
memcpy(dvert, dvert_src, sizeof(MDeformVert));
@@ -1874,7 +1889,7 @@ void BKE_gpencil_stroke_simplify_adaptive(bGPdata *gpd, bGPDstroke *gps, float e
j++;
}
else {
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert_src = &old_dvert[i];
BKE_gpencil_free_point_weights(dvert_src);
}
@@ -1903,12 +1918,12 @@ void BKE_gpencil_stroke_simplify_fixed(bGPdata *gpd, bGPDstroke *gps)
}
/* save points */
- bGPDspoint *old_points = MEM_dupallocN(gps->points);
- MDeformVert *old_dvert = NULL;
- MDeformVert *dvert_src = NULL;
+ bGPDspoint *old_points = (bGPDspoint *)MEM_dupallocN(gps->points);
+ MDeformVert *old_dvert = nullptr;
+ MDeformVert *dvert_src = nullptr;
- if (gps->dvert != NULL) {
- old_dvert = MEM_dupallocN(gps->dvert);
+ if (gps->dvert != nullptr) {
+ old_dvert = (MDeformVert *)MEM_dupallocN(gps->dvert);
}
/* resize gps */
@@ -1918,9 +1933,9 @@ void BKE_gpencil_stroke_simplify_fixed(bGPdata *gpd, bGPDstroke *gps)
}
newtot += 2;
- gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
- if (gps->dvert != NULL) {
- gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
+ gps->points = (bGPDspoint *)MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
+ if (gps->dvert != nullptr) {
+ gps->dvert = (MDeformVert *)MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
}
int j = 0;
@@ -1930,7 +1945,7 @@ void BKE_gpencil_stroke_simplify_fixed(bGPdata *gpd, bGPDstroke *gps)
if ((i == 0) || (i == gps->totpoints - 1) || ((i % 2) > 0.0)) {
memcpy(pt, pt_src, sizeof(bGPDspoint));
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert_src = &old_dvert[i];
MDeformVert *dvert = &gps->dvert[j];
memcpy(dvert, dvert_src, sizeof(MDeformVert));
@@ -1941,7 +1956,7 @@ void BKE_gpencil_stroke_simplify_fixed(bGPdata *gpd, bGPDstroke *gps)
j++;
}
else {
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert_src = &old_dvert[i];
BKE_gpencil_free_point_weights(dvert_src);
}
@@ -1966,25 +1981,25 @@ void BKE_gpencil_stroke_simplify_fixed(bGPdata *gpd, bGPDstroke *gps)
void BKE_gpencil_stroke_subdivide(bGPdata *gpd, bGPDstroke *gps, int level, int type)
{
bGPDspoint *temp_points;
- MDeformVert *temp_dverts = NULL;
- MDeformVert *dvert = NULL;
- MDeformVert *dvert_final = NULL;
- MDeformVert *dvert_next = NULL;
+ MDeformVert *temp_dverts = nullptr;
+ MDeformVert *dvert = nullptr;
+ MDeformVert *dvert_final = nullptr;
+ MDeformVert *dvert_next = nullptr;
int totnewpoints, oldtotpoints;
int i2;
for (int s = 0; s < level; s++) {
totnewpoints = gps->totpoints - 1;
/* duplicate points in a temp area */
- temp_points = MEM_dupallocN(gps->points);
+ temp_points = (bGPDspoint *)MEM_dupallocN(gps->points);
oldtotpoints = gps->totpoints;
/* resize the points arrays */
gps->totpoints += totnewpoints;
- gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints);
- if (gps->dvert != NULL) {
- temp_dverts = MEM_dupallocN(gps->dvert);
- gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
+ gps->points = (bGPDspoint *)MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints);
+ if (gps->dvert != nullptr) {
+ temp_dverts = (MDeformVert *)MEM_dupallocN(gps->dvert);
+ gps->dvert = (MDeformVert *)MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
}
/* move points from last to first to new place */
@@ -2002,7 +2017,7 @@ void BKE_gpencil_stroke_subdivide(bGPdata *gpd, bGPDstroke *gps, int level, int
pt_final->runtime.idx_orig = pt->runtime.idx_orig;
copy_v4_v4(pt_final->vert_color, pt->vert_color);
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert = &temp_dverts[i];
dvert_final = &gps->dvert[i2];
dvert_final->totweight = dvert->totweight;
@@ -2023,17 +2038,17 @@ void BKE_gpencil_stroke_subdivide(bGPdata *gpd, bGPDstroke *gps, int level, int
pt_final->strength = interpf(pt->strength, next->strength, 0.5f);
CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt_final->time = interpf(pt->time, next->time, 0.5f);
- pt_final->runtime.pt_orig = NULL;
+ pt_final->runtime.pt_orig = nullptr;
pt_final->flag = 0;
interp_v4_v4v4(pt_final->vert_color, pt->vert_color, next->vert_color, 0.5f);
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
dvert = &temp_dverts[i];
dvert_next = &temp_dverts[i + 1];
dvert_final = &gps->dvert[i2];
dvert_final->totweight = dvert->totweight;
- dvert_final->dw = MEM_dupallocN(dvert->dw);
+ dvert_final->dw = (MDeformWeight *)MEM_dupallocN(dvert->dw);
/* interpolate weight values */
for (int d = 0; d < dvert->totweight; d++) {
@@ -2055,7 +2070,7 @@ void BKE_gpencil_stroke_subdivide(bGPdata *gpd, bGPDstroke *gps, int level, int
/* Move points to smooth stroke (not simple type). */
if (type != GP_SUBDIV_SIMPLE) {
/* duplicate points in a temp area with the new subdivide data */
- temp_points = MEM_dupallocN(gps->points);
+ temp_points = (bGPDspoint *)MEM_dupallocN(gps->points);
/* extreme points are not changed */
for (int i = 0; i < gps->totpoints - 2; i++) {
@@ -2093,8 +2108,8 @@ void BKE_gpencil_stroke_merge_distance(bGPdata *gpd,
const float threshold,
const bool use_unselected)
{
- bGPDspoint *pt = NULL;
- bGPDspoint *pt_next = NULL;
+ bGPDspoint *pt = nullptr;
+ bGPDspoint *pt_next = nullptr;
float tagged = false;
/* Use square distance to speed up loop */
const float th_square = threshold * threshold;
@@ -2160,7 +2175,7 @@ void BKE_gpencil_stroke_merge_distance(bGPdata *gpd,
BKE_gpencil_stroke_geometry_update(gpd, gps);
}
-typedef struct GpEdge {
+struct GpEdge {
uint v1, v2;
/* Coordinates. */
float v1_co[3], v2_co[3];
@@ -2169,7 +2184,7 @@ typedef struct GpEdge {
/* Direction of the segment. */
float vec[3];
int flag;
-} GpEdge;
+};
static int gpencil_next_edge(
GpEdge *gp_edges, int totedges, GpEdge *gped_init, const float threshold, const bool reverse)
@@ -2262,13 +2277,13 @@ static void gpencil_generate_edgeloops(Object *ob,
/* Arrays for all edge vertices (forward and backward) that form a edge loop.
* This is reused for each edgeloop to create gpencil stroke. */
- uint *stroke = MEM_callocN(sizeof(uint) * me->totedge * 2, __func__);
- uint *stroke_fw = MEM_callocN(sizeof(uint) * me->totedge, __func__);
- uint *stroke_bw = MEM_callocN(sizeof(uint) * me->totedge, __func__);
+ uint *stroke = (uint *)MEM_callocN(sizeof(uint) * me->totedge * 2, __func__);
+ uint *stroke_fw = (uint *)MEM_callocN(sizeof(uint) * me->totedge, __func__);
+ uint *stroke_bw = (uint *)MEM_callocN(sizeof(uint) * me->totedge, __func__);
/* Create array with all edges. */
- GpEdge *gp_edges = MEM_callocN(sizeof(GpEdge) * me->totedge, __func__);
- GpEdge *gped = NULL;
+ GpEdge *gp_edges = (GpEdge *)MEM_callocN(sizeof(GpEdge) * me->totedge, __func__);
+ GpEdge *gped = nullptr;
for (int i = 0; i < me->totedge; i++) {
MEdge *ed = &me->medge[i];
gped = &gp_edges[i];
@@ -2321,7 +2336,7 @@ static void gpencil_generate_edgeloops(Object *ob,
/* Look backward edges. */
int totbw = gpencil_walk_edge(v_table, gp_edges, me->totedge, stroke_bw, e, angle, true);
- BLI_ghash_free(v_table, NULL, NULL);
+ BLI_ghash_free(v_table, nullptr, nullptr);
/* Join both arrays. */
int array_len = 0;
@@ -2423,7 +2438,7 @@ static int gpencil_material_find_index_by_name(Object *ob, const char *name)
{
for (int i = 0; i < ob->totcol; i++) {
Material *ma = BKE_object_material_get(ob, i + 1);
- if ((ma != NULL) && (ma->gp_style != NULL) && (STREQ(ma->id.name + 2, name))) {
+ if ((ma != nullptr) && (ma->gp_style != nullptr) && (STREQ(ma->id.name + 2, name))) {
return i;
}
}
@@ -2474,7 +2489,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
const bool use_seams,
const bool use_faces)
{
- if (ELEM(NULL, ob_gp, ob_mesh) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
+ if (ELEM(nullptr, ob_gp, ob_mesh) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == nullptr)) {
return false;
}
@@ -2511,7 +2526,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
make_element_name(ob_mesh->id.name + 2, "Fills", 128, element_name);
/* Create Layer and Frame. */
bGPDlayer *gpl_fill = BKE_gpencil_layer_named_get(gpd, element_name);
- if (gpl_fill == NULL) {
+ if (gpl_fill == nullptr) {
gpl_fill = BKE_gpencil_layer_addnew(gpd, element_name, true, false);
}
bGPDframe *gpf_fill = BKE_gpencil_layer_frame_get(
@@ -2524,11 +2539,11 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
int mat_idx = 0;
Material *ma = BKE_object_material_get(ob_mesh, mp->mat_nr + 1);
make_element_name(
- ob_mesh->id.name + 2, (ma != NULL) ? ma->id.name + 2 : "Fill", 64, element_name);
+ ob_mesh->id.name + 2, (ma != nullptr) ? ma->id.name + 2 : "Fill", 64, element_name);
mat_idx = BKE_gpencil_material_find_index_by_name_prefix(ob_gp, element_name);
if (mat_idx == -1) {
float color[4];
- if (ma != NULL) {
+ if (ma != nullptr) {
copy_v3_v3(color, &ma->r);
color[3] = 1.0f;
}
@@ -2567,7 +2582,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
/* Create Layer and Frame. */
bGPDlayer *gpl_stroke = BKE_gpencil_layer_named_get(gpd, element_name);
- if (gpl_stroke == NULL) {
+ if (gpl_stroke == nullptr) {
gpl_stroke = BKE_gpencil_layer_addnew(gpd, element_name, true, false);
}
bGPDframe *gpf_stroke = BKE_gpencil_layer_frame_get(
@@ -2589,7 +2604,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
*/
void BKE_gpencil_transform(bGPdata *gpd, const float mat[4][4])
{
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return;
}
@@ -2625,7 +2640,7 @@ int BKE_gpencil_stroke_point_count(const bGPdata *gpd)
{
int total_points = 0;
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return 0;
}
@@ -2650,7 +2665,7 @@ int BKE_gpencil_stroke_point_count(const bGPdata *gpd)
/* Used for "move only origins" in object_data_transform.c */
void BKE_gpencil_point_coords_get(bGPdata *gpd, GPencilPointCoordinates *elem_data)
{
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return;
}
@@ -2681,7 +2696,7 @@ void BKE_gpencil_point_coords_get(bGPdata *gpd, GPencilPointCoordinates *elem_da
/* Used for "move only origins" in object_data_transform.c */
void BKE_gpencil_point_coords_apply(bGPdata *gpd, const GPencilPointCoordinates *elem_data)
{
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return;
}
@@ -2717,7 +2732,7 @@ void BKE_gpencil_point_coords_apply_with_mat4(bGPdata *gpd,
const GPencilPointCoordinates *elem_data,
const float mat[4][4])
{
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return;
}
@@ -2818,24 +2833,24 @@ void BKE_gpencil_stroke_flip(bGPDstroke *gps)
* that should be kept when splitting up a stroke. Used in:
* gpencil_stroke_delete_tagged_points()
*/
-typedef struct tGPDeleteIsland {
+struct tGPDeleteIsland {
int start_idx;
int end_idx;
-} tGPDeleteIsland;
+};
static void gpencil_stroke_join_islands(bGPdata *gpd,
bGPDframe *gpf,
bGPDstroke *gps_first,
bGPDstroke *gps_last)
{
- bGPDspoint *pt = NULL;
- bGPDspoint *pt_final = NULL;
+ bGPDspoint *pt = nullptr;
+ bGPDspoint *pt_final = nullptr;
const int totpoints = gps_first->totpoints + gps_last->totpoints;
/* create new stroke */
bGPDstroke *join_stroke = BKE_gpencil_stroke_duplicate(gps_first, false, true);
- join_stroke->points = MEM_callocN(sizeof(bGPDspoint) * totpoints, __func__);
+ join_stroke->points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * totpoints, __func__);
join_stroke->totpoints = totpoints;
join_stroke->flag &= ~GP_STROKE_CYCLIC;
@@ -2868,17 +2883,17 @@ static void gpencil_stroke_join_islands(bGPdata *gpd,
}
/* Copy over vertex weight data (if available) */
- if ((gps_first->dvert != NULL) || (gps_last->dvert != NULL)) {
- join_stroke->dvert = MEM_callocN(sizeof(MDeformVert) * totpoints, __func__);
- MDeformVert *dvert_src = NULL;
- MDeformVert *dvert_dst = NULL;
+ if ((gps_first->dvert != nullptr) || (gps_last->dvert != nullptr)) {
+ join_stroke->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * totpoints, __func__);
+ MDeformVert *dvert_src = nullptr;
+ MDeformVert *dvert_dst = nullptr;
/* Copy weights (last before). */
e1 = 0;
e2 = 0;
for (int i = 0; i < totpoints; i++) {
dvert_dst = &join_stroke->dvert[i];
- dvert_src = NULL;
+ dvert_src = nullptr;
if (i < gps_last->totpoints) {
if (gps_last->dvert) {
dvert_src = &gps_last->dvert[e1];
@@ -2893,7 +2908,7 @@ static void gpencil_stroke_join_islands(bGPdata *gpd,
}
if ((dvert_src) && (dvert_src->dw)) {
- dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
+ dvert_dst->dw = (MDeformWeight *)MEM_dupallocN(dvert_src->dw);
}
}
}
@@ -2934,13 +2949,13 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
bool select,
int limit)
{
- tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2,
- "gp_point_islands");
+ tGPDeleteIsland *islands = (tGPDeleteIsland *)MEM_callocN(
+ sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2, "gp_point_islands");
bool in_island = false;
int num_islands = 0;
- bGPDstroke *new_stroke = NULL;
- bGPDstroke *gps_first = NULL;
+ bGPDstroke *new_stroke = nullptr;
+ bGPDstroke *gps_first = nullptr;
const bool is_cyclic = (bool)(gps->flag & GP_STROKE_CYCLIC);
/* First Pass: Identify start/end of islands */
@@ -2982,7 +2997,7 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
new_stroke = BKE_gpencil_stroke_duplicate(gps, false, true);
/* if cyclic and first stroke, save to join later */
- if ((is_cyclic) && (gps_first == NULL)) {
+ if ((is_cyclic) && (gps_first == nullptr)) {
gps_first = new_stroke;
}
@@ -2992,17 +3007,17 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
new_stroke->totpoints = island->end_idx - island->start_idx + 1;
/* Copy over the relevant point data */
- new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints,
- "gp delete stroke fragment");
+ new_stroke->points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints,
+ "gp delete stroke fragment");
memcpy(new_stroke->points,
gps->points + island->start_idx,
sizeof(bGPDspoint) * new_stroke->totpoints);
/* Copy over vertex weight data (if available) */
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
/* Copy over the relevant vertex-weight points */
- new_stroke->dvert = MEM_callocN(sizeof(MDeformVert) * new_stroke->totpoints,
- "gp delete stroke fragment weight");
+ new_stroke->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * new_stroke->totpoints,
+ "gp delete stroke fragment weight");
memcpy(new_stroke->dvert,
gps->dvert + island->start_idx,
sizeof(MDeformVert) * new_stroke->totpoints);
@@ -3013,7 +3028,7 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
MDeformVert *dvert_src = &gps->dvert[e];
MDeformVert *dvert_dst = &new_stroke->dvert[i];
if (dvert_src->dw) {
- dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
+ dvert_dst->dw = (MDeformWeight *)MEM_dupallocN(dvert_src->dw);
}
e++;
}
@@ -3047,7 +3062,7 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
/* Add new stroke to the frame or delete if below limit */
if ((limit > 0) && (new_stroke->totpoints <= limit)) {
if (gps_first == new_stroke) {
- gps_first = NULL;
+ gps_first = nullptr;
}
BKE_gpencil_free_stroke(new_stroke);
}
@@ -3064,7 +3079,7 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
}
}
/* if cyclic, need to join last stroke with first stroke */
- if ((is_cyclic) && (gps_first != NULL) && (gps_first != new_stroke)) {
+ if ((is_cyclic) && (gps_first != nullptr) && (gps_first != new_stroke)) {
gpencil_stroke_join_islands(gpd, gpf, gps_first, new_stroke);
}
}
@@ -3086,13 +3101,13 @@ void BKE_gpencil_curve_delete_tagged_points(bGPdata *gpd,
bGPDcurve *gpc,
int tag_flags)
{
- if (gpc == NULL) {
+ if (gpc == nullptr) {
return;
}
const bool is_cyclic = gps->flag & GP_STROKE_CYCLIC;
const int idx_last = gpc->tot_curve_points - 1;
- bGPDstroke *gps_first = NULL;
- bGPDstroke *gps_last = NULL;
+ bGPDstroke *gps_first = nullptr;
+ bGPDstroke *gps_last = nullptr;
int idx_start = 0;
int idx_end = 0;
@@ -3123,11 +3138,11 @@ void BKE_gpencil_curve_delete_tagged_points(bGPdata *gpd,
}
bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps, false, false);
- new_stroke->points = NULL;
+ new_stroke->points = nullptr;
new_stroke->flag &= ~GP_STROKE_CYCLIC;
new_stroke->editcurve = BKE_gpencil_stroke_editcurve_new(island_length);
- if (gps_first == NULL) {
+ if (gps_first == nullptr) {
gps_first = new_stroke;
}
@@ -3155,15 +3170,15 @@ void BKE_gpencil_curve_delete_tagged_points(bGPdata *gpd,
}
/* join first and last stroke if cyclic */
- if (is_cyclic && gps_first != NULL && gps_last != NULL && gps_first != gps_last) {
+ if (is_cyclic && gps_first != nullptr && gps_last != nullptr && gps_first != gps_last) {
bGPDcurve *gpc_first = gps_first->editcurve;
bGPDcurve *gpc_last = gps_last->editcurve;
int first_tot_points = gpc_first->tot_curve_points;
int old_tot_points = gpc_last->tot_curve_points;
gpc_last->tot_curve_points = first_tot_points + old_tot_points;
- gpc_last->curve_points = MEM_recallocN(gpc_last->curve_points,
- sizeof(bGPDcurve_point) * gpc_last->tot_curve_points);
+ gpc_last->curve_points = (bGPDcurve_point *)MEM_recallocN(
+ gpc_last->curve_points, sizeof(bGPDcurve_point) * gpc_last->tot_curve_points);
/* copy data from first to last */
memcpy(gpc_last->curve_points + old_tot_points,
gpc_first->curve_points,
@@ -3196,14 +3211,16 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps,
{
bGPDspoint *newpoint;
- gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
- if (gps->dvert != NULL) {
- gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * (gps->totpoints + 1));
+ gps->points = (bGPDspoint *)MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
+ if (gps->dvert != nullptr) {
+ gps->dvert = (MDeformVert *)MEM_reallocN(gps->dvert,
+ sizeof(MDeformVert) * (gps->totpoints + 1));
}
else {
/* If destination has weight add weight to origin. */
- if (dvert != NULL) {
- gps->dvert = MEM_callocN(sizeof(MDeformVert) * (gps->totpoints + 1), __func__);
+ if (dvert != nullptr) {
+ gps->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * (gps->totpoints + 1),
+ __func__);
}
}
@@ -3219,16 +3236,16 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps,
newpoint->time = point->time + deltatime;
copy_v4_v4(newpoint->vert_color, point->vert_color);
- if (gps->dvert != NULL) {
+ if (gps->dvert != nullptr) {
MDeformVert *newdvert = &gps->dvert[gps->totpoints - 1];
- if (dvert != NULL) {
+ if (dvert != nullptr) {
newdvert->totweight = dvert->totweight;
- newdvert->dw = MEM_dupallocN(dvert->dw);
+ newdvert->dw = (MDeformWeight *)MEM_dupallocN(dvert->dw);
}
else {
newdvert->totweight = 0;
- newdvert->dw = NULL;
+ newdvert->dw = nullptr;
}
}
}
@@ -3246,7 +3263,7 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
float deltatime = 0.0f;
/* sanity checks */
- if (ELEM(NULL, gps_a, gps_b)) {
+ if (ELEM(nullptr, gps_a, gps_b)) {
return;
}
@@ -3308,11 +3325,11 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
point = gps_a->points[gps_a->totpoints - 1];
deltatime = point.time;
- gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, 0.0f);
+ gpencil_stroke_copy_point(gps_a, nullptr, &point, delta, 0.0f, 0.0f, 0.0f);
/* 2nd: add one head point to finish invisible area */
point = gps_b->points[0];
- gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, deltatime);
+ gpencil_stroke_copy_point(gps_a, nullptr, &point, delta, 0.0f, 0.0f, deltatime);
}
const float ratio = (fit_thickness && gps_a->thickness > 0.0f) ?
@@ -3321,7 +3338,7 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
/* 3rd: add all points */
for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) {
- MDeformVert *dvert = (gps_b->dvert) ? &gps_b->dvert[i] : NULL;
+ MDeformVert *dvert = (gps_b->dvert) ? &gps_b->dvert[i] : nullptr;
gpencil_stroke_copy_point(
gps_a, dvert, pt, delta, pt->pressure * ratio, pt->strength, deltatime);
}
@@ -3340,16 +3357,16 @@ void BKE_gpencil_stroke_copy_to_keyframes(
if (gpf->framenum != cfra) {
bGPDframe *gpf_new = BKE_gpencil_layer_frame_find(gpl, cfra);
- if (gpf_new == NULL) {
+ if (gpf_new == nullptr) {
gpf_new = BKE_gpencil_frame_addnew(gpl, cfra);
}
- if (gpf_new == NULL) {
+ if (gpf_new == nullptr) {
continue;
}
bGPDstroke *gps_new = BKE_gpencil_stroke_duplicate(gps, true, true);
- if (gps_new == NULL) {
+ if (gps_new == nullptr) {
continue;
}
@@ -3363,38 +3380,38 @@ void BKE_gpencil_stroke_copy_to_keyframes(
}
/* Free hash table. */
- BLI_ghash_free(frame_list, NULL, NULL);
+ BLI_ghash_free(frame_list, nullptr, nullptr);
}
/* Stroke Uniform Subdivide ------------------------------------- */
-typedef struct tSamplePoint {
+struct tSamplePoint {
struct tSamplePoint *next, *prev;
float x, y, z;
float pressure, strength, time;
float vertex_color[4];
struct MDeformWeight *dw;
int totweight;
-} tSamplePoint;
+};
-typedef struct tSampleEdge {
+struct tSampleEdge {
float length_sq;
tSamplePoint *from;
tSamplePoint *to;
-} tSampleEdge;
+};
/* Helper: creates a tSamplePoint from a bGPDspoint and (optionally) a MDeformVert. */
static tSamplePoint *new_sample_point_from_gp_point(const bGPDspoint *pt, const MDeformVert *dvert)
{
- tSamplePoint *new_pt = MEM_callocN(sizeof(tSamplePoint), __func__);
+ tSamplePoint *new_pt = (tSamplePoint *)MEM_callocN(sizeof(tSamplePoint), __func__);
copy_v3_v3(&new_pt->x, &pt->x);
new_pt->pressure = pt->pressure;
new_pt->strength = pt->strength;
new_pt->time = pt->time;
copy_v4_v4((float *)&new_pt->vertex_color, (float *)&pt->vert_color);
- if (dvert != NULL) {
+ if (dvert != nullptr) {
new_pt->totweight = dvert->totweight;
- new_pt->dw = MEM_callocN(sizeof(MDeformWeight) * new_pt->totweight, __func__);
+ new_pt->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * new_pt->totweight, __func__);
for (uint i = 0; i < new_pt->totweight; ++i) {
MDeformWeight *dw = &new_pt->dw[i];
MDeformWeight *dw_from = &dvert->dw[i];
@@ -3409,7 +3426,7 @@ static tSamplePoint *new_sample_point_from_gp_point(const bGPDspoint *pt, const
* the edge. */
static tSampleEdge *new_sample_edge_from_sample_points(tSamplePoint *from, tSamplePoint *to)
{
- tSampleEdge *new_edge = MEM_callocN(sizeof(tSampleEdge), __func__);
+ tSampleEdge *new_edge = (tSampleEdge *)MEM_callocN(sizeof(tSampleEdge), __func__);
new_edge->from = from;
new_edge->to = to;
new_edge->length_sq = len_squared_v3v3(&from->x, &to->x);
@@ -3431,27 +3448,27 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
const bool select)
{
/* Stroke needs at least two points and strictly less points than the target number. */
- if (gps == NULL || gps->totpoints < 2 || gps->totpoints >= target_number) {
+ if (gps == nullptr || gps->totpoints < 2 || gps->totpoints >= target_number) {
return;
}
const int totpoints = gps->totpoints;
- const bool has_dverts = (gps->dvert != NULL);
+ const bool has_dverts = (gps->dvert != nullptr);
const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC);
- ListBase points = {NULL, NULL};
+ ListBase points = {nullptr, nullptr};
Heap *edges = BLI_heap_new();
/* Add all points into list. */
for (uint32_t i = 0; i < totpoints; ++i) {
bGPDspoint *pt = &gps->points[i];
- MDeformVert *dvert = has_dverts ? &gps->dvert[i] : NULL;
+ MDeformVert *dvert = has_dverts ? &gps->dvert[i] : nullptr;
tSamplePoint *sp = new_sample_point_from_gp_point(pt, dvert);
BLI_addtail(&points, sp);
}
/* Iterate over edges and insert them into the heap. */
- for (tSamplePoint *pt = ((tSamplePoint *)points.first)->next; pt != NULL; pt = pt->next) {
+ for (tSamplePoint *pt = ((tSamplePoint *)points.first)->next; pt != nullptr; pt = pt->next) {
tSampleEdge *se = new_sample_edge_from_sample_points(pt->prev, pt);
/* BLI_heap is a min-heap, but we need the largest key to be at the top, so we take the
* negative of the squared length. */
@@ -3459,8 +3476,8 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
}
if (is_cyclic) {
- tSamplePoint *sp_first = points.first;
- tSamplePoint *sp_last = points.last;
+ tSamplePoint *sp_first = (tSamplePoint *)points.first;
+ tSamplePoint *sp_last = (tSamplePoint *)points.last;
tSampleEdge *se = new_sample_edge_from_sample_points(sp_last, sp_first);
BLI_heap_insert(edges, -(se->length_sq), se);
}
@@ -3469,12 +3486,12 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
BLI_assert(num_points_needed > 0);
while (num_points_needed > 0) {
- tSampleEdge *se = BLI_heap_pop_min(edges);
+ tSampleEdge *se = (tSampleEdge *)BLI_heap_pop_min(edges);
tSamplePoint *sp = se->from;
tSamplePoint *sp_next = se->to;
/* Subdivide the edge. */
- tSamplePoint *new_sp = MEM_callocN(sizeof(tSamplePoint), __func__);
+ tSamplePoint *new_sp = (tSamplePoint *)MEM_callocN(sizeof(tSamplePoint), __func__);
interp_v3_v3v3(&new_sp->x, &sp->x, &sp_next->x, 0.5f);
new_sp->pressure = interpf(sp->pressure, sp_next->pressure, 0.5f);
new_sp->strength = interpf(sp->strength, sp_next->strength, 0.5f);
@@ -3485,7 +3502,8 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
0.5f);
if (sp->dw && sp_next->dw) {
new_sp->totweight = MIN2(sp->totweight, sp_next->totweight);
- new_sp->dw = MEM_callocN(sizeof(MDeformWeight) * new_sp->totweight, __func__);
+ new_sp->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * new_sp->totweight,
+ __func__);
for (uint32_t i = 0; i < new_sp->totweight; ++i) {
MDeformWeight *dw = &new_sp->dw[i];
MDeformWeight *dw_from = &sp->dw[i];
@@ -3509,13 +3527,13 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
BLI_heap_free(edges, (HeapFreeFP)MEM_freeN);
gps->totpoints = target_number;
- gps->points = MEM_recallocN(gps->points, sizeof(bGPDspoint) * gps->totpoints);
+ gps->points = (bGPDspoint *)MEM_recallocN(gps->points, sizeof(bGPDspoint) * gps->totpoints);
if (has_dverts) {
- gps->dvert = MEM_recallocN(gps->dvert, sizeof(MDeformVert) * gps->totpoints);
+ gps->dvert = (MDeformVert *)MEM_recallocN(gps->dvert, sizeof(MDeformVert) * gps->totpoints);
}
/* Convert list back to stroke point array. */
- tSamplePoint *sp = points.first;
+ tSamplePoint *sp = (tSamplePoint *)points.first;
for (uint32_t i = 0; i < gps->totpoints && sp; ++i, sp = sp->next) {
bGPDspoint *pt = &gps->points[i];
MDeformVert *dvert = &gps->dvert[i];
@@ -3528,7 +3546,7 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
if (sp->dw) {
dvert->totweight = sp->totweight;
- dvert->dw = MEM_callocN(sizeof(MDeformWeight) * dvert->totweight, __func__);
+ dvert->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dvert->totweight, __func__);
for (uint32_t j = 0; j < dvert->totweight; ++j) {
MDeformWeight *dw = &dvert->dw[j];
MDeformWeight *dw_from = &sp->dw[j];
@@ -3549,7 +3567,7 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
/* Free the sample points. Important to use the mutable loop here because we are erasing the list
* elements. */
LISTBASE_FOREACH_MUTABLE (tSamplePoint *, temp, &points) {
- if (temp->dw != NULL) {
+ if (temp->dw != nullptr) {
MEM_freeN(temp->dw);
}
MEM_SAFE_FREE(temp);
@@ -3601,14 +3619,14 @@ void BKE_gpencil_stroke_from_view_space(RegionView3D *rv3d,
/* ----------------------------------------------------------------------------- */
/* Stroke to perimeter */
-typedef struct tPerimeterPoint {
+struct tPerimeterPoint {
struct tPerimeterPoint *next, *prev;
float x, y, z;
-} tPerimeterPoint;
+};
static tPerimeterPoint *new_perimeter_point(const float pt[3])
{
- tPerimeterPoint *new_pt = MEM_callocN(sizeof(tPerimeterPoint), __func__);
+ tPerimeterPoint *new_pt = (tPerimeterPoint *)MEM_callocN(sizeof(tPerimeterPoint), __func__);
copy_v3_v3(&new_pt->x, pt);
return new_pt;
}
@@ -3771,14 +3789,14 @@ static ListBase *gpencil_stroke_perimeter_ex(const bGPdata *gpd,
{
/* sanity check */
if (gps->totpoints < 1) {
- return NULL;
+ return nullptr;
}
float defaultpixsize = 1000.0f / gpd->pixfactor;
float stroke_radius = ((gps->thickness + gpl->line_change) / defaultpixsize) / 2.0f;
- ListBase *perimeter_right_side = MEM_callocN(sizeof(ListBase), __func__);
- ListBase *perimeter_left_side = MEM_callocN(sizeof(ListBase), __func__);
+ ListBase *perimeter_right_side = (ListBase *)MEM_callocN(sizeof(ListBase), __func__);
+ ListBase *perimeter_left_side = (ListBase *)MEM_callocN(sizeof(ListBase), __func__);
int num_perimeter_points = 0;
bGPDspoint *first = &gps->points[0];
@@ -4018,7 +4036,7 @@ bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d,
const float diff_mat[4][4])
{
if (gps->totpoints == 0) {
- return NULL;
+ return nullptr;
}
bGPDstroke *gps_temp = BKE_gpencil_stroke_duplicate(gps, true, false);
const bool cyclic = ((gps_temp->flag & GP_STROKE_CYCLIC) != 0);
@@ -4026,8 +4044,8 @@ bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d,
/* If Cyclic, add a new point. */
if (cyclic && (gps_temp->totpoints > 1)) {
gps_temp->totpoints++;
- gps_temp->points = MEM_recallocN(gps_temp->points,
- sizeof(*gps_temp->points) * gps_temp->totpoints);
+ gps_temp->points = (bGPDspoint *)MEM_recallocN(
+ gps_temp->points, sizeof(*gps_temp->points) * gps_temp->totpoints);
bGPDspoint *pt_src = &gps_temp->points[0];
bGPDspoint *pt_dst = &gps_temp->points[gps_temp->totpoints - 1];
copy_v3_v3(&pt_dst->x, &pt_src->x);
@@ -4043,7 +4061,7 @@ bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d,
gpd, gpl, gps_temp, subdivisions, &num_perimeter_points);
if (num_perimeter_points == 0) {
- return NULL;
+ return nullptr;
}
/* Create new stroke. */
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 0e2219e6c7f..4db527e5b42 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -273,7 +273,7 @@ int BKE_gpencil_time_modifier_cfra(Depsgraph *depsgraph,
if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
- if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
+ if (GPENCIL_MODIFIER_EDIT(md, is_edit) && (!is_render)) {
continue;
}
@@ -838,7 +838,7 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
- if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
+ if (GPENCIL_MODIFIER_EDIT(md, is_edit) && (!is_render)) {
continue;
}
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index af0047680f2..81c161a4a7d 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -937,7 +937,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
ListBase isect_remedgebase = {NULL, NULL};
/* now we have all the splines */
- face_coords = MEM_mallocN((sizeof(float[3])) * sf_vert_tot, "maskrast_face_coords");
+ face_coords = MEM_mallocN(sizeof(float[3]) * sf_vert_tot, "maskrast_face_coords");
/* init bounds */
BLI_rctf_init_minmax(&bounds);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 4102703ca7c..b463d903303 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -312,7 +312,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
mesh->totselect = 0;
}
- if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) {
+ if (BLO_read_requires_endian_switch(reader) && mesh->tface) {
TFace *tf = mesh->tface;
for (int i = 0; i < mesh->totface; i++, tf++) {
BLI_endian_switch_uint32_array(tf->col, 4);
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index c2c7b317171..dbea83ae0ca 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -506,7 +506,7 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
if (node->storage) {
/* could be handlerized at some point, now only 1 exception still */
- if ((ELEM(ntree->type, NTREE_SHADER, NTREE_GEOMETRY)) &&
+ 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);
}
@@ -3143,7 +3143,7 @@ static void free_localized_node_groups(bNodeTree *ntree)
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) {
+ if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
bNodeTree *ngroup = (bNodeTree *)node->id;
ntreeFreeTree(ngroup);
MEM_freeN(ngroup);
@@ -3335,7 +3335,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
ltree->id.tag |= LIB_TAG_LOCALIZED;
LISTBASE_FOREACH (bNode *, node, &ltree->nodes) {
- if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) {
+ if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
node->id = (ID *)ntreeLocalize((bNodeTree *)node->id);
}
}
@@ -5121,6 +5121,7 @@ static void registerGeometryNodes()
register_node_type_geo_curve_subdivide();
register_node_type_geo_curve_to_mesh();
register_node_type_geo_curve_to_points();
+ register_node_type_geo_curve_trim();
register_node_type_geo_delete_geometry();
register_node_type_geo_edge_split();
register_node_type_geo_input_material();
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 87d8825ad90..9652622d4a1 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -410,7 +410,7 @@ Spline::LookupResult Spline::lookup_evaluated_length(const float length) const
const float *offset = std::lower_bound(lengths.begin(), lengths.end(), length);
const int index = offset - lengths.begin();
- const int next_index = (index == this->size() - 1) ? 0 : index + 1;
+ const int next_index = (index == this->evaluated_points_size() - 1) ? 0 : index + 1;
const float previous_length = (index == 0) ? 0.0f : lengths[index - 1];
const float factor = (length - previous_length) / (lengths[index] - previous_length);
diff --git a/source/blender/blenlib/BLI_delaunay_2d.h b/source/blender/blenlib/BLI_delaunay_2d.h
index d42bd6af637..5a8ddfb5a92 100644
--- a/source/blender/blenlib/BLI_delaunay_2d.h
+++ b/source/blender/blenlib/BLI_delaunay_2d.h
@@ -110,6 +110,10 @@ extern "C" {
* If zero is supplied for epsilon, an internal value of 1e-8 used
* instead, since this code will not work correctly if it is not allowed
* to merge "too near" vertices.
+ *
+ * Normally the output will contain mappings from outputs to inputs.
+ * If this is not needed, set need_ids to false and the execution may be much
+ * faster in some circumstances.
*/
typedef struct CDT_input {
int verts_len;
@@ -121,6 +125,7 @@ typedef struct CDT_input {
int *faces_start_table;
int *faces_len_table;
float epsilon;
+ bool need_ids;
} CDT_input;
/**
@@ -140,6 +145,7 @@ typedef struct CDT_input {
* a run-together array and a "start" and "len" extra array,
* similar triples are used to represent the output to input
* mapping of vertices, edges, and faces.
+ * These are only set if need_ids is true in the input.
*
* Those triples are:
* - verts_orig, verts_orig_start_table, verts_orig_len_table
@@ -236,6 +242,7 @@ template<typename Arith_t> class CDT_input {
Array<std::pair<int, int>> edge;
Array<Vector<int>> face;
Arith_t epsilon{0};
+ bool need_ids{true};
};
template<typename Arith_t> class CDT_result {
@@ -243,6 +250,7 @@ template<typename Arith_t> class CDT_result {
Array<vec2<Arith_t>> vert;
Array<std::pair<int, int>> edge;
Array<Vector<int>> face;
+ /* The orig vectors are only popluated if the need_ids input field is true. */
/** For each output vert, which input verts correspond to it? */
Array<Vector<int>> vert_orig;
/**
diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc
index 24a58103a10..362dbdf15c5 100644
--- a/source/blender/blenlib/intern/delaunay_2d.cc
+++ b/source/blender/blenlib/intern/delaunay_2d.cc
@@ -19,6 +19,7 @@
*/
#include <algorithm>
+#include <atomic>
#include <fstream>
#include <iostream>
#include <sstream>
@@ -29,6 +30,8 @@
#include "BLI_math_boolean.hh"
#include "BLI_math_mpq.hh"
#include "BLI_mpq2.hh"
+#include "BLI_set.hh"
+#include "BLI_task.hh"
#include "BLI_vector.hh"
#include "BLI_delaunay_2d.h"
@@ -77,8 +80,8 @@ template<> double math_to_double<double>(const double v)
* Define a templated 2D arrangement of vertices, edges, and faces.
* The #SymEdge data structure is the basis for a structure that allows
* easy traversal to neighboring (by topology) geometric elements.
- * Each of #CDTVert, #CDTEdge, and #CDTFace have an input_id linked list,
- * whose nodes contain integers that keep track of which input verts, edges,
+ * Each of #CDTVert, #CDTEdge, and #CDTFace have an input_id set,
+ * which contain integers that keep track of which input verts, edges,
* and faces, respectively, that the element was derived from.
*
* While this could be cleaned up some, it is usable by other routines in Blender
@@ -195,8 +198,8 @@ template<typename T> struct CDTVert {
FatCo<T> co;
/** Some edge attached to it. */
SymEdge<T> *symedge{nullptr};
- /** List of corresponding vertex input ids. */
- LinkNode *input_ids{nullptr};
+ /** Set of corresponding vertex input ids. Not used if don't need_ids. */
+ blender::Set<int> input_ids;
/** Index into array that #CDTArrangement keeps. */
int index{-1};
/** Index of a CDTVert that this has merged to. -1 if no merge. */
@@ -209,8 +212,10 @@ template<typename T> struct CDTVert {
};
template<typename Arith_t> struct CDTEdge {
- /** List of input edge ids that this is part of. */
- LinkNode *input_ids{nullptr};
+ /** Set of input edge ids that this is part of.
+ * If don't need_ids, then should contain 0 if it is a constrained edge,
+ * else empty. */
+ blender::Set<int> input_ids;
/** The directed edges for this edge. */
SymEdge<Arith_t> symedges[2]{SymEdge<Arith_t>(), SymEdge<Arith_t>()};
@@ -220,8 +225,10 @@ template<typename Arith_t> struct CDTEdge {
template<typename Arith_t> struct CDTFace {
/** A symedge in face; only used during output, so only valid then. */
SymEdge<Arith_t> *symedge{nullptr};
- /** List of input face ids that this is part of. */
- LinkNode *input_ids{nullptr};
+ /** Set of input face ids that this is part of.
+ * If don't need_ids, then should contain 0 if it is part of a constrained face,
+ * else empty. */
+ blender::Set<int> input_ids;
/** Used by algorithms operating on CDT structures. */
int visit_index{0};
/** Marks this face no longer used. */
@@ -334,27 +341,30 @@ template<typename T> class CDT_state {
int face_edge_offset;
/** How close before coords considered equal. */
T epsilon;
+ /** Do we need to track ids? */
+ bool need_ids;
- explicit CDT_state(int num_input_verts, int num_input_edges, int num_input_faces, T epsilon);
+ explicit CDT_state(
+ int num_input_verts, int num_input_edges, int num_input_faces, T epsilon, bool need_ids);
};
template<typename T> CDTArrangement<T>::~CDTArrangement()
{
for (int i : this->verts.index_range()) {
CDTVert<T> *v = this->verts[i];
- BLI_linklist_free(v->input_ids, nullptr);
+ v->input_ids.clear();
delete v;
this->verts[i] = nullptr;
}
for (int i : this->edges.index_range()) {
CDTEdge<T> *e = this->edges[i];
- BLI_linklist_free(e->input_ids, nullptr);
+ e->input_ids.clear();
delete e;
this->edges[i] = nullptr;
}
for (int i : this->faces.index_range()) {
CDTFace<T> *f = this->faces[i];
- BLI_linklist_free(f->input_ids, nullptr);
+ f->input_ids.clear();
delete f;
this->faces[i] = nullptr;
}
@@ -495,6 +505,7 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
constexpr int vert_radius = 3;
constexpr bool draw_vert_labels = true;
constexpr bool draw_edge_labels = false;
+ constexpr bool draw_face_labels = false;
if (cdt.verts.size() == 0) {
return;
@@ -559,7 +570,7 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
const CDTVert<T> *v = e->symedges[1].vert;
const vec2<double> &uco = u->co.approx;
const vec2<double> &vco = v->co.approx;
- int strokew = e->input_ids == nullptr ? thin_line : thick_line;
+ int strokew = e->input_ids.size() == 0 ? thin_line : thick_line;
f << R"(<line fill="none" stroke="black" stroke-width=")" << strokew << "\" x1=\""
<< SX(uco[0]) << "\" y1=\"" << SY(uco[1]) << "\" x2=\"" << SX(vco[0]) << "\" y2=\""
<< SY(vco[1]) << "\">\n";
@@ -586,6 +597,54 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
++i;
}
+ if (draw_face_labels) {
+ for (const CDTFace<T> *face : cdt.faces) {
+ if (!face->deleted) {
+ /* Since may not have prepared output yet, need a slow find of a SymEdge for this face. */
+ const SymEdge<T> *se_face_start = nullptr;
+ for (const CDTEdge<T> *e : cdt.edges) {
+ if (e->symedges[0].face == face) {
+ se_face_start = &e->symedges[0];
+ break;
+ }
+ if (e->symedges[1].face == face) {
+ se_face_start = &e->symedges[1];
+ }
+ }
+ if (se_face_start != nullptr) {
+ /* Find center of face. */
+ int face_nverts = 0;
+ vec2<double> cen(0.0, 0.0);
+ if (face == cdt.outer_face) {
+ cen.x = minx;
+ cen.y = miny;
+ }
+ else {
+ const SymEdge<T> *se = se_face_start;
+ do {
+ if (se->face == face) {
+ cen = cen + se->vert->co.approx;
+ face_nverts++;
+ }
+ } while ((se = se->next) != se_face_start);
+ if (face_nverts > 0) {
+ cen = cen / double(face_nverts);
+ }
+ }
+ f << "<text x=\"" << SX(cen[0]) << "\" y=\"" << SY(cen[1]) << "\""
+ << " font-size=\"small\">[";
+ f << trunc_ptr(face);
+ if (face->input_ids.size() > 0) {
+ for (int id : face->input_ids) {
+ f << " " << id;
+ }
+ }
+ f << "]</text>\n";
+ }
+ }
+ }
+ }
+
append = true;
# undef SX
# undef SY
@@ -754,7 +813,6 @@ template<> CDTVert<double>::CDTVert(const vec2<double> &pt)
this->co.exact = pt;
this->co.approx = pt;
this->co.abs_approx = pt; /* Not used, so doesn't matter. */
- this->input_ids = nullptr;
this->symedge = nullptr;
this->index = -1;
this->merge_to_index = -1;
@@ -767,7 +825,6 @@ template<> CDTVert<mpq_class>::CDTVert(const vec2<mpq_class> &pt)
this->co.exact = pt;
this->co.approx = double2(pt.x.get_d(), pt.y.get_d());
this->co.abs_approx = double2(fabs(this->co.approx.x), fabs(this->co.approx.y));
- this->input_ids = nullptr;
this->symedge = nullptr;
this->index = -1;
this->merge_to_index = -1;
@@ -824,35 +881,21 @@ template<typename T> void CDTArrangement<T>::reserve(int num_verts, int num_edge
}
template<typename T>
-CDT_state<T>::CDT_state(int num_input_verts, int num_input_edges, int num_input_faces, T epsilon)
+CDT_state<T>::CDT_state(
+ int num_input_verts, int num_input_edges, int num_input_faces, T epsilon, bool need_ids)
{
this->input_vert_tot = num_input_verts;
this->cdt.reserve(num_input_verts, num_input_edges, num_input_faces);
this->cdt.outer_face = this->cdt.add_face();
this->epsilon = epsilon;
+ this->need_ids = need_ids;
this->visit_count = 0;
}
-static bool id_in_list(const LinkNode *id_list, int id)
-{
- const LinkNode *ln;
-
- for (ln = id_list; ln != nullptr; ln = ln->next) {
- if (POINTER_AS_INT(ln->link) == id) {
- return true;
- }
- }
- return false;
-}
-
/* Is any id in (range_start, range_start+1, ... , range_end) in id_list? */
-static bool id_range_in_list(const LinkNode *id_list, int range_start, int range_end)
+static bool id_range_in_list(const blender::Set<int> &id_list, int range_start, int range_end)
{
- const LinkNode *ln;
- int id;
-
- for (ln = id_list; ln != nullptr; ln = ln->next) {
- id = POINTER_AS_INT(ln->link);
+ for (int id : id_list) {
if (id >= range_start && id <= range_end) {
return true;
}
@@ -860,19 +903,15 @@ static bool id_range_in_list(const LinkNode *id_list, int range_start, int range
return false;
}
-static void add_to_input_ids(LinkNode **dst, int input_id)
+static void add_to_input_ids(blender::Set<int> &dst, int input_id)
{
- if (!id_in_list(*dst, input_id)) {
- BLI_linklist_prepend(dst, POINTER_FROM_INT(input_id));
- }
+ dst.add(input_id);
}
-static void add_list_to_input_ids(LinkNode **dst, const LinkNode *src)
+static void add_list_to_input_ids(blender::Set<int> &dst, const blender::Set<int> &src)
{
- const LinkNode *ln;
-
- for (ln = src; ln != nullptr; ln = ln->next) {
- add_to_input_ids(dst, POINTER_AS_INT(ln->link));
+ for (int value : src) {
+ dst.add(value);
}
}
@@ -883,7 +922,7 @@ template<typename T> inline bool is_border_edge(const CDTEdge<T> *e, const CDT_s
template<typename T> inline bool is_constrained_edge(const CDTEdge<T> *e)
{
- return e->input_ids != nullptr;
+ return e->input_ids.size() > 0;
}
template<typename T> inline bool is_deleted_edge(const CDTEdge<T> *e)
@@ -979,7 +1018,7 @@ template<typename T> CDTEdge<T> *CDTArrangement<T>::add_diagonal(SymEdge<T> *s1,
for (SymEdge<T> *se = s2; se != sdiag; se = se->next) {
se->face = fnew;
}
- add_list_to_input_ids(&fnew->input_ids, fold->input_ids);
+ add_list_to_input_ids(fnew->input_ids, fold->input_ids);
return ediag;
}
@@ -1058,7 +1097,7 @@ template<typename T> CDTEdge<T> *CDTArrangement<T>::split_edge(SymEdge<T> *se, T
if (newsesym->vert->symedge == sesym) {
newsesym->vert->symedge = newsesym;
}
- add_list_to_input_ids(&e->input_ids, se->edge->input_ids);
+ add_list_to_input_ids(e->input_ids, se->edge->input_ids);
return e;
}
@@ -1880,7 +1919,7 @@ void add_edge_constraint(
SymEdge<T> *t = find_symedge_between_verts(v1, v2);
if (t != nullptr) {
/* Segment already there. */
- add_to_input_ids(&t->edge->input_ids, input_id);
+ add_to_input_ids(t->edge->input_ids, input_id);
if (r_edges != nullptr) {
BLI_linklist_append(&edge_list, t->edge);
*r_edges = edge_list.list;
@@ -2041,7 +2080,7 @@ void add_edge_constraint(
BLI_assert(cd_prev->lambda == 0.0);
BLI_assert(cd_prev->out->next->vert == cd->vert);
edge = cd_prev->out->edge;
- add_to_input_ids(&edge->input_ids, input_id);
+ add_to_input_ids(edge->input_ids, input_id);
if (r_edges != nullptr) {
BLI_linklist_append(&edge_list, edge);
}
@@ -2054,7 +2093,7 @@ void add_edge_constraint(
else {
edge = cdt_state->cdt.add_diagonal(tstart, t);
}
- add_to_input_ids(&edge->input_ids, input_id);
+ add_to_input_ids(edge->input_ids, input_id);
if (r_edges != nullptr) {
BLI_linklist_append(&edge_list, edge);
}
@@ -2093,7 +2132,8 @@ template<typename T> void add_edge_constraints(CDT_state<T> *cdt_state, const CD
}
CDTVert<T> *v1 = cdt_state->cdt.get_vert_resolve_merge(iv1);
CDTVert<T> *v2 = cdt_state->cdt.get_vert_resolve_merge(iv2);
- add_edge_constraint(cdt_state, v1, v2, i, nullptr);
+ int id = cdt_state->need_ids ? i : 0;
+ add_edge_constraint(cdt_state, v1, v2, id, nullptr);
}
cdt_state->face_edge_offset = ne;
}
@@ -2132,7 +2172,7 @@ void add_face_ids(
continue;
}
face->visit_index = visit;
- add_to_input_ids(&face->input_ids, face_id);
+ add_to_input_ids(face->input_ids, face_id);
SymEdge<T> *se_start = se;
for (se = se->next; se != se_start; se = se->next) {
if (!id_range_in_list(se->edge->input_ids, fedge_start, fedge_end)) {
@@ -2206,7 +2246,8 @@ template<typename T> void add_face_constraints(CDT_state<T> *cdt_state, const CD
CDTVert<T> *v1 = cdt->get_vert_resolve_merge(iv1);
CDTVert<T> *v2 = cdt->get_vert_resolve_merge(iv2);
LinkNode *edge_list;
- add_edge_constraint(cdt_state, v1, v2, face_edge_id, &edge_list);
+ int id = cdt_state->need_ids ? face_edge_id : 0;
+ add_edge_constraint(cdt_state, v1, v2, id, &edge_list);
/* Set a new face_symedge0 each time since earlier ones may not
* survive later symedge splits. Really, just want the one when
* i == flen -1, but this code guards against that one somehow
@@ -2224,7 +2265,8 @@ template<typename T> void add_face_constraints(CDT_state<T> *cdt_state, const CD
}
int fedge_end = fedge_start + flen - 1;
if (face_symedge0 != nullptr) {
- add_face_ids(cdt_state, face_symedge0, f, fedge_start, fedge_end);
+ int id = cdt_state->need_ids ? f : 0;
+ add_face_ids(cdt_state, face_symedge0, id, fedge_start, fedge_end);
}
fstart += flen;
}
@@ -2349,7 +2391,7 @@ template<typename T> void remove_non_constraint_edges_leave_valid_bmesh(CDT_stat
CDTFace<T> *fleft = se->face;
CDTFace<T> *fright = sym(se)->face;
if (fleft != cdt->outer_face && fright != cdt->outer_face &&
- (fleft->input_ids != nullptr || fright->input_ids != nullptr)) {
+ (fleft->input_ids.size() > 0 || fright->input_ids.size() > 0)) {
/* Is there another #SymEdge with same left and right faces?
* Or is there a vertex not part of e touching the same left and right faces? */
for (SymEdge<T> *se2 = se->next; dissolve && se2 != se; se2 = se2->next) {
@@ -2507,30 +2549,33 @@ template<typename T> void detect_holes(CDT_state<T> *cdt_state)
mid.exact[1] = (f->symedge->vert->co.exact[1] + f->symedge->next->vert->co.exact[1] +
f->symedge->next->next->vert->co.exact[1]) /
3;
- int hits = 0;
+ std::atomic<int> hits = 0;
/* TODO: Use CDT data structure here to greatly reduce search for intersections! */
- for (const CDTEdge<T> *e : cdt->edges) {
- if (!is_deleted_edge(e) && is_constrained_edge(e)) {
- if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) {
- continue; /* Don't count hits on edges between faces in same region. */
- }
- auto isect = vec2<T>::isect_seg_seg(ray_end.exact,
- mid.exact,
- e->symedges[0].vert->co.exact,
- e->symedges[1].vert->co.exact);
- switch (isect.kind) {
- case vec2<T>::isect_result::LINE_LINE_CROSS: {
- hits++;
- break;
+ threading::parallel_for(cdt->edges.index_range(), 256, [&](IndexRange range) {
+ for (const int i : range) {
+ const CDTEdge<T> *e = cdt->edges[i];
+ if (!is_deleted_edge(e) && is_constrained_edge(e)) {
+ if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) {
+ continue; /* Don't count hits on edges between faces in same region. */
+ }
+ auto isect = vec2<T>::isect_seg_seg(ray_end.exact,
+ mid.exact,
+ e->symedges[0].vert->co.exact,
+ e->symedges[1].vert->co.exact);
+ switch (isect.kind) {
+ case vec2<T>::isect_result::LINE_LINE_CROSS: {
+ hits++;
+ break;
+ }
+ case vec2<T>::isect_result::LINE_LINE_EXACT:
+ case vec2<T>::isect_result::LINE_LINE_NONE:
+ case vec2<T>::isect_result::LINE_LINE_COLINEAR:
+ break;
}
- case vec2<T>::isect_result::LINE_LINE_EXACT:
- case vec2<T>::isect_result::LINE_LINE_NONE:
- case vec2<T>::isect_result::LINE_LINE_COLINEAR:
- break;
}
}
- }
- f->hole = (hits % 2) == 0;
+ });
+ f->hole = (hits.load() % 2) == 0;
}
/* Finally, propagate hole status to all holes of a region. */
@@ -2631,25 +2676,31 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
for (int i = 0; i < verts_size; ++i) {
CDTVert<T> *v = cdt->verts[i];
if (v->merge_to_index != -1) {
- if (i < cdt_state->input_vert_tot) {
- add_to_input_ids(&cdt->verts[v->merge_to_index]->input_ids, i);
+ if (cdt_state->need_ids) {
+ if (i < cdt_state->input_vert_tot) {
+ add_to_input_ids(cdt->verts[v->merge_to_index]->input_ids, i);
+ }
}
vert_to_output_map[i] = vert_to_output_map[v->merge_to_index];
}
}
}
result.vert = Array<vec2<T>>(nv);
- result.vert_orig = Array<Vector<int>>(nv);
+ if (cdt_state->need_ids) {
+ result.vert_orig = Array<Vector<int>>(nv);
+ }
int i_out = 0;
for (int i = 0; i < verts_size; ++i) {
CDTVert<T> *v = cdt->verts[i];
if (v->merge_to_index == -1) {
result.vert[i_out] = v->co.exact;
- if (i < cdt_state->input_vert_tot) {
- result.vert_orig[i_out].append(i);
- }
- for (LinkNode *ln = v->input_ids; ln; ln = ln->next) {
- result.vert_orig[i_out].append(POINTER_AS_INT(ln->link));
+ if (cdt_state->need_ids) {
+ if (i < cdt_state->input_vert_tot) {
+ result.vert_orig[i_out].append(i);
+ }
+ for (int vert : v->input_ids) {
+ result.vert_orig[i_out].append(vert);
+ }
}
++i_out;
}
@@ -2660,15 +2711,19 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
return !is_deleted_edge(e);
});
result.edge = Array<std::pair<int, int>>(ne);
- result.edge_orig = Array<Vector<int>>(ne);
+ if (cdt_state->need_ids) {
+ result.edge_orig = Array<Vector<int>>(ne);
+ }
int e_out = 0;
for (const CDTEdge<T> *e : cdt->edges) {
if (!is_deleted_edge(e)) {
int vo1 = vert_to_output_map[e->symedges[0].vert->index];
int vo2 = vert_to_output_map[e->symedges[1].vert->index];
result.edge[e_out] = std::pair<int, int>(vo1, vo2);
- for (LinkNode *ln = e->input_ids; ln; ln = ln->next) {
- result.edge_orig[e_out].append(POINTER_AS_INT(ln->link));
+ if (cdt_state->need_ids) {
+ for (int edge : e->input_ids) {
+ result.edge_orig[e_out].append(edge);
+ }
}
++e_out;
}
@@ -2679,7 +2734,9 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
return !f->deleted && f != cdt->outer_face;
});
result.face = Array<Vector<int>>(nf);
- result.face_orig = Array<Vector<int>>(nf);
+ if (cdt_state->need_ids) {
+ result.face_orig = Array<Vector<int>>(nf);
+ }
int f_out = 0;
for (const CDTFace<T> *f : cdt->faces) {
if (!f->deleted && f != cdt->outer_face) {
@@ -2690,8 +2747,10 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
result.face[f_out].append(vert_to_output_map[se->vert->index]);
se = se->next;
} while (se != se_start);
- for (LinkNode *ln = f->input_ids; ln; ln = ln->next) {
- result.face_orig[f_out].append(POINTER_AS_INT(ln->link));
+ if (cdt_state->need_ids) {
+ for (int face : f->input_ids) {
+ result.face_orig[f_out].append(face);
+ }
}
++f_out;
}
@@ -2716,7 +2775,7 @@ CDT_result<T> delaunay_calc(const CDT_input<T> &input, CDT_output_type output_ty
int nv = input.vert.size();
int ne = input.edge.size();
int nf = input.face.size();
- CDT_state<T> cdt_state(nv, ne, nf, input.epsilon);
+ CDT_state<T> cdt_state(nv, ne, nf, input.epsilon, input.need_ids);
add_input_verts(&cdt_state, input);
initial_triangulation(&cdt_state.cdt);
add_edge_constraints(&cdt_state, input);
@@ -2772,6 +2831,7 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
}
}
in.epsilon = static_cast<double>(input->epsilon);
+ in.need_ids = input->need_ids;
blender::meshintersect::CDT_result<double> res = blender::meshintersect::delaunay_2d_calc(
in, output_type);
@@ -2784,74 +2844,99 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
int tot_e_orig = 0;
int tot_f_orig = 0;
int tot_f_lens = 0;
- for (int v = 0; v < nv; ++v) {
- tot_v_orig += res.vert_orig[v].size();
- }
- for (int e = 0; e < ne; ++e) {
- tot_e_orig += res.edge_orig[e].size();
- }
- for (int f = 0; f < nf; ++f) {
- tot_f_orig += res.face_orig[f].size();
- tot_f_lens += res.face[f].size();
+ if (input->need_ids) {
+ for (int v = 0; v < nv; ++v) {
+ tot_v_orig += res.vert_orig[v].size();
+ }
+ for (int e = 0; e < ne; ++e) {
+ tot_e_orig += res.edge_orig[e].size();
+ }
+ for (int f = 0; f < nf; ++f) {
+ tot_f_orig += res.face_orig[f].size();
+ tot_f_lens += res.face[f].size();
+ }
}
output->vert_coords = static_cast<decltype(output->vert_coords)>(
MEM_malloc_arrayN(nv, sizeof(output->vert_coords[0]), __func__));
- output->verts_orig = static_cast<int *>(MEM_malloc_arrayN(tot_v_orig, sizeof(int), __func__));
- output->verts_orig_start_table = static_cast<int *>(
- MEM_malloc_arrayN(nv, sizeof(int), __func__));
- output->verts_orig_len_table = static_cast<int *>(MEM_malloc_arrayN(nv, sizeof(int), __func__));
output->edges = static_cast<decltype(output->edges)>(
MEM_malloc_arrayN(ne, sizeof(output->edges[0]), __func__));
- output->edges_orig = static_cast<int *>(MEM_malloc_arrayN(tot_e_orig, sizeof(int), __func__));
- output->edges_orig_start_table = static_cast<int *>(
- MEM_malloc_arrayN(ne, sizeof(int), __func__));
- output->edges_orig_len_table = static_cast<int *>(MEM_malloc_arrayN(ne, sizeof(int), __func__));
output->faces = static_cast<int *>(MEM_malloc_arrayN(tot_f_lens, sizeof(int), __func__));
output->faces_start_table = static_cast<int *>(MEM_malloc_arrayN(nf, sizeof(int), __func__));
output->faces_len_table = static_cast<int *>(MEM_malloc_arrayN(nf, sizeof(int), __func__));
- output->faces_orig = static_cast<int *>(MEM_malloc_arrayN(tot_f_orig, sizeof(int), __func__));
- output->faces_orig_start_table = static_cast<int *>(
- MEM_malloc_arrayN(nf, sizeof(int), __func__));
- output->faces_orig_len_table = static_cast<int *>(MEM_malloc_arrayN(nf, sizeof(int), __func__));
+ if (input->need_ids) {
+ output->verts_orig = static_cast<int *>(MEM_malloc_arrayN(tot_v_orig, sizeof(int), __func__));
+ output->verts_orig_start_table = static_cast<int *>(
+ MEM_malloc_arrayN(nv, sizeof(int), __func__));
+ output->verts_orig_len_table = static_cast<int *>(
+ MEM_malloc_arrayN(nv, sizeof(int), __func__));
+ output->edges_orig = static_cast<int *>(MEM_malloc_arrayN(tot_e_orig, sizeof(int), __func__));
+ output->edges_orig_start_table = static_cast<int *>(
+ MEM_malloc_arrayN(ne, sizeof(int), __func__));
+ output->edges_orig_len_table = static_cast<int *>(
+ MEM_malloc_arrayN(ne, sizeof(int), __func__));
+ output->faces_orig = static_cast<int *>(MEM_malloc_arrayN(tot_f_orig, sizeof(int), __func__));
+ output->faces_orig_start_table = static_cast<int *>(
+ MEM_malloc_arrayN(nf, sizeof(int), __func__));
+ output->faces_orig_len_table = static_cast<int *>(
+ MEM_malloc_arrayN(nf, sizeof(int), __func__));
+ }
+ else {
+ output->verts_orig = NULL;
+ output->verts_orig_start_table = NULL;
+ output->verts_orig_len_table = NULL;
+ output->edges_orig = NULL;
+ output->edges_orig_start_table = NULL;
+ output->edges_orig_len_table = NULL;
+ output->faces_orig = NULL;
+ output->faces_orig_start_table = NULL;
+ output->faces_orig_len_table = NULL;
+ }
int v_orig_index = 0;
for (int v = 0; v < nv; ++v) {
output->vert_coords[v][0] = static_cast<float>(res.vert[v][0]);
output->vert_coords[v][1] = static_cast<float>(res.vert[v][1]);
- int this_start = v_orig_index;
- output->verts_orig_start_table[v] = this_start;
- for (int j : res.vert_orig[v].index_range()) {
- output->verts_orig[v_orig_index++] = res.vert_orig[v][j];
+ if (input->need_ids) {
+ int this_start = v_orig_index;
+ output->verts_orig_start_table[v] = this_start;
+ for (int j : res.vert_orig[v].index_range()) {
+ output->verts_orig[v_orig_index++] = res.vert_orig[v][j];
+ }
+ output->verts_orig_len_table[v] = v_orig_index - this_start;
}
- output->verts_orig_len_table[v] = v_orig_index - this_start;
}
int e_orig_index = 0;
for (int e = 0; e < ne; ++e) {
output->edges[e][0] = res.edge[e].first;
output->edges[e][1] = res.edge[e].second;
- int this_start = e_orig_index;
- output->edges_orig_start_table[e] = this_start;
- for (int j : res.edge_orig[e].index_range()) {
- output->edges_orig[e_orig_index++] = res.edge_orig[e][j];
+ if (input->need_ids) {
+ int this_start = e_orig_index;
+ output->edges_orig_start_table[e] = this_start;
+ for (int j : res.edge_orig[e].index_range()) {
+ output->edges_orig[e_orig_index++] = res.edge_orig[e][j];
+ }
+ output->edges_orig_len_table[e] = e_orig_index - this_start;
}
- output->edges_orig_len_table[e] = e_orig_index - this_start;
}
int f_orig_index = 0;
int f_index = 0;
for (int f = 0; f < nf; ++f) {
+
output->faces_start_table[f] = f_index;
int flen = res.face[f].size();
output->faces_len_table[f] = flen;
for (int j = 0; j < flen; ++j) {
output->faces[f_index++] = res.face[f][j];
}
- int this_start = f_orig_index;
- output->faces_orig_start_table[f] = this_start;
- for (int k : res.face_orig[f].index_range()) {
- output->faces_orig[f_orig_index++] = res.face_orig[f][k];
+ if (input->need_ids) {
+ int this_start = f_orig_index;
+ output->faces_orig_start_table[f] = this_start;
+ for (int k : res.face_orig[f].index_range()) {
+ output->faces_orig[f_orig_index++] = res.face_orig[f][k];
+ }
+ output->faces_orig_len_table[f] = f_orig_index - this_start;
}
- output->faces_orig_len_table[f] = f_orig_index - this_start;
}
return output;
}
@@ -2863,14 +2948,16 @@ extern "C" void BLI_delaunay_2d_cdt_free(::CDT_result *result)
MEM_freeN(result->faces);
MEM_freeN(result->faces_start_table);
MEM_freeN(result->faces_len_table);
- MEM_freeN(result->verts_orig);
- MEM_freeN(result->verts_orig_start_table);
- MEM_freeN(result->verts_orig_len_table);
- MEM_freeN(result->edges_orig);
- MEM_freeN(result->edges_orig_start_table);
- MEM_freeN(result->edges_orig_len_table);
- MEM_freeN(result->faces_orig);
- MEM_freeN(result->faces_orig_start_table);
- MEM_freeN(result->faces_orig_len_table);
+ if (result->verts_orig) {
+ MEM_freeN(result->verts_orig);
+ MEM_freeN(result->verts_orig_start_table);
+ MEM_freeN(result->verts_orig_len_table);
+ MEM_freeN(result->edges_orig);
+ MEM_freeN(result->edges_orig_start_table);
+ MEM_freeN(result->edges_orig_len_table);
+ MEM_freeN(result->faces_orig);
+ MEM_freeN(result->faces_orig_start_table);
+ MEM_freeN(result->faces_orig_len_table);
+ }
MEM_freeN(result);
}
diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc
index f91dd762e70..400b3f94a3f 100644
--- a/source/blender/blenlib/intern/mesh_intersect.cc
+++ b/source/blender/blenlib/intern/mesh_intersect.cc
@@ -1875,6 +1875,16 @@ static void do_cdt(CDT_data &cd)
}
}
+/* Find an original edge index that goes with the edge that the CDT output edge
+ * that goes between verts i0 and i1 (in the CDT output vert indexing scheme).
+ * There may be more than one: if so, prefer one that was originally a face edge.
+ * The input to CDT for a triangle with some intersecting segments from other triangles
+ * will have both edges and a face constraint for the main triangle (this is redundant
+ * but allows us to discover which face edge goes with which output edges).
+ * If there is any face edge, return one of those as the original.
+ * If there is no face edge but there is another edge in the input problem, then that
+ * edge must have come from intersection with another triangle, so set *r_is_intersect
+ * to true in that case. */
static int get_cdt_edge_orig(
int i0, int i1, const CDT_data &cd, const IMesh &in_tm, bool *r_is_intersect)
{
@@ -1900,35 +1910,50 @@ static int get_cdt_edge_orig(
}
/* Pick an arbitrary orig, but not one equal to NO_INDEX, if we can help it. */
- /* TODO: if edge has origs from more than on part of the nary input,
+ /* TODO: if edge has origs from more than one part of the nary input,
* then want to set *r_is_intersect to true. */
+ int face_eorig = NO_INDEX;
+ bool have_non_face_eorig = false;
for (int orig_index : cd.cdt_out.edge_orig[e]) {
/* orig_index encodes the triangle and pos within the triangle of the input edge. */
if (orig_index >= foff) {
- int in_face_index = (orig_index / foff) - 1;
- int pos = orig_index % foff;
- /* We need to retrieve the edge orig field from the Face used to populate the
- * in_face_index'th face of the CDT, at the pos'th position of the face. */
- int in_tm_face_index = cd.input_face[in_face_index];
- BLI_assert(in_tm_face_index < in_tm.face_size());
- const Face *facep = in_tm.face(in_tm_face_index);
- BLI_assert(pos < facep->size());
- bool is_rev = cd.is_reversed[in_face_index];
- int eorig = is_rev ? facep->edge_orig[2 - pos] : facep->edge_orig[pos];
- if (eorig != NO_INDEX) {
- return eorig;
+ if (face_eorig == NO_INDEX) {
+ int in_face_index = (orig_index / foff) - 1;
+ int pos = orig_index % foff;
+ /* We need to retrieve the edge orig field from the Face used to populate the
+ * in_face_index'th face of the CDT, at the pos'th position of the face. */
+ int in_tm_face_index = cd.input_face[in_face_index];
+ BLI_assert(in_tm_face_index < in_tm.face_size());
+ const Face *facep = in_tm.face(in_tm_face_index);
+ BLI_assert(pos < facep->size());
+ bool is_rev = cd.is_reversed[in_face_index];
+ int eorig = is_rev ? facep->edge_orig[2 - pos] : facep->edge_orig[pos];
+ if (eorig != NO_INDEX) {
+ face_eorig = eorig;
+ }
}
}
else {
- /* This edge came from an edge input to the CDT problem,
- * so it is an intersect edge. */
- *r_is_intersect = true;
- /* TODO: maybe there is an orig index:
- * This happens if an input edge was formed by an input face having
- * an edge that is co-planar with the cluster, while the face as a whole is not. */
- return NO_INDEX;
+ if (!have_non_face_eorig) {
+ have_non_face_eorig = true;
+ }
+ if (face_eorig != NO_INDEX && have_non_face_eorig) {
+ /* Only need at most one orig for each type. */
+ break;
+ }
}
}
+ if (face_eorig != NO_INDEX) {
+ return face_eorig;
+ }
+ else if (have_non_face_eorig) {
+ /* This must have been an input to the CDT problem that was an intersection edge. */
+ /* TODO: maybe there is an orig index:
+ * This happens if an input edge was formed by an input face having
+ * an edge that is co-planar with the cluster, while the face as a whole is not. */
+ *r_is_intersect = true;
+ return NO_INDEX;
+ }
return NO_INDEX;
}
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index 87330cf4899..66d0b44cfb3 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -184,7 +184,7 @@ size_t BLI_system_memory_max_in_megabytes(void)
/* Maximum addressable bytes on this platform.
*
* NOTE: Due to the shift arithmetic this is a half of the memory. */
- const size_t limit_bytes_half = (((size_t)1) << ((sizeof(size_t[8])) - 1));
+ const size_t limit_bytes_half = (((size_t)1) << (sizeof(size_t[8]) - 1));
/* Convert it to megabytes and return. */
return (limit_bytes_half >> 20) * 2;
}
diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c
index 33af4894b48..06087869685 100644
--- a/source/blender/blenlib/intern/task_iterator.c
+++ b/source/blender/blenlib/intern/task_iterator.c
@@ -409,11 +409,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
TaskParallelMempoolFunc func,
const TaskParallelSettings *settings)
{
- TaskPool *task_pool;
- ParallelMempoolState state;
- int i, num_threads, num_tasks;
-
- if (BLI_mempool_len(mempool) == 0) {
+ if (UNLIKELY(BLI_mempool_len(mempool) == 0)) {
return;
}
@@ -429,7 +425,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
userdata_chunk_local = MALLOCA(userdata_chunk_size);
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
if (settings->func_init != NULL) {
- settings->func_init(state.userdata, userdata_chunk_local);
+ settings->func_init(userdata, userdata_chunk_local);
}
tls.userdata_chunk = userdata_chunk_local;
}
@@ -451,14 +447,15 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
return;
}
- task_pool = BLI_task_pool_create(&state, TASK_PRIORITY_HIGH);
- num_threads = BLI_task_scheduler_num_threads();
+ ParallelMempoolState state;
+ TaskPool *task_pool = BLI_task_pool_create(&state, TASK_PRIORITY_HIGH);
+ const int num_threads = BLI_task_scheduler_num_threads();
/* The idea here is to prevent creating task for each of the loop iterations
* and instead have tasks which are evenly distributed across CPU cores and
* pull next item to be crunched using the threaded-aware BLI_mempool_iter.
*/
- num_tasks = num_threads + 2;
+ const int num_tasks = num_threads + 2;
state.userdata = userdata;
state.func = func;
@@ -470,7 +467,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
ParallelMempoolTaskData *mempool_iterator_data = mempool_iter_threadsafe_create(
mempool, (size_t)num_tasks);
- for (i = 0; i < num_tasks; i++) {
+ for (int i = 0; i < num_tasks; i++) {
if (use_userdata_chunk) {
userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
@@ -489,7 +486,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
if (use_userdata_chunk) {
if ((settings->func_free != NULL) || (settings->func_reduce != NULL)) {
- for (i = 0; i < num_tasks; i++) {
+ for (int i = 0; i < num_tasks; i++) {
if (settings->func_reduce) {
settings->func_reduce(
userdata, userdata_chunk, mempool_iterator_data[i].tls.userdata_chunk);
diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
index 08a3818e18f..bc6b7e9fe4e 100644
--- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
@@ -241,7 +241,7 @@ template<typename T> std::ostream &operator<<(std::ostream &os, const CDT_result
for (int i : r.edge.index_range()) {
os << "e" << i << " = (" << r.edge[i].first << ", " << r.edge[i].second << ")\n";
os << " orig: ";
- for (int j : r.edge_orig[i].size()) {
+ for (int j : r.edge_orig[i].index_range()) {
os << r.edge_orig[i][j] << " ";
}
os << "\n";
@@ -797,6 +797,55 @@ template<typename T> void crosssegs_test()
}
}
+template<typename T> void cutacrosstri_test()
+{
+ /* Right triangle with horizontal segment exactly crossing in the middle. */
+ const char *spec = R"(5 1 1
+ 0.0 0.0
+ 1.0 0.0
+ 0.0 1.0
+ 0.0 0.5
+ 0.5 0.5
+ 3 4
+ 0 1 2
+ )";
+
+ CDT_input<T> in = fill_input_from_string<T>(spec);
+ CDT_result<T> out = delaunay_2d_calc(in, CDT_FULL);
+ EXPECT_EQ(out.vert.size(), 5);
+ EXPECT_EQ(out.edge.size(), 7);
+ EXPECT_EQ(out.face.size(), 3);
+ int v0_out = get_orig_index(out.vert_orig, 0);
+ int v1_out = get_orig_index(out.vert_orig, 1);
+ int v2_out = get_orig_index(out.vert_orig, 2);
+ int v3_out = get_orig_index(out.vert_orig, 3);
+ int v4_out = get_orig_index(out.vert_orig, 4);
+ EXPECT_TRUE(v0_out != -1 && v1_out != -1 && v2_out != -1 && v3_out != -1 && v4_out != -1);
+ if (out.face.size() == 3) {
+ int e0_out = get_orig_index(out.edge_orig, 0);
+ EXPECT_NE(e0_out, -1);
+ int fe0_out = get_output_edge_index(out, v0_out, v1_out);
+ EXPECT_NE(fe0_out, -1);
+ int fe1a_out = get_output_edge_index(out, v1_out, v4_out);
+ EXPECT_NE(fe1a_out, -1);
+ int fe1b_out = get_output_edge_index(out, v4_out, v2_out);
+ EXPECT_NE(fe1b_out, -1);
+ if (fe1a_out != 0 && fe1b_out != 0) {
+ EXPECT_EQ(e0_out, get_orig_index(out.edge_orig, 0));
+ EXPECT_TRUE(out.edge_orig[fe1a_out].size() == 1 && out.edge_orig[fe1a_out][0] == 11);
+ EXPECT_TRUE(out.edge_orig[fe1b_out].size() == 1 && out.edge_orig[fe1b_out][0] == 11);
+ }
+ int e_diag = get_output_edge_index(out, v0_out, v4_out);
+ EXPECT_NE(e_diag, -1);
+ if (e_diag != -1) {
+ EXPECT_EQ(out.edge_orig[e_diag].size(), 0);
+ }
+ }
+ if (DO_DRAW) {
+ graph_draw<T>("CutAcrossTri", out.vert, out.edge, out.face);
+ }
+}
+
template<typename T> void diamondcross_test()
{
/* Diamond with constraint edge from top to bottom. Some dup verts. */
@@ -1470,6 +1519,11 @@ TEST(delaunay_d, CrossSegs)
crosssegs_test<double>();
}
+TEST(delaunay_d, CutAcrossTri)
+{
+ cutacrosstri_test<double>();
+}
+
TEST(delaunay_d, DiamondCross)
{
diamondcross_test<double>();
@@ -1610,6 +1664,11 @@ TEST(delaunay_m, CrossSegs)
crosssegs_test<mpq_class>();
}
+TEST(delaunay_m, CutAcrossTri)
+{
+ cutacrosstri_test<mpq_class>();
+}
+
TEST(delaunay_m, DiamondCross)
{
diamondcross_test<mpq_class>();
@@ -1704,7 +1763,8 @@ TEST(delaunay_d, CintTwoFace)
#if DO_TEXT_TESTS
template<typename T>
-void text_test(int num_arc_points, int num_lets_per_line, int num_lines, CDT_output_type otype)
+void text_test(
+ int num_arc_points, int num_lets_per_line, int num_lines, CDT_output_type otype, bool need_ids)
{
constexpr bool print_timing = true;
/*
@@ -1843,12 +1903,18 @@ void text_test(int num_arc_points, int num_lets_per_line, int num_lines, CDT_out
}
}
in.epsilon = b_before_arcs_in.epsilon;
+ in.need_ids = need_ids;
double tstart = PIL_check_seconds_timer();
CDT_result<T> out = delaunay_2d_calc(in, otype);
double tend = PIL_check_seconds_timer();
if (print_timing) {
std::cout << "time = " << tend - tstart << "\n";
}
+ if (!need_ids) {
+ EXPECT_EQ(out.vert_orig.size(), 0);
+ EXPECT_EQ(out.edge_orig.size(), 0);
+ EXPECT_EQ(out.face_orig.size(), 0);
+ }
if (DO_DRAW) {
std::string label = "Text arcpts=" + std::to_string(num_arc_points);
if (num_lets_per_line > 1) {
@@ -1863,19 +1929,46 @@ void text_test(int num_arc_points, int num_lets_per_line, int num_lines, CDT_out
TEST(delaunay_d, TextB10)
{
- text_test<double>(10, 1, 1, CDT_INSIDE_WITH_HOLES);
+ text_test<double>(10, 1, 1, CDT_INSIDE_WITH_HOLES, true);
}
TEST(delaunay_d, TextB200)
{
- text_test<double>(200, 1, 1, CDT_INSIDE_WITH_HOLES);
+ text_test<double>(200, 1, 1, CDT_INSIDE_WITH_HOLES, true);
}
TEST(delaunay_d, TextB10_10_10)
{
- text_test<double>(10, 10, 10, CDT_INSIDE_WITH_HOLES);
+ text_test<double>(10, 10, 10, CDT_INSIDE_WITH_HOLES, true);
+}
+
+TEST(delaunay_d, TextB10_10_10_noids)
+{
+ text_test<double>(10, 10, 10, CDT_INSIDE_WITH_HOLES, false);
}
+# ifdef WITH_GMP
+TEST(delaunay_m, TextB10)
+{
+ text_test<mpq_class>(10, 1, 1, CDT_INSIDE_WITH_HOLES, true);
+}
+
+TEST(delaunay_m, TextB200)
+{
+ text_test<mpq_class>(200, 1, 1, CDT_INSIDE_WITH_HOLES, true);
+}
+
+TEST(delaunay_m, TextB10_10_10)
+{
+ text_test<mpq_class>(10, 10, 10, CDT_INSIDE_WITH_HOLES, true);
+}
+
+TEST(delaunay_m, TextB10_10_10_noids)
+{
+ text_test<mpq_class>(10, 10, 10, CDT_INSIDE_WITH_HOLES, false);
+}
+# endif
+
#endif
#if DO_RANDOM_TESTS
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index d36c622c572..07a324181af 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -99,9 +99,15 @@ static void move_vertex_group_names_to_object_data(Main *bmain)
if (ELEM(object->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
ListBase *new_defbase = BKE_object_defgroup_list_mutable(object);
- /* Clear the list in case the it was already assigned from another object. */
- BLI_freelistN(new_defbase);
- *new_defbase = object->defbase;
+ /* Choose the longest vertex group name list among all linked duplicates. */
+ if (BLI_listbase_count(&object->defbase) < BLI_listbase_count(new_defbase)) {
+ BLI_freelistN(&object->defbase);
+ }
+ else {
+ /* Clear the list in case the it was already assigned from another object. */
+ BLI_freelistN(new_defbase);
+ *new_defbase = object->defbase;
+ }
}
}
}
@@ -551,5 +557,24 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
*/
{
/* Keep this block, even when empty. */
+
+ /* Convert Surface Deform to sparse-capable bind structure. */
+ if (!DNA_struct_elem_find(
+ fd->filesdna, "SurfaceDeformModifierData", "int", "num_mesh_verts")) {
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+ if (md->type == eModifierType_SurfaceDeform) {
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ if (smd->num_bind_verts && smd->verts) {
+ smd->num_mesh_verts = smd->num_bind_verts;
+
+ for (unsigned int i = 0; i < smd->num_bind_verts; i++) {
+ smd->verts[i].vertex_idx = i;
+ }
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index ee51a03d9fb..6f7b2cbc79f 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -800,7 +800,7 @@ short BM_edge_flag_to_mflag(BMEdge *e)
((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) |
- ((BM_edge_is_wire(e)) ? ME_LOOSEEDGE : 0) | /* not typical */
+ (BM_edge_is_wire(e) ? ME_LOOSEEDGE : 0) | /* not typical */
ME_EDGERENDER);
}
char BM_face_flag_to_mflag(BMFace *f)
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 456275cf157..bd0504b038a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -24,8 +24,8 @@
struct BMAllocTemplate;
struct BMLoopNorEditDataArray;
-struct MLoopNorSpaceArray;
struct BMPartialUpdate;
+struct MLoopNorSpaceArray;
void BM_mesh_elem_toolflags_ensure(BMesh *bm);
void BM_mesh_elem_toolflags_clear(BMesh *bm);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 2c32cd39002..5be7f4a5f3b 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -20,8 +20,8 @@
* \ingroup bmesh
*/
-struct Heap;
struct BMPartialUpdate;
+struct Heap;
#include "BLI_compiler_attrs.h"
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 99e50b35d97..86a7d8153f0 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -337,7 +337,7 @@ static bool bm_face_split_edgenet_find_loop_walk(BMVert *v_init,
/* in rare cases there may be edges with a single connecting vertex */
if (e_next != e_first) {
do {
- if ((BM_ELEM_API_FLAG_TEST(e_next, EDGE_NET)) &&
+ if (BM_ELEM_API_FLAG_TEST(e_next, EDGE_NET) &&
(bm_edge_flagged_radial_count(e_next) < 2)) {
BMVert *v_next;
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index 40f09d7e719..e66afcd88d9 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -842,7 +842,7 @@ static void *bmw_IslandManifoldWalker_step(BMWalker *walker)
/* utility function to see if an edge is a part of an ngon boundary */
static bool bm_edge_is_single(BMEdge *e)
{
- return ((BM_edge_is_boundary(e)) && (e->l->f->len > 4) &&
+ return (BM_edge_is_boundary(e) && (e->l->f->len > 4) &&
(BM_edge_is_boundary(e->l->next->e) || BM_edge_is_boundary(e->l->prev->e)));
}
diff --git a/source/blender/bmesh/operators/bmo_connect_concave.c b/source/blender/bmesh/operators/bmo_connect_concave.c
index bc1111676a3..15ed930afd8 100644
--- a/source/blender/bmesh/operators/bmo_connect_concave.c
+++ b/source/blender/bmesh/operators/bmo_connect_concave.c
@@ -51,10 +51,10 @@ static int bm_edge_length_cmp(const void *a_, const void *b_)
const BMEdge *e_a = *(const void **)a_;
const BMEdge *e_b = *(const void **)b_;
- int e_a_concave = ((BM_elem_flag_test(e_a->v1, BM_ELEM_TAG)) &&
- (BM_elem_flag_test(e_a->v2, BM_ELEM_TAG)));
- int e_b_concave = ((BM_elem_flag_test(e_b->v1, BM_ELEM_TAG)) &&
- (BM_elem_flag_test(e_b->v2, BM_ELEM_TAG)));
+ int e_a_concave = (BM_elem_flag_test(e_a->v1, BM_ELEM_TAG) &&
+ BM_elem_flag_test(e_a->v2, BM_ELEM_TAG));
+ int e_b_concave = (BM_elem_flag_test(e_b->v1, BM_ELEM_TAG) &&
+ BM_elem_flag_test(e_b->v2, BM_ELEM_TAG));
/* merge edges between concave edges last since these
* are most likely to remain and be the main dividers */
diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c
index 8e4b0732feb..7f70c452af3 100644
--- a/source/blender/bmesh/operators/bmo_edgenet.c
+++ b/source/blender/bmesh/operators/bmo_edgenet.c
@@ -93,7 +93,7 @@ static BMEdge *edge_next(BMesh *bm, BMEdge *e)
for (i = 0; i < 2; i++) {
BM_ITER_ELEM (e2, &iter, i ? e->v2 : e->v1, BM_EDGES_OF_VERT) {
- if ((BMO_edge_flag_test(bm, e2, EDGE_MARK)) &&
+ if (BMO_edge_flag_test(bm, e2, EDGE_MARK) &&
(BMO_edge_flag_test(bm, e2, EDGE_VIS) == false) && (e2 != e)) {
return e2;
}
diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c
index 2e09b21c9cc..6734cc60cad 100644
--- a/source/blender/bmesh/operators/bmo_fill_grid.c
+++ b/source/blender/bmesh/operators/bmo_fill_grid.c
@@ -645,20 +645,20 @@ void bmo_grid_fill_exec(BMesh *bm, BMOperator *op)
bm_edgeloop_flag_set(estore_a, BM_ELEM_HIDDEN, true);
bm_edgeloop_flag_set(estore_b, BM_ELEM_HIDDEN, true);
- if ((BM_mesh_edgeloops_find_path(
- bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_first, v_b_first)) &&
- (BM_mesh_edgeloops_find_path(
- bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_last, v_b_last))) {
+ if (BM_mesh_edgeloops_find_path(
+ bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_first, v_b_first) &&
+ BM_mesh_edgeloops_find_path(
+ bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_last, v_b_last)) {
estore_rail_a = eloops_rail.first;
estore_rail_b = eloops_rail.last;
}
else {
BM_mesh_edgeloops_free(&eloops_rail);
- if ((BM_mesh_edgeloops_find_path(
- bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_first, v_b_last)) &&
- (BM_mesh_edgeloops_find_path(
- bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_last, v_b_first))) {
+ if (BM_mesh_edgeloops_find_path(
+ bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_first, v_b_last) &&
+ BM_mesh_edgeloops_find_path(
+ bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_last, v_b_first)) {
estore_rail_a = eloops_rail.first;
estore_rail_b = eloops_rail.last;
BM_edgeloop_flip(bm, estore_b);
diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
index d015b715a69..6a80f360f59 100644
--- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c
+++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
@@ -860,12 +860,12 @@ static bool bm_edgering_pair_order_is_flipped(BMesh *UNUSED(bm),
/* step around any fan-faces on both sides */
do {
v_iter_a_step = v_iter_a_step->next;
- } while (v_iter_a_step && ((BM_edge_exists(v_iter_a_step->data, v_iter_b_first->data)) ||
- (BM_edge_exists(v_iter_a_step->data, v_iter_b_first->next->data))));
+ } while (v_iter_a_step && (BM_edge_exists(v_iter_a_step->data, v_iter_b_first->data) ||
+ BM_edge_exists(v_iter_a_step->data, v_iter_b_first->next->data)));
do {
v_iter_b_step = v_iter_b_step->next;
- } while (v_iter_b_step && ((BM_edge_exists(v_iter_b_step->data, v_iter_a_first->data)) ||
- (BM_edge_exists(v_iter_b_step->data, v_iter_a_first->next->data))));
+ } while (v_iter_b_step && (BM_edge_exists(v_iter_b_step->data, v_iter_a_first->data) ||
+ BM_edge_exists(v_iter_b_step->data, v_iter_a_first->next->data)));
v_iter_a_step = v_iter_a_step ? v_iter_a_step->prev : lb_a->last;
v_iter_b_step = v_iter_b_step ? v_iter_b_step->prev : lb_b->last;
diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.cc b/source/blender/compositor/nodes/COM_IDMaskNode.cc
index 9798dabd035..b51e79f2dea 100644
--- a/source/blender/compositor/nodes/COM_IDMaskNode.cc
+++ b/source/blender/compositor/nodes/COM_IDMaskNode.cc
@@ -17,9 +17,9 @@
*/
#include "COM_IDMaskNode.h"
-#include "COM_AntiAliasOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_IDMaskOperation.h"
+#include "COM_SMAAOperation.h"
namespace blender::compositor {
@@ -42,11 +42,27 @@ void IDMaskNode::convertToOperations(NodeConverter &converter,
converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
else {
- AntiAliasOperation *antiAliasOperation = new AntiAliasOperation();
- converter.addOperation(antiAliasOperation);
+ SMAAEdgeDetectionOperation *operation1 = nullptr;
- converter.addLink(operation->getOutputSocket(), antiAliasOperation->getInputSocket(0));
- converter.mapOutputSocket(getOutputSocket(0), antiAliasOperation->getOutputSocket(0));
+ operation1 = new SMAAEdgeDetectionOperation();
+ converter.addOperation(operation1);
+
+ converter.addLink(operation->getOutputSocket(0), operation1->getInputSocket(0));
+
+ /* Blending Weight Calculation Pixel Shader (Second Pass). */
+ SMAABlendingWeightCalculationOperation *operation2 =
+ new SMAABlendingWeightCalculationOperation();
+ converter.addOperation(operation2);
+
+ converter.addLink(operation1->getOutputSocket(), operation2->getInputSocket(0));
+
+ /* Neighborhood Blending Pixel Shader (Third Pass). */
+ SMAANeighborhoodBlendingOperation *operation3 = new SMAANeighborhoodBlendingOperation();
+ converter.addOperation(operation3);
+
+ converter.addLink(operation->getOutputSocket(0), operation3->getInputSocket(0));
+ converter.addLink(operation2->getOutputSocket(), operation3->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation3->getOutputSocket());
}
}
diff --git a/source/blender/compositor/operations/COM_SMAAOperation.cc b/source/blender/compositor/operations/COM_SMAAOperation.cc
index c3647a39909..3c753591ced 100644
--- a/source/blender/compositor/operations/COM_SMAAOperation.cc
+++ b/source/blender/compositor/operations/COM_SMAAOperation.cc
@@ -21,6 +21,7 @@
#include "COM_SMAAOperation.h"
#include "BLI_math.h"
#include "COM_SMAAAreaTexture.h"
+#include "BKE_node.h"
extern "C" {
#include "IMB_colormanagement.h"
@@ -166,8 +167,8 @@ SMAAEdgeDetectionOperation::SMAAEdgeDetectionOperation()
this->flags.complex = true;
this->m_imageReader = nullptr;
this->m_valueReader = nullptr;
- this->m_threshold = 0.1f;
- this->m_contrast_limit = 2.0f;
+ this->setThreshold(CMP_DEFAULT_SMAA_THRESHOLD);
+ this->setLocalContrastAdaptationFactor(CMP_DEFAULT_SMAA_CONTRAST_LIMIT);
}
void SMAAEdgeDetectionOperation::initExecution()
@@ -297,7 +298,7 @@ SMAABlendingWeightCalculationOperation::SMAABlendingWeightCalculationOperation()
this->addOutputSocket(DataType::Color);
this->flags.complex = true;
this->m_imageReader = nullptr;
- this->m_corner_rounding = 25;
+ this->setCornerRounding(CMP_DEFAULT_SMAA_CORNER_ROUNDING);
}
void *SMAABlendingWeightCalculationOperation::initializeTileData(rcti *rect)
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index 42c9cccceed..c029d203574 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -33,6 +33,7 @@ struct Depsgraph;
/* ------------------------------------------------ */
struct CacheFile;
+struct Collection;
struct CustomData_MeshMasks;
struct ID;
struct Main;
@@ -40,7 +41,6 @@ struct Object;
struct Scene;
struct Simulation;
struct bNodeTree;
-struct Collection;
#include "BLI_sys_types.h"
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 415145c8fa1..c63b3d825a0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1098,9 +1098,15 @@ void DepsgraphRelationBuilder::build_object_pointcache(Object *object)
}
else {
flag = FLAG_GEOMETRY;
- OperationKey geometry_key(
- &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
- add_relation(point_cache_key, geometry_key, "Point Cache -> Geometry");
+ OperationKey geometry_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
+ add_relation(point_cache_key, geometry_key, "Point Cache -> Geometry Eval");
+ if (object->data) {
+ /* Geometry may change, so rebuild the Drawing Cache. */
+ OperationKey object_data_batch_all_key(
+ (ID *)object->data, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_ALL);
+ add_relation(
+ point_cache_key, object_data_batch_all_key, "Point Cache -> Batch Update All");
+ }
}
BLI_assert(flag != -1);
/* Tag that we did handle that component. */
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 34b33e9a6c0..063126ff864 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -168,7 +168,6 @@ void depsgraph_tag_to_component_opcode(const ID *id,
break;
case ID_RECALC_GEOMETRY:
depsgraph_geometry_tag_to_component(id, component_type);
- *operation_code = OperationCode::GEOMETRY_EVAL_INIT;
break;
case ID_RECALC_GEOMETRY_DEFORM:
depsgraph_geometry_tag_to_component(id, component_type);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index ff3af9b28d1..f5b95ac97ff 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -91,7 +91,7 @@ typedef struct BoundSphere {
typedef char DRWViewportEmptyList;
#define DRW_VIEWPORT_LIST_SIZE(list) \
- (sizeof(list) == sizeof(DRWViewportEmptyList) ? 0 : ((sizeof(list)) / sizeof(void *)))
+ (sizeof(list) == sizeof(DRWViewportEmptyList) ? 0 : (sizeof(list) / sizeof(void *)))
/* Unused members must be either pass list or 'char *' when not used. */
#define DRW_VIEWPORT_DATA_SIZE(ty) \
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index 344150014ed..6d71b01b7e0 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -76,27 +76,23 @@ struct ExtractorRunData {
class ExtractorRunDatas : public Vector<ExtractorRunData> {
public:
- void filter_into(ExtractorRunDatas &result, eMRIterType iter_type) const
+ void filter_into(ExtractorRunDatas &result, eMRIterType iter_type, const bool is_mesh) const
{
for (const ExtractorRunData &data : *this) {
const MeshExtract *extractor = data.extractor;
- if ((iter_type & MR_ITER_LOOPTRI) && extractor->iter_looptri_bm) {
- BLI_assert(extractor->iter_looptri_mesh);
+ if ((iter_type & MR_ITER_LOOPTRI) && *(&extractor->iter_looptri_bm + is_mesh)) {
result.append(data);
continue;
}
- if ((iter_type & MR_ITER_POLY) && extractor->iter_poly_bm) {
- BLI_assert(extractor->iter_poly_mesh);
+ if ((iter_type & MR_ITER_POLY) && *(&extractor->iter_poly_bm + is_mesh)) {
result.append(data);
continue;
}
- if ((iter_type & MR_ITER_LEDGE) && extractor->iter_ledge_bm) {
- BLI_assert(extractor->iter_ledge_mesh);
+ if ((iter_type & MR_ITER_LEDGE) && *(&extractor->iter_ledge_bm + is_mesh)) {
result.append(data);
continue;
}
- if ((iter_type & MR_ITER_LVERT) && extractor->iter_lvert_bm) {
- BLI_assert(extractor->iter_lvert_mesh);
+ if ((iter_type & MR_ITER_LVERT) && *(&extractor->iter_lvert_bm + is_mesh)) {
result.append(data);
continue;
}
@@ -427,7 +423,7 @@ BLI_INLINE void extract_task_range_run_iter(const MeshRenderData *mr,
return;
}
- extractors->filter_into(range_data.extractors, iter_type);
+ extractors->filter_into(range_data.extractors, iter_type, is_mesh);
BLI_task_parallel_range(0, stop, &range_data, func, settings);
}
diff --git a/source/blender/editors/asset/asset_edit.cc b/source/blender/editors/asset/asset_edit.cc
index 0937af0dbf1..f4860737193 100644
--- a/source/blender/editors/asset/asset_edit.cc
+++ b/source/blender/editors/asset/asset_edit.cc
@@ -82,13 +82,13 @@ bool ED_asset_can_make_single_from_context(const bContext *C)
}
/* TODO better place? */
-/* TODO What about the setter and the itemf? */
+/* TODO What about the setter and the `itemf` callback? */
#include "BKE_preferences.h"
#include "DNA_asset_types.h"
#include "DNA_userdef_types.h"
int ED_asset_library_reference_to_enum_value(const AssetLibraryReference *library)
{
- /* Simple case: Predefined repo, just set the value. */
+ /* Simple case: Predefined repository, just set the value. */
if (library->type < ASSET_LIBRARY_CUSTOM) {
return library->type;
}
@@ -109,7 +109,7 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value)
{
AssetLibraryReference library;
- /* Simple case: Predefined repo, just set the value. */
+ /* Simple case: Predefined repository, just set the value. */
if (value < ASSET_LIBRARY_CUSTOM) {
library.type = value;
library.custom_library_index = -1;
diff --git a/source/blender/editors/asset/asset_list.cc b/source/blender/editors/asset/asset_list.cc
index 1ea948d97d4..dd1c5f360a0 100644
--- a/source/blender/editors/asset/asset_list.cc
+++ b/source/blender/editors/asset/asset_list.cc
@@ -60,7 +60,7 @@ class AssetLibraryReferenceWrapper {
const AssetLibraryReference reference_;
public:
- /* Intentionally not `explicit`, allow implicit conversion for convienience. Might have to be
+ /* Intentionally not `explicit`, allow implicit conversion for convenience. Might have to be
* NOLINT */
AssetLibraryReferenceWrapper(const AssetLibraryReference &reference);
~AssetLibraryReferenceWrapper() = default;
@@ -301,7 +301,7 @@ void AssetList::clear(bContext *C)
filelist_freelib(files);
filelist_clear(files);
- WM_main_add_notifier(NC_ASSET | ND_ASSET_LIST, NULL);
+ WM_main_add_notifier(NC_ASSET | ND_ASSET_LIST, nullptr);
}
/**
@@ -348,7 +348,7 @@ void AssetList::tagMainDataDirty() const
void AssetList::remapID(ID * /*id_old*/, ID * /*id_new*/) const
{
- /* Trigger full refetch of the file list if main data was changed, don't even attempt remap
+ /* Trigger full re-fetch of the file list if main data was changed, don't even attempt remap
* pointers. We could give file list types a id-remap callback, but it's probably not worth it.
* Refreshing local file lists is relatively cheap. */
tagMainDataDirty();
@@ -605,7 +605,7 @@ int ED_assetlist_size(const AssetLibraryReference *library_reference)
}
/**
- * Tag all asset lists in the storage that show main data as needing an update (refetch).
+ * Tag all asset lists in the storage that show main data as needing an update (re-fetch).
*
* This only tags the data. If the asset list is visible on screen, the space is still responsible
* for ensuring the necessary redraw. It can use #ED_assetlist_listen() to check if the asset-list
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 0062e363cdf..8640ffa67cf 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -278,7 +278,7 @@ static void gpencil_stroke_pair_table(bContext *C,
tGPDinterpolate_layer *tgpil)
{
bGPdata *gpd = tgpi->gpd;
- const bool only_selected = ((GPENCIL_EDIT_MODE(gpd)) &&
+ const bool only_selected = (GPENCIL_EDIT_MODE(gpd) &&
((tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) != 0));
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
@@ -291,8 +291,7 @@ static void gpencil_stroke_pair_table(bContext *C,
LISTBASE_FOREACH (bGPDstroke *, gps_from, &tgpil->prevFrame->strokes) {
bGPDstroke *gps_to = NULL;
/* only selected */
- if ((GPENCIL_EDIT_MODE(gpd)) && (only_selected) &&
- ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
+ if (GPENCIL_EDIT_MODE(gpd) && (only_selected) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
continue;
}
/* skip strokes that are invalid for current view */
@@ -712,7 +711,7 @@ static bool gpencil_interpolate_set_init_values(bContext *C, wmOperator *op, tGP
tgpi->flag, (RNA_enum_get(op->ptr, "layers") == 1), GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS);
SET_FLAG_FROM_TEST(
tgpi->flag,
- ((GPENCIL_EDIT_MODE(tgpi->gpd)) && (RNA_boolean_get(op->ptr, "interpolate_selected_only"))),
+ (GPENCIL_EDIT_MODE(tgpi->gpd) && (RNA_boolean_get(op->ptr, "interpolate_selected_only"))),
GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED);
tgpi->flipmode = RNA_enum_get(op->ptr, "flip");
@@ -1249,7 +1248,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
const int step = RNA_int_get(op->ptr, "step");
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
const bool all_layers = (bool)(RNA_enum_get(op->ptr, "layers") == 1);
- const bool only_selected = ((GPENCIL_EDIT_MODE(gpd)) &&
+ const bool only_selected = (GPENCIL_EDIT_MODE(gpd) &&
(RNA_boolean_get(op->ptr, "interpolate_selected_only") != 0));
eGP_InterpolateFlipMode flipmode = RNA_enum_get(op->ptr, "flip");
@@ -1309,7 +1308,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
LISTBASE_FOREACH (bGPDstroke *, gps_from, &prevFrame->strokes) {
bGPDstroke *gps_to = NULL;
/* Only selected. */
- if ((GPENCIL_EDIT_MODE(gpd)) && (only_selected) &&
+ if (GPENCIL_EDIT_MODE(gpd) && (only_selected) &&
((gps_from->flag & GP_STROKE_SELECT) == 0)) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 78eaab01b1a..cf49aefe2ea 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -1316,8 +1316,7 @@ static void gpencil_primitive_interaction_end(bContext *C,
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
const int def_nr = tgpi->gpd->vertex_group_active_index - 1;
- const ListBase *defbase = BKE_object_defgroup_list(tgpi->ob);
- const bool have_weight = (bool)BLI_findlink(defbase, def_nr);
+ const bool have_weight = BLI_findlink(&tgpi->gpd->vertex_group_names, def_nr) != NULL;
/* return to normal cursor and header status */
ED_workspace_status_text(C, NULL);
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 462462cf341..14caf0c08a7 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -1352,7 +1352,7 @@ static void gpencil_sculpt_brush_init_stroke(bContext *C, tGP_BrushEditData *gso
* - This is useful when animating as it saves that "uh-oh" moment when you realize you've
* spent too much time editing the wrong frame.
*/
- if ((IS_AUTOKEY_ON(scene)) && (gpf->framenum != cfra)) {
+ if (IS_AUTOKEY_ON(scene) && (gpf->framenum != cfra)) {
BKE_gpencil_frame_addcopy(gpl, cfra);
/* Need tag to recalculate evaluated data to avoid crashes. */
DEG_id_tag_update(&gso->gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
@@ -1377,7 +1377,7 @@ static float gpencil_sculpt_rotation_eval_get(tGP_BrushEditData *gso,
int idx_eval)
{
/* If multiframe or no modifiers, return 0. */
- if ((GPENCIL_MULTIEDIT_SESSIONS_ON(gso->gpd)) || (!gso->is_transformed)) {
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(gso->gpd) || (!gso->is_transformed)) {
return 0.0f;
}
@@ -1513,8 +1513,7 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
}
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* If masked and the point is not selected, skip it. */
- if ((GPENCIL_ANY_SCULPT_MASK(gso->mask)) &&
- ((pt_active->flag & GP_SPOINT_SELECT) == 0)) {
+ if (GPENCIL_ANY_SCULPT_MASK(gso->mask) && ((pt_active->flag & GP_SPOINT_SELECT) == 0)) {
continue;
}
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index 16605b6c634..633e371cbd1 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -919,7 +919,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
pt_active = pt->runtime.pt_orig;
if (pt_active != NULL) {
/* If masked and the point is not selected, skip it. */
- if ((GPENCIL_ANY_VERTEX_MASK(gso->mask)) &&
+ if (GPENCIL_ANY_VERTEX_MASK(gso->mask) &&
((pt_active->flag & GP_SPOINT_SELECT) == 0)) {
continue;
}
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 5cf2a9c9dd0..50e53acb376 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -34,9 +34,9 @@ struct ListBase;
struct ARegion;
struct ARegionType;
+struct FModifier;
struct Main;
struct NlaStrip;
-struct FModifier;
struct PanelType;
struct ReportList;
struct ScrArea;
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index eaa54f66928..868235c36e5 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -31,7 +31,6 @@
extern "C" {
#endif
-struct bAction;
struct Base;
struct Bone;
struct Depsgraph;
@@ -46,6 +45,7 @@ struct Scene;
struct UndoType;
struct View3D;
struct ViewLayer;
+struct bAction;
struct bArmature;
struct bContext;
struct bPoseChannel;
@@ -255,8 +255,8 @@ struct PoseBackup *ED_pose_backup_create_selected_bones(
struct PoseBackup *ED_pose_backup_create_all_bones(
const struct Object *ob, const struct bAction *action) ATTR_WARN_UNUSED_RESULT;
bool ED_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup);
-void ED_pose_backup_restore(const struct PoseBackup *pose_backup);
-void ED_pose_backup_free(struct PoseBackup *pose_backup);
+void ED_pose_backup_restore(const struct PoseBackup *pbd);
+void ED_pose_backup_free(struct PoseBackup *pbd);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/ED_asset.h b/source/blender/editors/include/ED_asset.h
index d33085f1cc4..0058c0615c3 100644
--- a/source/blender/editors/include/ED_asset.h
+++ b/source/blender/editors/include/ED_asset.h
@@ -28,9 +28,9 @@ extern "C" {
struct AssetFilterSettings;
struct AssetLibraryReference;
-struct bContext;
struct Main;
struct ReportList;
+struct bContext;
struct wmNotifier;
typedef struct AssetTempIDConsumer AssetTempIDConsumer;
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 058d4fa91a3..6e4002fcc0a 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -31,6 +31,7 @@ struct ID;
struct Main;
struct Scene;
struct ScrArea;
+struct SpaceNode;
struct Tex;
struct View2D;
struct bContext;
@@ -40,7 +41,6 @@ struct bNodeSocketType;
struct bNodeTree;
struct bNodeTreeType;
struct bNodeType;
-struct SpaceNode;
typedef enum {
NODE_TOP = 1,
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 6d0172e724a..5318c653b6d 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -34,9 +34,9 @@ struct ParticleSystem;
struct Scene;
struct UndoType;
struct ViewLayer;
-struct wmGenericUserData;
struct bContext;
struct rcti;
+struct wmGenericUserData;
/* particle edit mode */
void PE_free_ptcache_edit(struct PTCacheEdit *edit);
diff --git a/source/blender/editors/include/ED_spreadsheet.h b/source/blender/editors/include/ED_spreadsheet.h
index ff77135a51c..dfa8aa7bfbc 100644
--- a/source/blender/editors/include/ED_spreadsheet.h
+++ b/source/blender/editors/include/ED_spreadsheet.h
@@ -16,14 +16,14 @@
#pragma once
-struct SpreadsheetContext;
-struct SpaceSpreadsheet;
-struct SpaceNode;
struct ID;
-struct bNode;
struct Main;
-struct bContext;
struct Object;
+struct SpaceNode;
+struct SpaceSpreadsheet;
+struct SpreadsheetContext;
+struct bContext;
+struct bNode;
#ifdef __cplusplus
extern "C" {
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index d5316df0e0c..ddde4f5a9dc 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2453,7 +2453,7 @@ bool ui_but_is_rna_valid(uiBut *but)
*/
bool ui_but_supports_cycling(const uiBut *but)
{
- return ((ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX)) ||
+ return (ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX) ||
(but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) ||
(but->type == UI_BTYPE_COLOR && ((uiButColor *)but)->is_pallete_color) ||
(but->menu_step_func != NULL));
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 858955271b2..4f8bb6342f7 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -770,7 +770,7 @@ static uiAfterFunc *ui_afterfunc_new(void)
* \param context_but: A button from which to get the context from (`uiBut.context`) for the
* operator execution.
*
- * \note Ownership over \a properties is moved here. The after-func owns it now.
+ * \note Ownership over \a properties is moved here. The #uiAfterFunc owns it now.
* \note Can only call while handling buttons.
*/
static void ui_handle_afterfunc_add_operator_ex(wmOperatorType *ot,
@@ -1157,7 +1157,7 @@ static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
}
/**
- * \note Ownership of \a properties is moved here. The after-func owns it now.
+ * \note Ownership of \a properties is moved here. The #uiAfterFunc owns it now.
*
* \param context_but: The button to use context from when calling or polling the operator.
*
@@ -9458,10 +9458,10 @@ static int ui_list_handle_click_drag(bContext *C,
activate = true;
}
}
- /* KM_CLICK is only sent after an uncaught release event, so the forground button gets all
+ /* #KM_CLICK is only sent after an uncaught release event, so the foreground button gets all
* regular events (including mouse presses to start dragging) and this part only kicks in if it
* hasn't handled the release event. Note that if there's no overlaid button, the row selects
- * on the press event already via regular UI_BTYPE_LISTROW handling. */
+ * on the press event already via regular #UI_BTYPE_LISTROW handling. */
else if ((event->type == LEFTMOUSE) && (event->val == KM_CLICK)) {
activate = true;
}
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 13436b6c6c8..c863b1f8bdf 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -688,13 +688,13 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
if (data->items.more) {
ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
GPU_blend(GPU_BLEND_ALPHA);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
+ UI_icon_draw(BLI_rcti_size_x(&rect) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
GPU_blend(GPU_BLEND_NONE);
}
if (data->items.offset) {
ui_searchbox_butrect(&rect, data, 0);
GPU_blend(GPU_BLEND_ALPHA);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
+ UI_icon_draw(BLI_rcti_size_x(&rect) / 2, rect.ymax - 7, ICON_TRIA_UP);
GPU_blend(GPU_BLEND_NONE);
}
}
@@ -990,13 +990,13 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
if (data->items.more) {
ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
GPU_blend(GPU_BLEND_ALPHA);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
+ UI_icon_draw(BLI_rcti_size_x(&rect) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
GPU_blend(GPU_BLEND_NONE);
}
if (data->items.offset) {
ui_searchbox_butrect(&rect, data, 0);
GPU_blend(GPU_BLEND_ALPHA);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
+ UI_icon_draw(BLI_rcti_size_x(&rect) / 2, rect.ymax - 7, ICON_TRIA_UP);
GPU_blend(GPU_BLEND_NONE);
}
}
diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc
index 2860abb32a1..5a05813f947 100644
--- a/source/blender/editors/interface/interface_template_asset_view.cc
+++ b/source/blender/editors/interface/interface_template_asset_view.cc
@@ -53,7 +53,7 @@ static void asset_view_item_but_drag_set(uiBut *but,
AssetHandle *asset_handle)
{
ID *id = asset_handle->file_data->id;
- if (id != NULL) {
+ if (id != nullptr) {
UI_but_drag_set_id(but, id);
return;
}
@@ -257,14 +257,14 @@ void uiTemplateAssetView(uiLayout *layout,
if (activate_opname) {
PointerRNA *ptr = UI_list_custom_activate_operator_set(
- list, activate_opname, r_activate_op_properties != NULL);
+ list, activate_opname, r_activate_op_properties != nullptr);
if (r_activate_op_properties && ptr) {
*r_activate_op_properties = *ptr;
}
}
if (drag_opname) {
PointerRNA *ptr = UI_list_custom_drag_operator_set(
- list, drag_opname, r_drag_op_properties != NULL);
+ list, drag_opname, r_drag_op_properties != nullptr);
if (r_drag_op_properties && ptr) {
*r_drag_op_properties = *ptr;
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index aa6dff3952a..93a790b53d0 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -852,7 +852,7 @@ static bool ui_view2d_cur_ensure_rect_in_view(View2D *v2d, const rctf *rect)
void UI_but_ensure_in_view(const bContext *C, ARegion *region, const uiBut *but)
{
View2D *v2d = &region->v2d;
- /* Unitialized view or region that doesn't use View2D. */
+ /* Uninitialized view or region that doesn't use View2D. */
if ((v2d->flag & V2D_IS_INIT) == 0) {
return;
}
diff --git a/source/blender/editors/io/io_gpencil.h b/source/blender/editors/io/io_gpencil.h
index b347be00412..428b09f0e9c 100644
--- a/source/blender/editors/io/io_gpencil.h
+++ b/source/blender/editors/io/io_gpencil.h
@@ -25,8 +25,8 @@
*/
struct ARegion;
-struct bContext;
struct View3D;
+struct bContext;
struct wmOperatorType;
void WM_OT_gpencil_import_svg(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 2109fe2a822..6251fb799c5 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -123,9 +123,14 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
RNA_enum_items_add_value(
&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_ALL_SRC);
- if (data_type == DT_TYPE_MDEFORMVERT) {
- Object *ob_src = CTX_data_active_object(C);
+ Object *ob_src = CTX_data_active_object(C);
+ if (ob_src == NULL) {
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+ return item;
+ }
+ if (data_type == DT_TYPE_MDEFORMVERT && BKE_object_supports_vertex_groups(ob_src)) {
if (BKE_object_pose_armature_get(ob_src)) {
RNA_enum_items_add_value(
&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_SELECT);
@@ -133,67 +138,57 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_DEFORM);
}
- if (ob_src) {
- const bDeformGroup *dg;
- int i;
+ const bDeformGroup *dg;
+ int i;
- RNA_enum_item_add_separator(&item, &totitem);
+ RNA_enum_item_add_separator(&item, &totitem);
- const ListBase *defbase = BKE_object_defgroup_list(ob_src);
- for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
- tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = dg->name;
- RNA_enum_item_add(&item, &totitem, &tmp_item);
- }
+ const ListBase *defbase = BKE_object_defgroup_list(ob_src);
+ for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = dg->name;
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
else if (data_type == DT_TYPE_SHAPEKEY) {
/* TODO */
}
else if (data_type == DT_TYPE_UV) {
- Object *ob_src = CTX_data_active_object(C);
-
- if (ob_src) {
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
- CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
- cddata_masks.lmask |= CD_MASK_MLOOPUV;
- Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
- int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
+ CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
+ cddata_masks.lmask |= CD_MASK_MLOOPUV;
+ Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
+ int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
- RNA_enum_item_add_separator(&item, &totitem);
+ RNA_enum_item_add_separator(&item, &totitem);
- for (int i = 0; i < num_data; i++) {
- tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
- &me_eval->ldata, CD_MLOOPUV, i);
- RNA_enum_item_add(&item, &totitem, &tmp_item);
- }
+ for (int i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
+ &me_eval->ldata, CD_MLOOPUV, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
else if (data_type == DT_TYPE_VCOL) {
- Object *ob_src = CTX_data_active_object(C);
-
- if (ob_src) {
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
- CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
- cddata_masks.lmask |= CD_MASK_MLOOPCOL;
- Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
- int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPCOL);
+ CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
+ cddata_masks.lmask |= CD_MASK_MLOOPCOL;
+ Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
+ int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPCOL);
- RNA_enum_item_add_separator(&item, &totitem);
+ RNA_enum_item_add_separator(&item, &totitem);
- for (int i = 0; i < num_data; i++) {
- tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
- &me_eval->ldata, CD_MLOOPCOL, i);
- RNA_enum_item_add(&item, &totitem, &tmp_item);
- }
+ for (int i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
+ &me_eval->ldata, CD_MLOOPCOL, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 4ea599fd30e..f64f95c5322 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -3892,7 +3892,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
int fail = 0;
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
- if (obact != ob) {
+ if (obact != ob && BKE_object_supports_vertex_groups(ob)) {
if (ED_vgroup_array_copy(ob, obact)) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(CTX_data_main(C));
@@ -3909,8 +3909,8 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
if ((changed_tot == 0 && fail == 0) || fail) {
BKE_reportf(op->reports,
RPT_ERROR,
- "Copy vertex groups to selected: %d done, %d failed (object data must have "
- "matching indices)",
+ "Copy vertex groups to selected: %d done, %d failed (object data must support "
+ "vertex groups and have matching indices)",
changed_tot,
fail);
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 9abf15d2198..5aa63ac56d8 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -861,9 +861,9 @@ static void action_preview_render_cleanup(IconPreview *preview, struct PoseBacku
DEG_id_tag_update(&preview->active_object->id, ID_RECALC_GEOMETRY);
}
-/* Render a pose. It is assumed that the pose has already been applied and that the scene camera is
- * capturing the pose. In other words, this function just renders from the scene camera without
- * evaluating the Action stored in preview->id. */
+/* Render a pose from the scene camera. It is assumed that the scene camera is
+ * capturing the pose. The pose is applied temporarily to the current object
+ * before rendering. */
static void action_preview_render(IconPreview *preview, IconPreviewSize *preview_sized)
{
char err_out[256] = "";
@@ -1308,8 +1308,9 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
scaledy = (float)h;
}
- ex = (short)scaledx;
- ey = (short)scaledy;
+ /* Scaling down must never assign zero width/height, see: T89868. */
+ ex = MAX2(1, (short)scaledx);
+ ey = MAX2(1, (short)scaledy);
dx = (w - ex) / 2;
dy = (h - ey) / 2;
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index ffa6f6ac962..23b90171a1d 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -784,11 +784,10 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s,
bool do_random = false;
bool do_partial_update = false;
- bool update_color = ((brush->flag & BRUSH_USE_GRADIENT) &&
- ((ELEM(brush->gradient_stroke_mode,
- BRUSH_GRADIENT_SPACING_REPEAT,
- BRUSH_GRADIENT_SPACING_CLAMP)) ||
- (cache->last_pressure != pressure)));
+ bool update_color = ((brush->flag & BRUSH_USE_GRADIENT) && (ELEM(brush->gradient_stroke_mode,
+ BRUSH_GRADIENT_SPACING_REPEAT,
+ BRUSH_GRADIENT_SPACING_CLAMP) ||
+ (cache->last_pressure != pressure)));
float tex_rotation = -brush->mtex.rot;
float mask_rotation = -brush->mask_mtex.rot;
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index 7564fa4b930..9cb363ff0c9 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -34,8 +34,8 @@ struct Tex;
struct bContext;
struct bContextDataResult;
struct bNode;
-struct bNodeTree;
struct bNodeSocket;
+struct bNodeTree;
struct wmOperatorType;
struct SpaceProperties_Runtime {
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 1421be41124..a853efb1ace 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -859,7 +859,7 @@ static int graphkeys_box_select_exec(bContext *C, wmOperator *op)
* as frame-range one is often used for tweaking timing when "blocking",
* while channels is not that useful.
*/
- if ((BLI_rcti_size_x(&rect)) >= (BLI_rcti_size_y(&rect))) {
+ if (BLI_rcti_size_x(&rect) >= BLI_rcti_size_y(&rect)) {
mode = BEZT_OK_FRAMERANGE;
}
else {
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 50b0ea75052..4779a82948d 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -1013,14 +1013,14 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, bool color_ma
uiLayoutRow(col, true), imfptr, "color_mode", UI_ITEM_R_EXPAND, IFACE_("Color"), ICON_NONE);
/* only display depth setting if multiple depths can be used */
- if ((ELEM(depth_ok,
- R_IMF_CHAN_DEPTH_1,
- R_IMF_CHAN_DEPTH_8,
- R_IMF_CHAN_DEPTH_10,
- R_IMF_CHAN_DEPTH_12,
- R_IMF_CHAN_DEPTH_16,
- R_IMF_CHAN_DEPTH_24,
- R_IMF_CHAN_DEPTH_32)) == 0) {
+ if (ELEM(depth_ok,
+ R_IMF_CHAN_DEPTH_1,
+ R_IMF_CHAN_DEPTH_8,
+ R_IMF_CHAN_DEPTH_10,
+ R_IMF_CHAN_DEPTH_12,
+ R_IMF_CHAN_DEPTH_16,
+ R_IMF_CHAN_DEPTH_24,
+ R_IMF_CHAN_DEPTH_32) == 0) {
uiItemR(uiLayoutRow(col, true), imfptr, "color_depth", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 6b9821745c7..dad354ba8ee 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1995,7 +1995,7 @@ static bool image_save_as_draw_check_prop(PointerRNA *ptr,
return !(STREQ(prop_id, "filepath") || STREQ(prop_id, "directory") ||
STREQ(prop_id, "filename") ||
/* when saving a copy, relative path has no effect */
- ((STREQ(prop_id, "relative_path")) && RNA_boolean_get(ptr, "copy")));
+ (STREQ(prop_id, "relative_path") && RNA_boolean_get(ptr, "copy")));
}
static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
index c9b73aabf96..680da9b6794 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
@@ -22,8 +22,8 @@
#include "BLI_float2.hh"
#include "BLI_float3.hh"
-struct Object;
struct Collection;
+struct Object;
namespace blender::ed::spreadsheet {
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh
index d9e6d882c2a..19906d73e7f 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh
@@ -23,9 +23,9 @@
#include "spreadsheet_dataset_layout.hh"
struct ARegion;
-struct uiBlock;
struct View2D;
struct bContext;
+struct uiBlock;
namespace blender::ed::spreadsheet {
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_draw.hh b/source/blender/editors/space_spreadsheet/spreadsheet_draw.hh
index 647587ec8b0..9accd1d3d09 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_draw.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_draw.hh
@@ -18,9 +18,9 @@
#include "BLI_vector.hh"
-struct uiBlock;
-struct bContext;
struct ARegion;
+struct bContext;
+struct uiBlock;
namespace blender::ed::spreadsheet {
diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c
index 16eb66624ce..0cd2d9baa0b 100644
--- a/source/blender/editors/space_text/text_format_lua.c
+++ b/source/blender/editors/space_text/text_format_lua.c
@@ -165,9 +165,9 @@ static char txtfmt_lua_format_identifier(const char *str)
/* Keep aligned args for readability. */
/* clang-format off */
- if ((txtfmt_lua_find_specialvar(str)) != -1) { fmt = FMT_TYPE_SPECIAL;
- } else if ((txtfmt_lua_find_keyword(str)) != -1) { fmt = FMT_TYPE_KEYWORD;
- } else { fmt = FMT_TYPE_DEFAULT;
+ if (txtfmt_lua_find_specialvar(str) != -1) { fmt = FMT_TYPE_SPECIAL;
+ } else if (txtfmt_lua_find_keyword(str) != -1) { fmt = FMT_TYPE_KEYWORD;
+ } else { fmt = FMT_TYPE_DEFAULT;
}
/* clang-format on */
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
index 1a024779a83..97d9ec546ca 100644
--- a/source/blender/editors/space_text/text_format_osl.c
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -189,11 +189,11 @@ static char txtfmt_osl_format_identifier(const char *str)
/* Keep aligned args for readability. */
/* clang-format off */
- if ((txtfmt_osl_find_specialvar(str)) != -1) { fmt = FMT_TYPE_SPECIAL;
- } else if ((txtfmt_osl_find_builtinfunc(str)) != -1) { fmt = FMT_TYPE_KEYWORD;
- } else if ((txtfmt_osl_find_reserved(str)) != -1) { fmt = FMT_TYPE_RESERVED;
- } else if ((txtfmt_osl_find_preprocessor(str)) != -1) { fmt = FMT_TYPE_DIRECTIVE;
- } else { fmt = FMT_TYPE_DEFAULT;
+ if (txtfmt_osl_find_specialvar(str) != -1) { fmt = FMT_TYPE_SPECIAL;
+ } else if (txtfmt_osl_find_builtinfunc(str) != -1) { fmt = FMT_TYPE_KEYWORD;
+ } else if (txtfmt_osl_find_reserved(str) != -1) { fmt = FMT_TYPE_RESERVED;
+ } else if (txtfmt_osl_find_preprocessor(str) != -1) { fmt = FMT_TYPE_DIRECTIVE;
+ } else { fmt = FMT_TYPE_DEFAULT;
}
/* clang-format on */
diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c
index 1200dda7533..ea3d0ec1478 100644
--- a/source/blender/editors/space_text/text_format_pov.c
+++ b/source/blender/editors/space_text/text_format_pov.c
@@ -762,11 +762,11 @@ static char txtfmt_pov_format_identifier(const char *str)
/* Keep aligned args for readability. */
/* clang-format off */
- if ((txtfmt_pov_find_specialvar(str)) != -1) { fmt = FMT_TYPE_SPECIAL;
- } else if ((txtfmt_pov_find_keyword(str)) != -1) { fmt = FMT_TYPE_KEYWORD;
- } else if ((txtfmt_pov_find_reserved_keywords(str)) != -1) { fmt = FMT_TYPE_RESERVED;
- } else if ((txtfmt_pov_find_reserved_builtins(str)) != -1) { fmt = FMT_TYPE_DIRECTIVE;
- } else { fmt = FMT_TYPE_DEFAULT;
+ if (txtfmt_pov_find_specialvar(str) != -1) { fmt = FMT_TYPE_SPECIAL;
+ } else if (txtfmt_pov_find_keyword(str) != -1) { fmt = FMT_TYPE_KEYWORD;
+ } else if (txtfmt_pov_find_reserved_keywords(str) != -1) { fmt = FMT_TYPE_RESERVED;
+ } else if (txtfmt_pov_find_reserved_builtins(str) != -1) { fmt = FMT_TYPE_DIRECTIVE;
+ } else { fmt = FMT_TYPE_DEFAULT;
}
/* clang-format on */
diff --git a/source/blender/editors/space_text/text_format_pov_ini.c b/source/blender/editors/space_text/text_format_pov_ini.c
index 1c6a93d2d7a..259ad02a6b7 100644
--- a/source/blender/editors/space_text/text_format_pov_ini.c
+++ b/source/blender/editors/space_text/text_format_pov_ini.c
@@ -347,10 +347,10 @@ static int txtfmt_ini_find_bool(const char *string)
static char txtfmt_pov_ini_format_identifier(const char *str)
{
char fmt;
- if ((txtfmt_ini_find_keyword(str)) != -1) {
+ if (txtfmt_ini_find_keyword(str) != -1) {
fmt = FMT_TYPE_KEYWORD;
}
- else if ((txtfmt_ini_find_reserved(str)) != -1) {
+ else if (txtfmt_ini_find_reserved(str) != -1) {
fmt = FMT_TYPE_RESERVED;
}
else {
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
index 2717c0bf5b0..e2a01a8d85d 100644
--- a/source/blender/editors/space_text/text_format_py.c
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -315,10 +315,10 @@ static char txtfmt_py_format_identifier(const char *str)
/* Keep aligned args for readability. */
/* clang-format off */
- if ((txtfmt_py_find_specialvar(str)) != -1) { fmt = FMT_TYPE_SPECIAL;
- } else if ((txtfmt_py_find_builtinfunc(str)) != -1) { fmt = FMT_TYPE_KEYWORD;
- } else if ((txtfmt_py_find_decorator(str)) != -1) { fmt = FMT_TYPE_RESERVED;
- } else { fmt = FMT_TYPE_DEFAULT;
+ if (txtfmt_py_find_specialvar(str) != -1) { fmt = FMT_TYPE_SPECIAL;
+ } else if (txtfmt_py_find_builtinfunc(str) != -1) { fmt = FMT_TYPE_KEYWORD;
+ } else if (txtfmt_py_find_decorator(str) != -1) { fmt = FMT_TYPE_RESERVED;
+ } else { fmt = FMT_TYPE_DEFAULT;
}
/* clang-format on */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d34cc6f424f..efcf7d587e1 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -78,7 +78,7 @@ static void initSnapSpatial(TransInfo *t, float r_snap[2]);
bool transdata_check_local_islands(TransInfo *t, short around)
{
- return ((around == V3D_AROUND_LOCAL_ORIGINS) && ((ELEM(t->obedit_type, OB_MESH, OB_GPENCIL))));
+ return ((around == V3D_AROUND_LOCAL_ORIGINS) && (ELEM(t->obedit_type, OB_MESH, OB_GPENCIL)));
}
/* ************************** SPACE DEPENDENT CODE **************************** */
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index a6f5aba5a1d..17512c79d03 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -262,8 +262,16 @@ static void free_transform_custom_data(TransCustomData *custom_data)
/* Canceled, need to update the strips display. */
static void seq_transform_cancel(TransInfo *t, SeqCollection *transformed_strips)
{
+ ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false));
+
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ /* Handle pre-existing overlapping strips even when operator is canceled.
+ * This is necessary for SEQUENCER_OT_duplicate_move macro for example. */
+ if (SEQ_transform_test_overlap(seqbase, seq)) {
+ SEQ_transform_seqbase_shuffle(seqbase, seq, t->scene);
+ }
+
SEQ_time_update_sequence_bounds(t->scene, seq);
}
}
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 0368252f54b..3e0029156c1 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -695,7 +695,7 @@ int ED_undo_operator_repeat(bContext *C, wmOperator *op)
CTX_wm_region_set(C, region_win);
}
- if ((WM_operator_repeat_check(C, op)) && (WM_operator_poll(C, op->type)) &&
+ if (WM_operator_repeat_check(C, op) && WM_operator_poll(C, op->type) &&
/* NOTE: undo/redo can't run if there are jobs active,
* check for screen jobs only so jobs like material/texture/world preview
* (which copy their data), won't stop redo, see T29579],
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 28853bcdedf..535a0e00347 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1928,6 +1928,11 @@ static StitchState *stitch_init(bContext *C,
state->obedit = obedit;
state->em = em;
+ /* Workaround for sync-select & face-select mode which implies all selected faces are detached,
+ * for stitch this isn't useful behavior, see T86924. */
+ const int selectmode_orig = scene->toolsettings->selectmode;
+ scene->toolsettings->selectmode = SCE_SELECT_VERTEX;
+
/* in uv synch selection, all uv's are visible */
if (ts->uv_flag & UV_SYNC_SELECTION) {
state->element_map = BM_uv_element_map_create(state->em->bm, scene, false, false, true, true);
@@ -1935,6 +1940,9 @@ static StitchState *stitch_init(bContext *C,
else {
state->element_map = BM_uv_element_map_create(state->em->bm, scene, true, false, true, true);
}
+
+ scene->toolsettings->selectmode = selectmode_orig;
+
if (!state->element_map) {
state_delete(state);
return NULL;
@@ -1989,7 +1997,7 @@ static StitchState *stitch_init(bContext *C,
/* Now, on to generate our uv connectivity data */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!(ts->uv_flag & UV_SYNC_SELECTION) &&
- ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || !BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
+ (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) || !BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
continue;
}
@@ -2172,8 +2180,8 @@ static StitchState *stitch_init(bContext *C,
"uv_stitch_selection_stack");
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!(ts->uv_flag & UV_SYNC_SELECTION) && ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
- !BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
+ if (!(ts->uv_flag & UV_SYNC_SELECTION) &&
+ (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) || !BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
continue;
}
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 0e9669d0f60..3d5dabda23d 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -315,7 +315,7 @@ static ParamHandle *construct_param_handle(const Scene *scene,
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
+ if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ||
(options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue;
}
@@ -404,7 +404,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
+ if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ||
(options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index cd0059f3c21..afb23690a84 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -2285,7 +2285,7 @@ struct less_SVertex2D {
Vec3r A = x->point2D();
Vec3r B = y->point2D();
for (unsigned int i = 0; i < 3; i++) {
- if ((fabs(A[i] - B[i])) < epsilon) {
+ if (fabs(A[i] - B[i]) < epsilon) {
continue;
}
if (A[i] < B[i]) {
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 247b0b3f57b..1d4370ed3a9 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -575,9 +575,9 @@ BLI_INLINE int lineart_LineIntersectTest2d(
}
struct Depsgraph;
-struct Scene;
-struct LineartRenderBuffer;
struct LineartGpencilModifierData;
+struct LineartRenderBuffer;
+struct Scene;
void MOD_lineart_destroy_render_data(struct LineartGpencilModifierData *lmd);
@@ -602,8 +602,8 @@ LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartRenderBuffer *r
LineartBoundingArea *MOD_lineart_get_bounding_area(LineartRenderBuffer *rb, double x, double y);
-struct bGPDlayer;
struct bGPDframe;
+struct bGPDlayer;
void MOD_lineart_gpencil_generate(LineartCache *cache,
struct Depsgraph *depsgraph,
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 9899d889c56..82fd85f5c65 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -3442,9 +3442,9 @@ static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb,
return true;
}
- 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))) {
+ 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;
}
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
index 9d109320f09..70ff4a373dd 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
@@ -33,10 +33,10 @@
#include <math.h>
#include <string.h>
-struct LineartStaticMemPool;
-struct LineartStaticMemPoolNode;
struct LineartEdge;
struct LineartRenderBuffer;
+struct LineartStaticMemPool;
+struct LineartStaticMemPoolNode;
void *lineart_list_append_pointer_pool(ListBase *h, struct LineartStaticMemPool *smp, void *data);
void *lineart_list_append_pointer_pool_sized(ListBase *h,
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index 1293cc0953d..4bb13d01c2d 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -609,7 +609,13 @@ GPUOffScreen *GPU_offscreen_create(
}
if ((depth && !ofs->depth) || !ofs->color) {
- BLI_snprintf(err_out, 256, "GPUTexture: Texture allocation failed.");
+ const char error[] = "GPUTexture: Texture allocation failed.";
+ if (err_out) {
+ BLI_snprintf(err_out, 256, error);
+ }
+ else {
+ fprintf(stderr, error);
+ }
GPU_offscreen_free(ofs);
return nullptr;
}
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index 7646cce2a3e..585cb296bac 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -88,7 +88,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
name = outnode->name;
input = outnode->inputs.first;
- if ((STR_ELEM(name, "set_value", "set_rgb", "set_rgba")) && (input->type == type)) {
+ if (STR_ELEM(name, "set_value", "set_rgb", "set_rgba") && (input->type == type)) {
input = MEM_dupallocN(outnode->inputs.first);
if (input->link) {
input->link->users++;
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index f90c37e5c50..42b85da1f93 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -90,7 +90,7 @@ void GLBackend::platform_init()
device |= GPU_DEVICE_INTEL_UHD;
}
}
- else if ((strstr(renderer, "Mesa DRI R")) ||
+ else if (strstr(renderer, "Mesa DRI R") ||
(strstr(renderer, "Radeon") && strstr(vendor, "X.Org")) ||
(strstr(renderer, "AMD") && strstr(vendor, "X.Org")) ||
(strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) ||
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 2cfce7b1ba0..d527aca184c 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -69,8 +69,8 @@ extern "C" {
* \attention defined in ???
*/
struct ImBuf;
-struct rcti;
struct rctf;
+struct rcti;
/**
*
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 4a964c64917..79c2583f983 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -1195,22 +1195,9 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
{
uchar *rect, *_newrect = NULL, *newrect;
float *rectf, *_newrectf = NULL, *newrectf;
- float sample, add;
- float val_a, nval_a, diff_a;
- float val_b, nval_b, diff_b;
- float val_g, nval_g, diff_g;
- float val_r, nval_r, diff_r;
- float val_af, nval_af, diff_af;
- float val_bf, nval_bf, diff_bf;
- float val_gf, nval_gf, diff_gf;
- float val_rf, nval_rf, diff_rf;
int x, y;
bool do_rect = false, do_float = false;
- val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
- val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
- val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
- val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
if (ibuf == NULL) {
return NULL;
}
@@ -1236,119 +1223,158 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
}
}
- add = (ibuf->x - 1.001) / (newx - 1.0);
-
rect = (uchar *)ibuf->rect;
rectf = (float *)ibuf->rect_float;
newrect = _newrect;
newrectf = _newrectf;
- for (y = ibuf->y; y > 0; y--) {
-
- sample = 0;
-
+ /* Special case, copy all columns, needed since the scaling logic assumes there is at least
+ * two rows to interpolate between causing out of bounds read for 1px images, see T70356. */
+ if (UNLIKELY(ibuf->x == 1)) {
if (do_rect) {
- val_a = rect[0];
- nval_a = rect[4];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = rect[1];
- nval_b = rect[5];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = rect[2];
- nval_g = rect[6];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = rect[3];
- nval_r = rect[7];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
-
- rect += 8;
+ for (y = ibuf->y; y > 0; y--) {
+ for (x = newx; x > 0; x--) {
+ memcpy(newrect, rect, sizeof(char[4]));
+ newrect += 4;
+ }
+ rect += 4;
+ }
}
if (do_float) {
- val_af = rectf[0];
- nval_af = rectf[4];
- diff_af = nval_af - val_af;
+ for (y = ibuf->y; y > 0; y--) {
+ for (x = newx; x > 0; x--) {
+ memcpy(newrectf, rectf, sizeof(float[4]));
+ newrectf += 4;
+ }
+ rectf += 4;
+ }
+ }
+ }
+ else {
+ const float add = (ibuf->x - 1.001) / (newx - 1.0);
+ float sample;
- val_bf = rectf[1];
- nval_bf = rectf[5];
- diff_bf = nval_bf - val_bf;
+ float val_a, nval_a, diff_a;
+ float val_b, nval_b, diff_b;
+ float val_g, nval_g, diff_g;
+ float val_r, nval_r, diff_r;
+ float val_af, nval_af, diff_af;
+ float val_bf, nval_bf, diff_bf;
+ float val_gf, nval_gf, diff_gf;
+ float val_rf, nval_rf, diff_rf;
- val_gf = rectf[2];
- nval_gf = rectf[6];
- diff_gf = nval_gf - val_gf;
+ val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
+ val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
+ val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
+ val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
- val_rf = rectf[3];
- nval_rf = rectf[7];
- diff_rf = nval_rf - val_rf;
+ for (y = ibuf->y; y > 0; y--) {
- rectf += 8;
- }
- for (x = newx; x > 0; x--) {
- if (sample >= 1.0f) {
- sample -= 1.0f;
+ sample = 0;
- if (do_rect) {
- val_a = nval_a;
- nval_a = rect[0];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = nval_b;
- nval_b = rect[1];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = nval_g;
- nval_g = rect[2];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = nval_r;
- nval_r = rect[3];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
- rect += 4;
- }
- if (do_float) {
- val_af = nval_af;
- nval_af = rectf[0];
- diff_af = nval_af - val_af;
+ if (do_rect) {
+ val_a = rect[0];
+ nval_a = rect[4];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = rect[1];
+ nval_b = rect[5];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = rect[2];
+ nval_g = rect[6];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = rect[3];
+ nval_r = rect[7];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+
+ rect += 8;
+ }
+ if (do_float) {
+ val_af = rectf[0];
+ nval_af = rectf[4];
+ diff_af = nval_af - val_af;
- val_bf = nval_bf;
- nval_bf = rectf[1];
- diff_bf = nval_bf - val_bf;
+ val_bf = rectf[1];
+ nval_bf = rectf[5];
+ diff_bf = nval_bf - val_bf;
- val_gf = nval_gf;
- nval_gf = rectf[2];
- diff_gf = nval_gf - val_gf;
+ val_gf = rectf[2];
+ nval_gf = rectf[6];
+ diff_gf = nval_gf - val_gf;
- val_rf = nval_rf;
- nval_rf = rectf[3];
- diff_rf = nval_rf - val_rf;
- rectf += 4;
- }
- }
- if (do_rect) {
- newrect[0] = val_a + sample * diff_a;
- newrect[1] = val_b + sample * diff_b;
- newrect[2] = val_g + sample * diff_g;
- newrect[3] = val_r + sample * diff_r;
- newrect += 4;
+ val_rf = rectf[3];
+ nval_rf = rectf[7];
+ diff_rf = nval_rf - val_rf;
+
+ rectf += 8;
}
- if (do_float) {
- newrectf[0] = val_af + sample * diff_af;
- newrectf[1] = val_bf + sample * diff_bf;
- newrectf[2] = val_gf + sample * diff_gf;
- newrectf[3] = val_rf + sample * diff_rf;
- newrectf += 4;
+ for (x = newx; x > 0; x--) {
+ if (sample >= 1.0f) {
+ sample -= 1.0f;
+
+ if (do_rect) {
+ val_a = nval_a;
+ nval_a = rect[0];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = nval_b;
+ nval_b = rect[1];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = nval_g;
+ nval_g = rect[2];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = nval_r;
+ nval_r = rect[3];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+ rect += 4;
+ }
+ if (do_float) {
+ val_af = nval_af;
+ nval_af = rectf[0];
+ diff_af = nval_af - val_af;
+
+ val_bf = nval_bf;
+ nval_bf = rectf[1];
+ diff_bf = nval_bf - val_bf;
+
+ val_gf = nval_gf;
+ nval_gf = rectf[2];
+ diff_gf = nval_gf - val_gf;
+
+ val_rf = nval_rf;
+ nval_rf = rectf[3];
+ diff_rf = nval_rf - val_rf;
+ rectf += 4;
+ }
+ }
+ if (do_rect) {
+ newrect[0] = val_a + sample * diff_a;
+ newrect[1] = val_b + sample * diff_b;
+ newrect[2] = val_g + sample * diff_g;
+ newrect[3] = val_r + sample * diff_r;
+ newrect += 4;
+ }
+ if (do_float) {
+ newrectf[0] = val_af + sample * diff_af;
+ newrectf[1] = val_bf + sample * diff_bf;
+ newrectf[2] = val_gf + sample * diff_gf;
+ newrectf[3] = val_rf + sample * diff_rf;
+ newrectf += 4;
+ }
+ sample += add;
}
- sample += add;
}
}
@@ -1371,22 +1397,9 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
{
uchar *rect, *_newrect = NULL, *newrect;
float *rectf, *_newrectf = NULL, *newrectf;
- float sample, add;
- float val_a, nval_a, diff_a;
- float val_b, nval_b, diff_b;
- float val_g, nval_g, diff_g;
- float val_r, nval_r, diff_r;
- float val_af, nval_af, diff_af;
- float val_bf, nval_bf, diff_bf;
- float val_gf, nval_gf, diff_gf;
- float val_rf, nval_rf, diff_rf;
int x, y, skipx;
bool do_rect = false, do_float = false;
- val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
- val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
- val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
- val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
if (ibuf == NULL) {
return NULL;
}
@@ -1412,126 +1425,159 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
}
}
- add = (ibuf->y - 1.001) / (newy - 1.0);
- skipx = 4 * ibuf->x;
-
rect = (uchar *)ibuf->rect;
rectf = (float *)ibuf->rect_float;
newrect = _newrect;
newrectf = _newrectf;
- for (x = ibuf->x; x > 0; x--) {
+ skipx = 4 * ibuf->x;
- sample = 0;
+ /* Special case, copy all rows, needed since the scaling logic assumes there is at least
+ * two rows to interpolate between causing out of bounds read for 1px images, see T70356. */
+ if (UNLIKELY(ibuf->y == 1)) {
if (do_rect) {
- rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
- newrect = _newrect + 4 * (x - 1);
-
- val_a = rect[0];
- nval_a = rect[skipx];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = rect[1];
- nval_b = rect[skipx + 1];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = rect[2];
- nval_g = rect[skipx + 2];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = rect[3];
- nval_r = rect[skipx + 3];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
-
- rect += 2 * skipx;
+ for (y = newy; y > 0; y--) {
+ memcpy(newrect, rect, sizeof(char) * skipx);
+ newrect += skipx;
+ }
}
if (do_float) {
- rectf = ibuf->rect_float + 4 * (x - 1);
- newrectf = _newrectf + 4 * (x - 1);
-
- val_af = rectf[0];
- nval_af = rectf[skipx];
- diff_af = nval_af - val_af;
+ for (y = newy; y > 0; y--) {
+ memcpy(newrectf, rectf, sizeof(float) * skipx);
+ newrectf += skipx;
+ }
+ }
+ }
+ else {
+ const float add = (ibuf->y - 1.001) / (newy - 1.0);
+ float sample;
+
+ float val_a, nval_a, diff_a;
+ float val_b, nval_b, diff_b;
+ float val_g, nval_g, diff_g;
+ float val_r, nval_r, diff_r;
+ float val_af, nval_af, diff_af;
+ float val_bf, nval_bf, diff_bf;
+ float val_gf, nval_gf, diff_gf;
+ float val_rf, nval_rf, diff_rf;
+
+ val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
+ val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
+ val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
+ val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
+
+ for (x = ibuf->x; x > 0; x--) {
+ sample = 0;
+ if (do_rect) {
+ rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
+ newrect = _newrect + 4 * (x - 1);
+
+ val_a = rect[0];
+ nval_a = rect[skipx];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = rect[1];
+ nval_b = rect[skipx + 1];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = rect[2];
+ nval_g = rect[skipx + 2];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = rect[3];
+ nval_r = rect[skipx + 3];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+
+ rect += 2 * skipx;
+ }
+ if (do_float) {
+ rectf = ibuf->rect_float + 4 * (x - 1);
+ newrectf = _newrectf + 4 * (x - 1);
- val_bf = rectf[1];
- nval_bf = rectf[skipx + 1];
- diff_bf = nval_bf - val_bf;
+ val_af = rectf[0];
+ nval_af = rectf[skipx];
+ diff_af = nval_af - val_af;
- val_gf = rectf[2];
- nval_gf = rectf[skipx + 2];
- diff_gf = nval_gf - val_gf;
+ val_bf = rectf[1];
+ nval_bf = rectf[skipx + 1];
+ diff_bf = nval_bf - val_bf;
- val_rf = rectf[3];
- nval_rf = rectf[skipx + 3];
- diff_rf = nval_rf - val_rf;
+ val_gf = rectf[2];
+ nval_gf = rectf[skipx + 2];
+ diff_gf = nval_gf - val_gf;
- rectf += 2 * skipx;
- }
+ val_rf = rectf[3];
+ nval_rf = rectf[skipx + 3];
+ diff_rf = nval_rf - val_rf;
- for (y = newy; y > 0; y--) {
- if (sample >= 1.0f) {
- sample -= 1.0f;
+ rectf += 2 * skipx;
+ }
+ for (y = newy; y > 0; y--) {
+ if (sample >= 1.0f) {
+ sample -= 1.0f;
+
+ if (do_rect) {
+ val_a = nval_a;
+ nval_a = rect[0];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = nval_b;
+ nval_b = rect[1];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = nval_g;
+ nval_g = rect[2];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = nval_r;
+ nval_r = rect[3];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+ rect += skipx;
+ }
+ if (do_float) {
+ val_af = nval_af;
+ nval_af = rectf[0];
+ diff_af = nval_af - val_af;
+
+ val_bf = nval_bf;
+ nval_bf = rectf[1];
+ diff_bf = nval_bf - val_bf;
+
+ val_gf = nval_gf;
+ nval_gf = rectf[2];
+ diff_gf = nval_gf - val_gf;
+
+ val_rf = nval_rf;
+ nval_rf = rectf[3];
+ diff_rf = nval_rf - val_rf;
+ rectf += skipx;
+ }
+ }
if (do_rect) {
- val_a = nval_a;
- nval_a = rect[0];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = nval_b;
- nval_b = rect[1];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = nval_g;
- nval_g = rect[2];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = nval_r;
- nval_r = rect[3];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
- rect += skipx;
+ newrect[0] = val_a + sample * diff_a;
+ newrect[1] = val_b + sample * diff_b;
+ newrect[2] = val_g + sample * diff_g;
+ newrect[3] = val_r + sample * diff_r;
+ newrect += skipx;
}
if (do_float) {
- val_af = nval_af;
- nval_af = rectf[0];
- diff_af = nval_af - val_af;
-
- val_bf = nval_bf;
- nval_bf = rectf[1];
- diff_bf = nval_bf - val_bf;
-
- val_gf = nval_gf;
- nval_gf = rectf[2];
- diff_gf = nval_gf - val_gf;
-
- val_rf = nval_rf;
- nval_rf = rectf[3];
- diff_rf = nval_rf - val_rf;
- rectf += skipx;
+ newrectf[0] = val_af + sample * diff_af;
+ newrectf[1] = val_bf + sample * diff_bf;
+ newrectf[2] = val_gf + sample * diff_gf;
+ newrectf[3] = val_rf + sample * diff_rf;
+ newrectf += skipx;
}
+ sample += add;
}
- if (do_rect) {
- newrect[0] = val_a + sample * diff_a;
- newrect[1] = val_b + sample * diff_b;
- newrect[2] = val_g + sample * diff_g;
- newrect[3] = val_r + sample * diff_r;
- newrect += skipx;
- }
- if (do_float) {
- newrectf[0] = val_af + sample * diff_af;
- newrectf[1] = val_bf + sample * diff_bf;
- newrectf[2] = val_gf + sample * diff_gf;
- newrectf[3] = val_rf + sample * diff_rf;
- newrectf += skipx;
- }
- sample += add;
}
}
@@ -1620,6 +1666,8 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
*/
bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
{
+ BLI_assert_msg(newx > 0 && newy > 0, "Images must be at least 1 on both dimensions!");
+
if (ibuf == NULL) {
return false;
}
@@ -1666,6 +1714,8 @@ struct imbufRGBA {
*/
bool IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
{
+ BLI_assert_msg(newx > 0 && newy > 0, "Images must be at least 1 on both dimensions!");
+
unsigned int *rect, *_newrect, *newrect;
struct imbufRGBA *rectf, *_newrectf, *newrectf;
int x, y;
@@ -1838,6 +1888,8 @@ static void *do_scale_thread(void *data_v)
void IMB_scaleImBuf_threaded(ImBuf *ibuf, unsigned int newx, unsigned int newy)
{
+ BLI_assert_msg(newx > 0 && newy > 0, "Images must be at least 1 on both dimensions!");
+
ScaleTreadInitData init_data = {NULL};
/* prepare initialization data */
diff --git a/source/blender/io/gpencil/gpencil_io.h b/source/blender/io/gpencil/gpencil_io.h
index 24b13479359..fab867b38b3 100644
--- a/source/blender/io/gpencil/gpencil_io.h
+++ b/source/blender/io/gpencil/gpencil_io.h
@@ -27,9 +27,9 @@ extern "C" {
#endif
struct ARegion;
-struct bContext;
struct Object;
struct View3D;
+struct bContext;
typedef struct GpencilIOParams {
bContext *C;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.hh b/source/blender/io/gpencil/intern/gpencil_io_base.hh
index c8d85d08f7b..02758883f19 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh
@@ -37,9 +37,9 @@ struct Object;
struct RegionView3D;
struct Scene;
-struct bGPdata;
struct bGPDlayer;
struct bGPDstroke;
+struct bGPdata;
using blender::Vector;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh
index 0e9271dd2c6..99e8b1ed4fd 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh
@@ -24,10 +24,10 @@
#include "gpencil_io_import_base.hh"
struct GpencilIOParams;
-struct NSVGshape;
struct NSVGpath;
-struct bGPdata;
+struct NSVGshape;
struct bGPDframe;
+struct bGPdata;
#define SVG_IMPORTER_NAME "SVG Import for Grease Pencil"
#define SVG_IMPORTER_VERSION "v1.0"
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 3732de6c0ec..520fc6c1b00 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -35,6 +35,7 @@ extern "C" {
#define MAXTEXTBOX 256 /* used in readfile.c and editfont.c */
struct AnimData;
+struct CurveEval;
struct CurveProfile;
struct EditFont;
struct GHash;
@@ -43,7 +44,6 @@ struct Key;
struct Material;
struct Object;
struct VFont;
-struct CurveEval;
/* These two Lines with # tell makesdna this struct can be excluded. */
#
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 0952c45e81f..380d8ad1249 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -33,8 +33,8 @@ extern "C" {
struct AnimData;
struct Curve;
-struct MDeformVert;
struct Curve;
+struct MDeformVert;
#define GP_DEFAULT_PIX_FACTOR 1.0f
#define GP_DEFAULT_GRID_LINES 4
diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h
index f6dac88051b..1b3dbd148df 100644
--- a/source/blender/makesdna/DNA_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_modifier_defaults.h
@@ -647,7 +647,8 @@
.target = NULL, \
.verts = NULL, \
.falloff = 4.0f, \
- .numverts = 0, \
+ .num_mesh_verts = 0, \
+ .num_bind_verts = 0, \
.numpoly = 0, \
.flags = 0, \
.mat = _DNA_DEFAULT_UNIT_M4, \
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 1c765d19ce2..401b49f2ee8 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -2180,7 +2180,7 @@ typedef struct SDefBind {
typedef struct SDefVert {
SDefBind *binds;
unsigned int numbinds;
- char _pad[4];
+ unsigned int vertex_idx;
} SDefVert;
typedef struct SurfaceDeformModifierData {
@@ -2192,11 +2192,10 @@ typedef struct SurfaceDeformModifierData {
/** Vertex bind data. */
SDefVert *verts;
float falloff;
- unsigned int numverts, numpoly;
+ unsigned int num_mesh_verts, num_bind_verts, numpoly;
int flags;
float mat[4][4];
float strength;
- char _pad[4];
char defgrp_name[64];
} SurfaceDeformModifierData;
@@ -2204,10 +2203,9 @@ typedef struct SurfaceDeformModifierData {
enum {
/* This indicates "do bind on next modifier evaluation" as well as "is bound". */
MOD_SDEF_BIND = (1 << 0),
- MOD_SDEF_INVERT_VGROUP = (1 << 1)
-
- /* MOD_SDEF_USES_LOOPTRI = (1 << 1), */ /* UNUSED */
- /* MOD_SDEF_HAS_CONCAVE = (1 << 2), */ /* UNUSED */
+ MOD_SDEF_INVERT_VGROUP = (1 << 1),
+ /* Only store bind data for nonzero vgroup weights at the time of bind. */
+ MOD_SDEF_SPARSE_BIND = (1 << 2),
};
/* Surface Deform vertex bind modes */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 1f75006bd07..e325a22a74d 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -37,6 +37,8 @@ struct Collection;
struct ID;
struct Image;
struct ListBase;
+struct Material;
+struct Tex;
struct bGPdata;
struct bNodeInstanceHash;
struct bNodeLink;
@@ -44,8 +46,6 @@ struct bNodePreview;
struct bNodeTreeExec;
struct bNodeType;
struct uiBlock;
-struct Tex;
-struct Material;
#define NODE_MAXSTR 64
@@ -1390,6 +1390,11 @@ typedef struct NodeGeometryCurveSubdivide {
uint8_t cuts_type;
} NodeGeometryCurveSubdivide;
+typedef struct NodeGeometryCurveTrim {
+ /* GeometryNodeCurveInterpolateMode. */
+ uint8_t mode;
+} NodeGeometryCurveTrim;
+
typedef struct NodeGeometryCurveToPoints {
/* GeometryNodeCurveResampleMode. */
uint8_t mode;
@@ -1954,6 +1959,11 @@ typedef enum GeometryNodeCurveSampleMode {
GEO_NODE_CURVE_SAMPLE_LENGTH = 1,
} GeometryNodeCurveSampleMode;
+typedef enum GeometryNodeCurveInterpolateMode {
+ GEO_NODE_CURVE_INTERPOLATE_FACTOR = 0,
+ GEO_NODE_CURVE_INTERPOLATE_LENGTH = 1,
+} GeometryNodeCurveInterpolateMode;
+
typedef enum GeometryNodeAttributeTransferMapMode {
GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED = 0,
GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST = 1,
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 7032bc23b2c..5bd9cc7a999 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -279,7 +279,7 @@ typedef struct uiListDyn {
int resize;
int resize_prev;
- /* Allocated custom data. Free'ed together with the uiList (and when re-assigning). */
+ /** Allocated custom data. Freed together with the #uiList (and when re-assigning). */
void *customdata;
/* Filtering data. */
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 1bd4c9233e3..55dc51e0632 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -43,9 +43,9 @@ extern "C" {
struct Ipo;
struct MovieClip;
struct Scene;
+struct SequenceLookup;
struct VFont;
struct bSound;
-struct SequenceLookup;
/* strlens; 256= FILE_MAXFILE, 768= FILE_MAXDIR */
diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h
index 735be0c10bf..d363e40e4f0 100644
--- a/source/blender/makesdna/intern/dna_rename_defs.h
+++ b/source/blender/makesdna/intern/dna_rename_defs.h
@@ -136,4 +136,5 @@ DNA_STRUCT_RENAME_ELEM(wmWindow, global_area_map, global_areas)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, line_types, edge_types)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_flags, mask_switches)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_mask_bits)
+DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numverts, num_bind_verts)
DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits)
diff --git a/source/blender/makesrna/intern/rna_asset.c b/source/blender/makesrna/intern/rna_asset.c
index 497f4f37ea3..0020d90ba1a 100644
--- a/source/blender/makesrna/intern/rna_asset.c
+++ b/source/blender/makesrna/intern/rna_asset.c
@@ -137,7 +137,7 @@ static void rna_AssetHandle_get_full_library_path(
bContext *C,
FileDirEntry *asset_file,
AssetLibraryReference *library,
- char r_result[FILE_MAX_LIBEXTRA])
+ char r_result[/*FILE_MAX_LIBEXTRA*/])
{
AssetHandle asset = {.file_data = asset_file};
ED_asset_handle_get_full_library_path(C, library, &asset, r_result);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index e64eaf8c363..5fddb0f18a5 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -6884,6 +6884,15 @@ static void rna_def_modifier_surfacedeform(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "use_sparse_bind", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SDEF_SPARSE_BIND);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(
+ prop,
+ "Sparse Bind",
+ "Only record binding data for vertices matching the vertex group at the time of bind");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -100, 100);
RNA_def_property_ui_range(prop, -100, 100, 10, 2);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 198ee107231..ce2c777b782 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -10065,6 +10065,32 @@ static void def_geo_curve_to_points(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
+static void def_geo_curve_trim(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem mode_items[] = {
+ {GEO_NODE_CURVE_INTERPOLATE_FACTOR,
+ "FACTOR",
+ 0,
+ "Factor",
+ "Find the endpoint positions using a factor of each spline's length"},
+ {GEO_NODE_CURVE_INTERPOLATE_LENGTH,
+ "LENGTH",
+ 0,
+ "Length",
+ "Find the endpoint positions using a length from the start of each spline"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ RNA_def_struct_sdna_from(srna, "NodeGeometryCurveTrim", "storage");
+
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "How to find endpoint positions for the trimmed spline");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
static void def_geo_attribute_transfer(StructRNA *srna)
{
static EnumPropertyItem mapping_items[] = {
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index e110459eeea..ed681291e29 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1997,16 +1997,25 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values)
}
}
+static bool check_object_vgroup_support_and_warn(const Object *ob,
+ const char *op_name,
+ ReportList *reports)
+{
+ if (!BKE_object_supports_vertex_groups(ob)) {
+ const char *ob_type_name = "Unknown";
+ RNA_enum_name_from_value(rna_enum_object_type_items, ob->type, &ob_type_name);
+ BKE_reportf(reports, RPT_ERROR, "%s is not supported for '%s' objects", op_name, ob_type_name);
+ return false;
+ }
+ return true;
+}
+
static bDeformGroup *rna_Object_vgroup_new(Object *ob,
Main *bmain,
ReportList *reports,
const char *name)
{
- if (!OB_TYPE_SUPPORT_VGROUP(ob->type)) {
- const char *ob_type_name = "Unknown";
- RNA_enum_name_from_value(rna_enum_object_type_items, ob->type, &ob_type_name);
- BKE_reportf(
- reports, RPT_ERROR, "VertexGroups.new(): is not supported for '%s' objects", ob_type_name);
+ if (!check_object_vgroup_support_and_warn(ob, "VertexGroups.new()", reports)) {
return NULL;
}
@@ -2023,6 +2032,10 @@ static void rna_Object_vgroup_remove(Object *ob,
ReportList *reports,
PointerRNA *defgroup_ptr)
{
+ if (!check_object_vgroup_support_and_warn(ob, "VertexGroups.remove()", reports)) {
+ return;
+ }
+
bDeformGroup *defgroup = defgroup_ptr->data;
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
@@ -2042,8 +2055,12 @@ static void rna_Object_vgroup_remove(Object *ob,
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
-static void rna_Object_vgroup_clear(Object *ob, Main *bmain)
+static void rna_Object_vgroup_clear(Object *ob, Main *bmain, ReportList *reports)
{
+ if (!check_object_vgroup_support_and_warn(ob, "VertexGroups.clear()", reports)) {
+ return;
+ }
+
BKE_object_defgroup_remove_all(ob);
DEG_relations_tag_update(bmain);
@@ -2777,7 +2794,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "clear", "rna_Object_vgroup_clear");
- RNA_def_function_flag(func, FUNC_USE_MAIN);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Delete all vertex groups from object");
}
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 8aab0c079a3..057f49c0319 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -30,6 +30,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "SEQ_edit.h"
+
#include "rna_internal.h"
#ifdef RNA_RUNTIME
@@ -99,6 +101,24 @@ static void rna_Sequences_move_strip_to_meta(
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
}
+static Sequence *rna_Sequence_split(
+ ID *id, Sequence *seq, Main *bmain, int frame, int split_method)
+{
+ Scene *scene = (Scene *)id;
+ Editing *ed = SEQ_editing_get(scene, false);
+ ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
+
+ Sequence *r_seq = SEQ_edit_strip_split(bmain, scene, seqbase, seq, frame, split_method);
+
+ /* Update depsgraph. */
+ DEG_relations_tag_update(bmain);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
+
+ WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
+
+ return r_seq;
+}
+
static Sequence *rna_Sequences_new_clip(ID *id,
ListBase *seqbase,
Main *bmain,
@@ -635,6 +655,12 @@ void RNA_api_sequence_strip(StructRNA *srna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem seq_split_method_items[] = {
+ {SEQ_SPLIT_SOFT, "SOFT", 0, "Soft", ""},
+ {SEQ_SPLIT_HARD, "HARD", 0, "Hard", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
func = RNA_def_function(srna, "update", "rna_Sequence_update_rnafunc");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
RNA_def_function_ui_description(func, "Update the strip dimensions");
@@ -676,6 +702,18 @@ void RNA_api_sequence_strip(StructRNA *srna)
"Invalidate cached images for strip and all dependent strips");
parm = RNA_def_enum(func, "type", seq_cahce_type_items, 0, "Type", "Cache Type");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+
+ func = RNA_def_function(srna, "split", "rna_Sequence_split");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ RNA_def_function_ui_description(func, "Split Sequence");
+ parm = RNA_def_int(
+ func, "frame", 0, INT_MIN, INT_MAX, "", "Frame where to split the strip", INT_MIN, INT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_enum(func, "split_method", seq_split_method_items, 0, "", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ /* Retirn type. */
+ parm = RNA_def_pointer(func, "sequence", "Sequence", "", "Right side Sequence");
+ RNA_def_function_return(func, parm);
}
void RNA_api_sequence_elements(BlenderRNA *brna, PropertyRNA *cprop)
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 0019f315bbe..f2d2b190d87 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2699,7 +2699,7 @@ static const EnumPropertyItem *rna_FileBrowser_FileSelectEntry_id_type_itemf(
{
const FileDirEntry *entry = ptr->data;
if (entry->blentype == 0) {
- const static EnumPropertyItem none_items[] = {
+ static const EnumPropertyItem none_items[] = {
{0, "NONE", 0, "None", ""},
};
return none_items;
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index fd1c0b7951a..d29a90a1886 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1100,7 +1100,7 @@ int rna_show_statusbar_vram_editable(struct PointerRNA *UNUSED(ptr), const char
static size_t max_memory_in_megabytes(void)
{
/* Maximum addressable bytes on this platform. */
- const size_t limit_bytes = (((size_t)1) << ((sizeof(size_t[8])) - 1));
+ const size_t limit_bytes = (((size_t)1) << (sizeof(size_t[8]) - 1));
/* Convert it to megabytes and return. */
return (limit_bytes >> 20);
}
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index dd011a293ee..ec6de8f8387 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -94,6 +94,11 @@ typedef struct SDefBindCalcData {
float imat[4][4];
const float falloff;
int success;
+ /** Vertex group lookup data. */
+ const MDeformVert *const dvert;
+ int const defgrp_index;
+ bool const invert_vgroup;
+ bool const sparse_bind;
} SDefBindCalcData;
/**
@@ -218,7 +223,7 @@ static void freeData(ModifierData *md)
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
if (smd->verts) {
- for (int i = 0; i < smd->numverts; i++) {
+ for (int i = 0; i < smd->num_bind_verts; i++) {
if (smd->verts[i].binds) {
for (int j = 0; j < smd->verts[i].numbinds; j++) {
MEM_SAFE_FREE(smd->verts[i].binds[j].vert_inds);
@@ -243,7 +248,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
if (smd->verts) {
tsmd->verts = MEM_dupallocN(smd->verts);
- for (int i = 0; i < smd->numverts; i++) {
+ for (int i = 0; i < smd->num_bind_verts; i++) {
if (smd->verts[i].binds) {
tsmd->verts[i].binds = MEM_dupallocN(smd->verts[i].binds);
@@ -963,12 +968,32 @@ static void bindVert(void *__restrict userdata,
SDefBindPoly *bpoly;
SDefBind *sdbind;
+ sdvert->vertex_idx = index;
+
if (data->success != MOD_SDEF_BIND_RESULT_SUCCESS) {
sdvert->binds = NULL;
sdvert->numbinds = 0;
return;
}
+ if (data->sparse_bind) {
+ float weight = 0.0f;
+
+ if (data->dvert && data->defgrp_index != -1) {
+ weight = BKE_defvert_find_weight(&data->dvert[index], data->defgrp_index);
+ }
+
+ if (data->invert_vgroup) {
+ weight = 1.0f - weight;
+ }
+
+ if (weight <= 0) {
+ sdvert->binds = NULL;
+ sdvert->numbinds = 0;
+ return;
+ }
+ }
+
copy_v3_v3(point_co, data->vertexCos[index]);
bwdata = computeBindWeights(data, point_co);
@@ -1135,6 +1160,21 @@ static void bindVert(void *__restrict userdata,
freeBindData(bwdata);
}
+/* Remove vertices without bind data from the bind array. */
+static void compactSparseBinds(SurfaceDeformModifierData *smd)
+{
+ smd->num_bind_verts = 0;
+
+ for (uint i = 0; i < smd->num_mesh_verts; i++) {
+ if (smd->verts[i].numbinds > 0) {
+ smd->verts[smd->num_bind_verts++] = smd->verts[i];
+ }
+ }
+
+ smd->verts = MEM_reallocN_id(
+ smd->verts, sizeof(*smd->verts) * smd->num_bind_verts, "SDefBindVerts (sparse)");
+}
+
static bool surfacedeformBind(Object *ob,
SurfaceDeformModifierData *smd_orig,
SurfaceDeformModifierData *smd_eval,
@@ -1142,7 +1182,8 @@ static bool surfacedeformBind(Object *ob,
uint numverts,
uint tnumpoly,
uint tnumverts,
- Mesh *target)
+ Mesh *target,
+ Mesh *mesh)
{
BVHTreeFromMesh treeData = {NULL};
const MVert *mvert = target->mvert;
@@ -1205,9 +1246,15 @@ static bool surfacedeformBind(Object *ob,
return false;
}
- smd_orig->numverts = numverts;
+ smd_orig->num_mesh_verts = numverts;
smd_orig->numpoly = tnumpoly;
+ int defgrp_index;
+ MDeformVert *dvert;
+ MOD_get_vgroup(ob, mesh, smd_orig->defgrp_name, &dvert, &defgrp_index);
+ const bool invert_vgroup = (smd_orig->flags & MOD_SDEF_INVERT_VGROUP) != 0;
+ const bool sparse_bind = (smd_orig->flags & MOD_SDEF_SPARSE_BIND) != 0;
+
SDefBindCalcData data = {
.treeData = &treeData,
.vert_edges = vert_edges,
@@ -1221,6 +1268,10 @@ static bool surfacedeformBind(Object *ob,
.vertexCos = vertexCos,
.falloff = smd_orig->falloff,
.success = MOD_SDEF_BIND_RESULT_SUCCESS,
+ .dvert = dvert,
+ .defgrp_index = defgrp_index,
+ .invert_vgroup = invert_vgroup,
+ .sparse_bind = sparse_bind,
};
if (data.targetCos == NULL) {
@@ -1242,6 +1293,13 @@ static bool surfacedeformBind(Object *ob,
MEM_freeN(data.targetCos);
+ if (sparse_bind) {
+ compactSparseBinds(smd_orig);
+ }
+ else {
+ smd_orig->num_bind_verts = numverts;
+ }
+
if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeData((ModifierData *)smd_orig);
@@ -1267,6 +1325,11 @@ static bool surfacedeformBind(Object *ob,
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains invalid polygons");
freeData((ModifierData *)smd_orig);
}
+ else if (smd_orig->num_bind_verts == 0 || !smd_orig->verts) {
+ data.success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "No vertices were bound");
+ freeData((ModifierData *)smd_orig);
+ }
freeAdjacencyMap(vert_edges, adj_array, edge_polys);
free_bvhtree_from_mesh(&treeData);
@@ -1281,14 +1344,15 @@ static void deformVert(void *__restrict userdata,
const SDefDeformData *const data = (SDefDeformData *)userdata;
const SDefBind *sdbind = data->bind_verts[index].binds;
const int num_binds = data->bind_verts[index].numbinds;
- float *const vertexCos = data->vertexCos[index];
+ const unsigned int vertex_idx = data->bind_verts[index].vertex_idx;
+ float *const vertexCos = data->vertexCos[vertex_idx];
float norm[3], temp[3], offset[3];
/* Retrieve the value of the weight vertex group if specified. */
float weight = 1.0f;
if (data->dvert && data->defgrp_index != -1) {
- weight = BKE_defvert_find_weight(&data->dvert[index], data->defgrp_index);
+ weight = BKE_defvert_find_weight(&data->dvert[vertex_idx], data->defgrp_index);
if (data->invert_vgroup) {
weight = 1.0f - weight;
@@ -1423,7 +1487,8 @@ static void surfacedeformModifier_do(ModifierData *md,
/* Avoid converting edit-mesh data, binding is an exception. */
BKE_mesh_wrapper_ensure_mdata(target);
- if (!surfacedeformBind(ob, smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
+ if (!surfacedeformBind(
+ ob, smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target, mesh)) {
smd->flags &= ~MOD_SDEF_BIND;
}
/* Early abort, this is binding 'call', no need to perform whole evaluation. */
@@ -1431,8 +1496,9 @@ static void surfacedeformModifier_do(ModifierData *md,
}
/* Poly count checks */
- if (smd->numverts != numverts) {
- BKE_modifier_set_error(ob, md, "Vertices changed from %u to %u", smd->numverts, numverts);
+ if (smd->num_mesh_verts != numverts) {
+ BKE_modifier_set_error(
+ ob, md, "Vertices changed from %u to %u", smd->num_mesh_verts, numverts);
return;
}
if (smd->numpoly != tnumpoly) {
@@ -1468,8 +1534,8 @@ static void surfacedeformModifier_do(ModifierData *md,
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numverts > 10000);
- BLI_task_parallel_range(0, numverts, &data, deformVert, &settings);
+ settings.use_threading = (smd->num_bind_verts > 10000);
+ BLI_task_parallel_range(0, smd->num_bind_verts, &data, deformVert, &settings);
MEM_freeN(data.targetCos);
}
@@ -1554,6 +1620,11 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetEnabled(col, !is_bound);
+ uiLayoutSetActive(col, !is_bound && RNA_string_length(ptr, "vertex_group") != 0);
+ uiItemR(col, ptr, "use_sparse_bind", 0, NULL, ICON_NONE);
+
uiItemS(layout);
col = uiLayoutColumn(layout, false);
@@ -1576,10 +1647,10 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
{
const SurfaceDeformModifierData *smd = (const SurfaceDeformModifierData *)md;
- BLO_write_struct_array(writer, SDefVert, smd->numverts, smd->verts);
+ BLO_write_struct_array(writer, SDefVert, smd->num_bind_verts, smd->verts);
if (smd->verts) {
- for (int i = 0; i < smd->numverts; i++) {
+ for (int i = 0; i < smd->num_bind_verts; i++) {
BLO_write_struct_array(writer, SDefBind, smd->verts[i].numbinds, smd->verts[i].binds);
if (smd->verts[i].binds) {
@@ -1607,7 +1678,7 @@ static void blendRead(BlendDataReader *reader, ModifierData *md)
BLO_read_data_address(reader, &smd->verts);
if (smd->verts) {
- for (int i = 0; i < smd->numverts; i++) {
+ for (int i = 0; i < smd->num_bind_verts; i++) {
BLO_read_data_address(reader, &smd->verts[i].binds);
if (smd->verts[i].binds) {
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index e9ce823967e..974cbf95af0 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -179,6 +179,7 @@ set(SRC
geometry/nodes/node_geo_curve_subdivide.cc
geometry/nodes/node_geo_curve_to_mesh.cc
geometry/nodes/node_geo_curve_to_points.cc
+ geometry/nodes/node_geo_curve_trim.cc
geometry/nodes/node_geo_delete_geometry.cc
geometry/nodes/node_geo_edge_split.cc
geometry/nodes/node_geo_input_material.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 73e711eb401..b8d8f120e91 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -66,6 +66,7 @@ void register_node_type_geo_curve_reverse(void);
void register_node_type_geo_curve_subdivide(void);
void register_node_type_geo_curve_to_mesh(void);
void register_node_type_geo_curve_to_points(void);
+void register_node_type_geo_curve_trim(void);
void register_node_type_geo_delete_geometry(void);
void register_node_type_geo_edge_split(void);
void register_node_type_geo_input_material(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index c24763baa1e..dd158cdaf75 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -303,6 +303,7 @@ DefNode(GeometryNode, GEO_NODE_CURVE_RESAMPLE, def_geo_curve_resample, "CURVE_RE
DefNode(GeometryNode, GEO_NODE_CURVE_SAMPLE, def_geo_curve_sample, "CURVE_SAMPLE", CurveSample, "Curve Sample", "")
DefNode(GeometryNode, GEO_NODE_CURVE_SUBDIVIDE, def_geo_curve_subdivide, "CURVE_SUBDIVIDE", CurveSubdivide, "Curve Subdivide", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "")
+DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Curve Trim", "")
DefNode(GeometryNode, GEO_NODE_CURVE_REVERSE, 0, "CURVE_REVERSE", CurveReverse, "Curve Reverse", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "")
DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "")
diff --git a/source/blender/nodes/composite/nodes/node_composite_antialiasing.c b/source/blender/nodes/composite/nodes/node_composite_antialiasing.c
index 7437496d878..fa276e9a794 100644
--- a/source/blender/nodes/composite/nodes/node_composite_antialiasing.c
+++ b/source/blender/nodes/composite/nodes/node_composite_antialiasing.c
@@ -42,9 +42,9 @@ static void node_composit_init_antialiasing(bNodeTree *UNUSED(ntree), bNode *nod
{
NodeAntiAliasingData *data = MEM_callocN(sizeof(NodeAntiAliasingData), "node antialiasing data");
- data->threshold = 1.0f;
- data->contrast_limit = 0.2f;
- data->corner_rounding = 0.25f;
+ data->threshold = CMP_DEFAULT_SMAA_THRESHOLD;
+ data->contrast_limit = CMP_DEFAULT_SMAA_CONTRAST_LIMIT;
+ data->corner_rounding = CMP_DEFAULT_SMAA_CORNER_ROUNDING;
node->storage = data;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
new file mode 100644
index 00000000000..f7aecf72303
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -0,0 +1,408 @@
+/*
+ * 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 "BKE_spline.hh"
+#include "BLI_task.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+using blender::attribute_math::mix2;
+
+static bNodeSocketTemplate geo_node_curve_trim_in[] = {
+ {SOCK_GEOMETRY, N_("Curve")},
+ {SOCK_FLOAT, N_("Start"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("End"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("Start"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10000.0f, PROP_DISTANCE},
+ {SOCK_FLOAT, N_("End"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 10000.0f, PROP_DISTANCE},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_curve_trim_out[] = {
+ {SOCK_GEOMETRY, N_("Curve")},
+ {-1, ""},
+};
+
+static void geo_node_curve_trim_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+}
+
+static void geo_node_curve_trim_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeGeometryCurveTrim *data = (NodeGeometryCurveTrim *)MEM_callocN(sizeof(NodeGeometryCurveTrim),
+ __func__);
+
+ data->mode = GEO_NODE_CURVE_INTERPOLATE_FACTOR;
+ node->storage = data;
+}
+
+static void geo_node_curve_trim_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeGeometryCurveTrim &node_storage = *(NodeGeometryCurveTrim *)node->storage;
+ const GeometryNodeCurveInterpolateMode mode = (GeometryNodeCurveInterpolateMode)
+ node_storage.mode;
+
+ bNodeSocket *start_fac = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *end_fac = start_fac->next;
+ bNodeSocket *start_len = end_fac->next;
+ bNodeSocket *end_len = start_len->next;
+
+ nodeSetSocketAvailability(start_fac, mode == GEO_NODE_CURVE_INTERPOLATE_FACTOR);
+ nodeSetSocketAvailability(end_fac, mode == GEO_NODE_CURVE_INTERPOLATE_FACTOR);
+ nodeSetSocketAvailability(start_len, mode == GEO_NODE_CURVE_INTERPOLATE_LENGTH);
+ nodeSetSocketAvailability(end_len, mode == GEO_NODE_CURVE_INTERPOLATE_LENGTH);
+}
+
+namespace blender::nodes {
+
+struct TrimLocation {
+ /* Control point index at the start side of the trim location. */
+ int left_index;
+ /* Control point intex at the end of the trim location's segment. */
+ int right_index;
+ /* The factor between the left and right indices. */
+ float factor;
+};
+
+template<typename T>
+static void shift_slice_to_start(MutableSpan<T> data, const int start_index, const int size)
+{
+ BLI_assert(start_index + size - 1 <= data.size());
+ memmove(data.data(), &data[start_index], sizeof(T) * size);
+}
+
+/* Shift slice to start of span and modifies start and end data. */
+template<typename T>
+static void linear_trim_data(const TrimLocation &start,
+ const TrimLocation &end,
+ MutableSpan<T> data)
+{
+ const int size = end.right_index - start.left_index + 1;
+
+ if (start.left_index > 0) {
+ shift_slice_to_start<T>(data, start.left_index, size);
+ }
+
+ const T start_data = mix2<T>(start.factor, data.first(), data[1]);
+ const T end_data = mix2<T>(end.factor, data[size - 2], data[size - 1]);
+
+ data.first() = start_data;
+ data[size - 1] = end_data;
+}
+
+/* Identical operation as #linear_trim_data, but opy data to a new MutableSpan rather than
+ * modifying the original data. */
+template<typename T>
+static void linear_trim_to_output_data(const TrimLocation &start,
+ const TrimLocation &end,
+ Span<T> src,
+ MutableSpan<T> dst)
+{
+ const int size = end.right_index - start.left_index + 1;
+
+ const T start_data = mix2<T>(start.factor, src[start.left_index], src[start.right_index]);
+ const T end_data = mix2<T>(end.factor, src[end.left_index], src[end.right_index]);
+
+ dst.copy_from(src.slice(start.left_index, size));
+ dst.first() = start_data;
+ dst.last() = end_data;
+}
+
+/* Look up the control points to the left and right of factor, and get the factor between them. */
+static TrimLocation lookup_control_point_position(const Spline::LookupResult &lookup,
+ Span<int> control_point_offsets)
+{
+ const int *left_offset = std::lower_bound(
+ control_point_offsets.begin(), control_point_offsets.end(), lookup.evaluated_index);
+ const int index = left_offset - control_point_offsets.begin();
+ const int left = control_point_offsets[index] > lookup.evaluated_index ? index - 1 : index;
+ const int right = left + 1;
+
+ const float factor = std::clamp(
+ (lookup.evaluated_index + lookup.factor - control_point_offsets[left]) /
+ (control_point_offsets[right] - control_point_offsets[left]),
+ 0.0f,
+ 1.0f);
+
+ return {left, right, factor};
+}
+
+static void trim_poly_spline(Spline &spline,
+ const Spline::LookupResult &start_lookup,
+ const Spline::LookupResult &end_lookup)
+{
+ /* Poly splines have a 1 to 1 mapping between control points and evaluated points. */
+ const TrimLocation start = {
+ start_lookup.evaluated_index, start_lookup.next_evaluated_index, start_lookup.factor};
+ const TrimLocation end = {
+ end_lookup.evaluated_index, end_lookup.next_evaluated_index, end_lookup.factor};
+
+ const int size = end.right_index - start.left_index + 1;
+
+ linear_trim_data<float3>(start, end, spline.positions());
+ linear_trim_data<float>(start, end, spline.radii());
+ linear_trim_data<float>(start, end, spline.tilts());
+
+ spline.attributes.foreach_attribute(
+ [&](StringRefNull name, const AttributeMetaData &UNUSED(meta_data)) {
+ std::optional<GMutableSpan> src = spline.attributes.get_for_write(name);
+ BLI_assert(src);
+ attribute_math::convert_to_static_type(src->type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ linear_trim_data<T>(start, end, src->typed<T>());
+ });
+ return true;
+ },
+ ATTR_DOMAIN_POINT);
+
+ spline.resize(size);
+}
+
+/**
+ * Trim NURB splines by converting to a poly spline.
+ */
+static PolySpline trim_nurbs_spline(const Spline &spline,
+ const Spline::LookupResult &start_lookup,
+ const Spline::LookupResult &end_lookup)
+{
+ /* Since this outputs a poly spline, the evaluated indices are the control point indices. */
+ const TrimLocation start = {
+ start_lookup.evaluated_index, start_lookup.next_evaluated_index, start_lookup.factor};
+ const TrimLocation end = {
+ end_lookup.evaluated_index, end_lookup.next_evaluated_index, end_lookup.factor};
+
+ const int size = end.right_index - start.left_index + 1;
+
+ /* Create poly spline and copy trimmed data to it. */
+ PolySpline new_spline;
+ new_spline.resize(size);
+
+ /* Copy generic attribute data. */
+ spline.attributes.foreach_attribute(
+ [&](StringRefNull name, const AttributeMetaData &meta_data) {
+ std::optional<GSpan> src = spline.attributes.get_for_read(name);
+ BLI_assert(src);
+ if (!new_spline.attributes.create(name, meta_data.data_type)) {
+ BLI_assert_unreachable();
+ return false;
+ }
+ std::optional<GMutableSpan> dst = new_spline.attributes.get_for_write(name);
+ BLI_assert(dst);
+
+ attribute_math::convert_to_static_type(src->type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ GVArray_Typed<T> eval_data = spline.interpolate_to_evaluated<T>(src->typed<T>());
+ linear_trim_to_output_data<T>(
+ start, end, eval_data->get_internal_span(), dst->typed<T>());
+ });
+ return true;
+ },
+ ATTR_DOMAIN_POINT);
+
+ linear_trim_to_output_data<float3>(
+ start, end, spline.evaluated_positions(), new_spline.positions());
+
+ GVArray_Typed<float> evaluated_radii = spline.interpolate_to_evaluated(spline.radii());
+ linear_trim_to_output_data<float>(
+ start, end, evaluated_radii->get_internal_span(), new_spline.radii());
+
+ GVArray_Typed<float> evaluated_tilts = spline.interpolate_to_evaluated(spline.tilts());
+ linear_trim_to_output_data<float>(
+ start, end, evaluated_tilts->get_internal_span(), new_spline.tilts());
+
+ return new_spline;
+}
+
+/**
+ * Trim Bezier splines by adjusting the first and last handles
+ * and control points to maintain the original shape.
+ */
+static void trim_bezier_spline(Spline &spline,
+ const Spline::LookupResult &start_lookup,
+ const Spline::LookupResult &end_lookup)
+{
+ BezierSpline &bezier_spline = static_cast<BezierSpline &>(spline);
+ Span<int> control_offsets = bezier_spline.control_point_offsets();
+
+ const TrimLocation start = lookup_control_point_position(start_lookup, control_offsets);
+ TrimLocation end = lookup_control_point_position(end_lookup, control_offsets);
+
+ /* The number of control points in the resulting spline. */
+ const int size = end.right_index - start.left_index + 1;
+
+ /* Trim the spline attributes. Done before end.factor recalculation as it needs
+ * the original end.factor value. */
+ linear_trim_data<float>(start, end, bezier_spline.radii());
+ linear_trim_data<float>(start, end, bezier_spline.tilts());
+ spline.attributes.foreach_attribute(
+ [&](StringRefNull name, const AttributeMetaData &UNUSED(meta_data)) {
+ std::optional<GMutableSpan> src = spline.attributes.get_for_write(name);
+ BLI_assert(src);
+ attribute_math::convert_to_static_type(src->type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ linear_trim_data<T>(start, end, src->typed<T>());
+ });
+ return true;
+ },
+ ATTR_DOMAIN_POINT);
+
+ /* Recalculate end.factor if the size is two, because the adjustment in the
+ * position of the control point of the spline to the left of the new end point will change the
+ * factor between them. */
+ if (size == 2) {
+ if (start_lookup.factor == 1.0f) {
+ end.factor = 0.0f;
+ }
+ else {
+ end.factor = (end_lookup.evaluated_index + end_lookup.factor -
+ (start_lookup.evaluated_index + start_lookup.factor)) /
+ (control_offsets[end.right_index] -
+ (start_lookup.evaluated_index + start_lookup.factor));
+ end.factor = std::clamp(end.factor, 0.0f, 1.0f);
+ }
+ }
+
+ BezierSpline::InsertResult start_point = bezier_spline.calculate_segment_insertion(
+ start.left_index, start.right_index, start.factor);
+
+ /* Update the start control point parameters so they are used calculating the new end point. */
+ bezier_spline.positions()[start.left_index] = start_point.position;
+ bezier_spline.handle_positions_right()[start.left_index] = start_point.right_handle;
+ bezier_spline.handle_positions_left()[start.right_index] = start_point.handle_next;
+
+ const BezierSpline::InsertResult end_point = bezier_spline.calculate_segment_insertion(
+ end.left_index, end.right_index, end.factor);
+
+ /* If size is two, then the start point right handle needs to change to reflect the end point
+ * previous handle update. */
+ if (size == 2) {
+ start_point.right_handle = end_point.handle_prev;
+ }
+
+ /* Shift control point position data to start at beginning of array. */
+ if (start.left_index > 0) {
+ shift_slice_to_start(bezier_spline.positions(), start.left_index, size);
+ shift_slice_to_start(bezier_spline.handle_positions_left(), start.left_index, size);
+ shift_slice_to_start(bezier_spline.handle_positions_right(), start.left_index, size);
+ }
+
+ bezier_spline.positions().first() = start_point.position;
+ bezier_spline.positions()[size - 1] = end_point.position;
+
+ bezier_spline.handle_positions_left().first() = start_point.left_handle;
+ bezier_spline.handle_positions_left()[size - 1] = end_point.left_handle;
+
+ bezier_spline.handle_positions_right().first() = start_point.right_handle;
+ bezier_spline.handle_positions_right()[size - 1] = end_point.right_handle;
+
+ /* If there is at least one control point between the endpoints, update the control
+ * point handle to the right of the start point and to the left of the end point. */
+ if (size > 2) {
+ bezier_spline.handle_positions_left()[start.right_index - start.left_index] =
+ start_point.handle_next;
+ bezier_spline.handle_positions_right()[end.left_index - start.left_index] =
+ end_point.handle_prev;
+ }
+
+ bezier_spline.resize(size);
+}
+
+static void geo_node_curve_trim_exec(GeoNodeExecParams params)
+{
+ const NodeGeometryCurveTrim &node_storage = *(NodeGeometryCurveTrim *)params.node().storage;
+ const GeometryNodeCurveInterpolateMode mode = (GeometryNodeCurveInterpolateMode)
+ node_storage.mode;
+
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
+ geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ if (!geometry_set.has_curve()) {
+ params.set_output("Curve", std::move(geometry_set));
+ return;
+ }
+
+ CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
+ CurveEval &curve = *curve_component.get_for_write();
+ MutableSpan<SplinePtr> splines = curve.splines();
+
+ const float start = mode == GEO_NODE_CURVE_INTERPOLATE_FACTOR ?
+ params.extract_input<float>("Start") :
+ params.extract_input<float>("Start_001");
+ const float end = mode == GEO_NODE_CURVE_INTERPOLATE_FACTOR ?
+ params.extract_input<float>("End") :
+ params.extract_input<float>("End_001");
+
+ threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
+ for (const int i : range) {
+ Spline &spline = *splines[i];
+
+ /* Currently this node doesn't support cyclic splines, it could in the future though. */
+ if (spline.is_cyclic()) {
+ continue;
+ }
+
+ /* Return a spline with one point instead of implicitly
+ * reversing the sline or switching the parameters. */
+ if (end < start) {
+ spline.resize(1);
+ continue;
+ }
+
+ const Spline::LookupResult start_lookup =
+ (mode == GEO_NODE_CURVE_INTERPOLATE_LENGTH) ?
+ spline.lookup_evaluated_length(std::clamp(start, 0.0f, spline.length())) :
+ spline.lookup_evaluated_factor(std::clamp(start, 0.0f, 1.0f));
+ const Spline::LookupResult end_lookup =
+ (mode == GEO_NODE_CURVE_INTERPOLATE_LENGTH) ?
+ spline.lookup_evaluated_length(std::clamp(end, 0.0f, spline.length())) :
+ spline.lookup_evaluated_factor(std::clamp(end, 0.0f, 1.0f));
+
+ switch (spline.type()) {
+ case Spline::Type::Bezier:
+ trim_bezier_spline(spline, start_lookup, end_lookup);
+ break;
+ case Spline::Type::Poly:
+ trim_poly_spline(spline, start_lookup, end_lookup);
+ break;
+ case Spline::Type::NURBS:
+ splines[i] = std::make_unique<PolySpline>(
+ trim_nurbs_spline(spline, start_lookup, end_lookup));
+ break;
+ }
+ splines[i]->mark_cache_invalid();
+ }
+ });
+
+ params.set_output("Curve", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_curve_trim()
+{
+ static bNodeType ntype;
+ geo_node_type_base(&ntype, GEO_NODE_CURVE_TRIM, "Curve Trim", NODE_CLASS_GEOMETRY, 0);
+ node_type_socket_templates(&ntype, geo_node_curve_trim_in, geo_node_curve_trim_out);
+ ntype.geometry_node_execute = blender::nodes::geo_node_curve_trim_exec;
+ ntype.draw_buttons = geo_node_curve_trim_layout;
+ node_type_storage(
+ &ntype, "NodeGeometryCurveTrim", node_free_standard_storage, node_copy_standard_storage);
+ node_type_init(&ntype, geo_node_curve_trim_init);
+ node_type_update(&ntype, geo_node_curve_trim_update);
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 90f54c50a6d..84d804f8bdf 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -20,8 +20,8 @@
#pragma once
-struct AnimationEvalContext;
struct ARegionType;
+struct AnimationEvalContext;
struct ChannelDriver; /* DNA_anim_types.h */
struct ID; /* DNA_ID.h */
struct ListBase; /* DNA_listBase.h */
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index 3d5aabcfda9..24887b24eb6 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -608,7 +608,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
/* keep switch in same order as above */
switch (slot->slot_type) {
case BMO_OP_SLOT_BOOL:
- item = PyBool_FromLong((BMO_SLOT_AS_BOOL(slot)));
+ item = PyBool_FromLong(BMO_SLOT_AS_BOOL(slot));
break;
case BMO_OP_SLOT_INT:
item = PyLong_FromLong(BMO_SLOT_AS_INT(slot));
diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c
index c1e28182c53..1c3334f1adc 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.c
+++ b/source/blender/python/bmesh/bmesh_py_utils.c
@@ -189,7 +189,7 @@ static PyObject *bpy_bm_utils_vert_dissolve(PyObject *UNUSED(self), PyObject *ar
bm = py_vert->bm;
- return PyBool_FromLong((BM_vert_dissolve(bm, py_vert->v)));
+ return PyBool_FromLong(BM_vert_dissolve(bm, py_vert->v));
}
PyDoc_STRVAR(bpy_bm_utils_vert_splice_doc,
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index 8dc5a6c629c..d66643c5d61 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -283,7 +283,7 @@ void BPY_app_handlers_reset(const short do_all)
for (i = PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
- if ((PyFunction_Check((item = PyList_GET_ITEM(ls, i)))) &&
+ if (PyFunction_Check((item = PyList_GET_ITEM(ls, i))) &&
(dict_ptr = _PyObject_GetDictPtr(item)) && (*dict_ptr) &&
(PyDict_GetItem(*dict_ptr, perm_id_str) != NULL)) {
/* keep */
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 14e25e02d84..f332d547965 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -1779,7 +1779,7 @@ static const EnumPropertyItem *enum_items_from_py(PyObject *seq_fast,
item = seq_fast_items[i];
- if ((PyTuple_CheckExact(item)) && (item_size = PyTuple_GET_SIZE(item)) &&
+ if (PyTuple_CheckExact(item) && (item_size = PyTuple_GET_SIZE(item)) &&
(item_size >= 3 && item_size <= 5) &&
(tmp.identifier = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
(tmp.name = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index dc98e3313c9..8b8130f3cc2 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -2998,7 +2998,7 @@ static int Matrix_translation_set(MatrixObject *self, PyObject *value, void *UNU
return -1;
}
- if ((mathutils_array_parse(tvec, 3, 3, value, "Matrix.translation")) == -1) {
+ if (mathutils_array_parse(tvec, 3, 3, value, "Matrix.translation") == -1) {
return -1;
}
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 88b3bddddf6..a2dfaf501d6 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -1505,6 +1505,9 @@ static PyObject *list_of_lists_from_arrays(const int *array,
PyObject *ret, *sublist;
int i, j, sublist_len, sublist_start, val;
+ if (array == NULL) {
+ return PyList_New(0);
+ }
ret = PyList_New(toplevel_len);
for (i = 0; i < toplevel_len; i++) {
sublist_len = len_table[i];
@@ -1521,7 +1524,7 @@ static PyObject *list_of_lists_from_arrays(const int *array,
PyDoc_STRVAR(
M_Geometry_delaunay_2d_cdt_doc,
- ".. function:: delaunay_2d_cdt(vert_coords, edges, faces, output_type, epsilon)\n"
+ ".. function:: delaunay_2d_cdt(vert_coords, edges, faces, output_type, epsilon [,need_ids])\n"
"\n"
" Computes the Constrained Delaunay Triangulation of a set of vertices,\n"
" with edges and faces that must appear in the triangulation.\n"
@@ -1533,6 +1536,8 @@ PyDoc_STRVAR(
" input element indices corresponding to the positionally same output element.\n"
" For edges, the orig indices start with the input edges and then continue\n"
" with the edges implied by each of the faces (n of them for an n-gon).\n"
+ " If the need_ids argument is supplied, and False, then the code skips the preparation\n"
+ " of the orig arrays, which may save some time."
"\n"
" :arg vert_coords: Vertex coordinates (2d)\n"
" :type vert_coords: list of :class:`mathutils.Vector`\n"
@@ -1543,10 +1548,14 @@ PyDoc_STRVAR(
" :arg output_type: What output looks like. 0 => triangles with convex hull. "
"1 => triangles inside constraints. "
"2 => the input constraints, intersected. "
- "3 => like 2 but with extra edges to make valid BMesh faces.\n"
+ "3 => like 2 but detect holes and omit them from output. "
+ "4 => like 2 but with extra edges to make valid BMesh faces. "
+ "5 => like 4 but detect holes and omit them from output.\n"
" :type output_type: int\\n"
" :arg epsilon: For nearness tests; should not be zero\n"
" :type epsilon: float\n"
+ " :arg need_ids: are the orig output arrays needed? (optional, default True)\n"
+ " :type need_args: bool\n"
" :return: Output tuple, (vert_coords, edges, faces, orig_verts, orig_edges, orig_faces)\n"
" :rtype: (list of `mathutils.Vector`, "
"list of (int, int), "
@@ -1561,6 +1570,7 @@ static PyObject *M_Geometry_delaunay_2d_cdt(PyObject *UNUSED(self), PyObject *ar
PyObject *vert_coords, *edges, *faces, *item;
int output_type;
float epsilon;
+ bool need_ids = true;
float(*in_coords)[2] = NULL;
int(*in_edges)[2] = NULL;
int *in_faces = NULL;
@@ -1578,8 +1588,14 @@ static PyObject *M_Geometry_delaunay_2d_cdt(PyObject *UNUSED(self), PyObject *ar
PyObject *ret_value = NULL;
int i;
- if (!PyArg_ParseTuple(
- args, "OOOif:delaunay_2d_cdt", &vert_coords, &edges, &faces, &output_type, &epsilon)) {
+ if (!PyArg_ParseTuple(args,
+ "OOOif|p:delaunay_2d_cdt",
+ &vert_coords,
+ &edges,
+ &faces,
+ &output_type,
+ &epsilon,
+ &need_ids)) {
return NULL;
}
@@ -1609,6 +1625,7 @@ static PyObject *M_Geometry_delaunay_2d_cdt(PyObject *UNUSED(self), PyObject *ar
in.faces_start_table = in_faces_start_table;
in.faces_len_table = in_faces_len_table;
in.epsilon = epsilon;
+ in.need_ids = need_ids;
res = BLI_delaunay_2d_cdt_calc(&in, output_type);
diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h
index aa2e182e1c0..e4c9f20f736 100644
--- a/source/blender/sequencer/SEQ_iterator.h
+++ b/source/blender/sequencer/SEQ_iterator.h
@@ -30,9 +30,9 @@ extern "C" {
#include "BLI_ghash.h"
struct Editing;
-struct Sequence;
struct GSet;
struct GSetIterator;
+struct Sequence;
#define SEQ_ITERATOR_FOREACH(var, collection) \
for (SeqIterator iter = {{{NULL}}}; \
diff --git a/source/blender/sequencer/SEQ_proxy.h b/source/blender/sequencer/SEQ_proxy.h
index b06adef2802..7bfe932ff1c 100644
--- a/source/blender/sequencer/SEQ_proxy.h
+++ b/source/blender/sequencer/SEQ_proxy.h
@@ -34,8 +34,8 @@ struct ListBase;
struct Main;
struct Scene;
struct SeqIndexBuildContext;
-struct Sequence;
struct SeqRenderData;
+struct Sequence;
bool SEQ_proxy_rebuild_context(struct Main *bmain,
struct Depsgraph *depsgraph,
diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h
index 706f4064bf3..f4338d13c8f 100644
--- a/source/blender/sequencer/SEQ_sequencer.h
+++ b/source/blender/sequencer/SEQ_sequencer.h
@@ -32,8 +32,8 @@ extern "C" {
struct Editing;
struct Scene;
struct Sequence;
-struct SequencerToolSettings;
struct SequenceLookup;
+struct SequencerToolSettings;
/* RNA enums, just to be more readable */
enum {
diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h
index 837a2de5742..9ff827333be 100644
--- a/source/blender/sequencer/SEQ_transform.h
+++ b/source/blender/sequencer/SEQ_transform.h
@@ -29,8 +29,8 @@ extern "C" {
struct ListBase;
struct Scene;
-struct Sequence;
struct SeqCollection;
+struct Sequence;
int SEQ_transform_get_left_handle_frame(struct Sequence *seq);
int SEQ_transform_get_right_handle_frame(struct Sequence *seq);
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c
index b9278b9f971..0dc8dfa10d7 100644
--- a/source/blender/sequencer/intern/strip_edit.c
+++ b/source/blender/sequencer/intern/strip_edit.c
@@ -407,6 +407,8 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
BLI_addtail(&left_strips, seq);
}
+ SEQ_collection_free(collection);
+
/* Sort list, so that no strip can depend on next strip in list.
* This is important for SEQ_time_update_sequence functionality. */
SEQ_sort(&left_strips);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 66e91526009..1c994707ca9 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -623,7 +623,7 @@ void WM_uilisttype_free(void);
void WM_uilisttype_to_full_list_id(const struct uiListType *ult,
const char *list_id,
- char *r_ui_list_id);
+ char r_full_list_id[]);
const char *WM_uilisttype_list_id_get(const struct uiListType *ult, struct uiList *list);
/* wm_menu_type.c */
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 0922aaaee53..f01e28f8822 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -457,6 +457,7 @@ static void wm_draw_region_buffer_create(ARegion *region, bool stereo, bool use_
GPUOffScreen *offscreen = GPU_offscreen_create(
region->winx, region->winy, false, false, NULL);
if (!offscreen) {
+ WM_report(RPT_ERROR, "Region could not be drawn!");
return;
}
diff --git a/source/blender/windowmanager/intern/wm_uilist_type.c b/source/blender/windowmanager/intern/wm_uilist_type.c
index 468ea7e4d5b..82ba4aa6e6f 100644
--- a/source/blender/windowmanager/intern/wm_uilist_type.c
+++ b/source/blender/windowmanager/intern/wm_uilist_type.c
@@ -154,7 +154,7 @@ void WM_uilisttype_free(void)
/**
* The "full" list-ID is an internal name used for storing and identifying a list. It is built like
* this:
- * "{uiListType.idname}_{list_id}", wherby "list_id" is an optional parameter passed to
+ * "{uiListType.idname}_{list_id}", whereby "list_id" is an optional parameter passed to
* `UILayout.template_list()`. If it is not set, the full list-ID is just "{uiListType.idname}_".
*
* Note that whenever the Python API refers to the list-ID, it's the short, "non-full" one it
@@ -163,7 +163,7 @@ void WM_uilisttype_free(void)
*/
void WM_uilisttype_to_full_list_id(const uiListType *ult,
const char *list_id,
- char r_full_list_id[UI_MAX_NAME_STR])
+ char r_full_list_id[/*UI_MAX_NAME_STR*/])
{
/* We tag the list id with the list type... */
BLI_snprintf(r_full_list_id, UI_MAX_NAME_STR, "%s_%s", ult->idname, list_id ? list_id : "");