diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index cc2ca265cfc..108841b0bcc 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -1037,6 +1037,15 @@ void CurvesGeometry::calculate_bezier_auto_handles() void CurvesGeometry::translate(const float3 &translation) { + if (math::is_zero(translation)) { + return; + } + + std::optional> bounds; + if (this->runtime->bounds_cache.is_cached()) { + bounds = this->runtime->bounds_cache.data(); + } + translate_positions(this->positions_for_write(), translation); if (!this->handle_positions_left().is_empty()) { translate_positions(this->handle_positions_left_for_write(), translation); @@ -1045,6 +1054,12 @@ void CurvesGeometry::translate(const float3 &translation) translate_positions(this->handle_positions_right_for_write(), translation); } this->tag_positions_changed(); + + if (bounds) { + bounds->min += translation; + bounds->max += translation; + this->runtime->bounds_cache.ensure([&](blender::Bounds &r_data) { r_data = *bounds; }); + } } void CurvesGeometry::transform(const float4x4 &matrix) diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 6b4eaa36f93..79e03ccd933 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1582,23 +1582,42 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) BKE_mesh_tag_positions_changed(me); } -void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys) +static void translate_positions(MutableSpan positions, const float3 &translation) { - MutableSpan positions = me->vert_positions_for_write(); - for (float3 &position : positions) { - position += offset; + using namespace blender; + threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) { + for (float3 &position : positions.slice(range)) { + position += translation; + } + }); +} + +void BKE_mesh_translate(Mesh *mesh, const float offset[3], const bool do_keys) +{ + using namespace blender; + if (math::is_zero(float3(offset))) { + return; } - int i; - if (do_keys && me->key) { - LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) { - float *fp = (float *)kb->data; - for (i = kb->totelem; i--; fp += 3) { - add_v3_v3(fp, offset); - } + std::optional> bounds; + if (mesh->runtime->bounds_cache.is_cached()) { + bounds = mesh->runtime->bounds_cache.data(); + } + + translate_positions(mesh->vert_positions_for_write(), offset); + if (do_keys && mesh->key) { + LISTBASE_FOREACH (KeyBlock *, kb, &mesh->key->block) { + translate_positions({static_cast(kb->data), kb->totelem}, offset); } } - BKE_mesh_tag_positions_changed_uniformly(me); + + BKE_mesh_tag_positions_changed_uniformly(mesh); + + if (bounds) { + bounds->min += offset; + bounds->max += offset; + mesh->bounds_set_eager(*bounds); + } } void BKE_mesh_tessface_clear(Mesh *mesh) diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc index 7eac7bc87aa..10e9182c598 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc @@ -54,14 +54,6 @@ static void transform_positions(MutableSpan positions, const float4x4 &m }); } -static void translate_mesh(Mesh &mesh, const float3 translation) -{ - if (!math::is_zero(translation)) { - translate_positions(mesh.vert_positions_for_write(), translation); - BKE_mesh_tag_positions_changed_uniformly(&mesh); - } -} - static void transform_mesh(Mesh &mesh, const float4x4 &transform) { transform_positions(mesh.vert_positions_for_write(), transform); @@ -70,11 +62,26 @@ static void transform_mesh(Mesh &mesh, const float4x4 &transform) static void translate_pointcloud(PointCloud &pointcloud, const float3 translation) { + if (math::is_zero(translation)) { + return; + } + + std::optional> bounds; + if (pointcloud.runtime->bounds_cache.is_cached()) { + bounds = pointcloud.runtime->bounds_cache.data(); + } + MutableAttributeAccessor attributes = pointcloud.attributes_for_write(); SpanAttributeWriter position = attributes.lookup_or_add_for_write_span( "position", ATTR_DOMAIN_POINT); translate_positions(position.span, translation); position.finish(); + + if (bounds) { + bounds->min += translation; + bounds->max += translation; + pointcloud.runtime->bounds_cache.ensure([&](Bounds &r_data) { r_data = *bounds; }); + } } static void transform_pointcloud(PointCloud &pointcloud, const float4x4 &transform) @@ -199,7 +206,7 @@ static void translate_geometry_set(GeoNodeExecParams ¶ms, curves->geometry.wrap().translate(translation); } if (Mesh *mesh = geometry.get_mesh_for_write()) { - translate_mesh(*mesh, translation); + BKE_mesh_translate(mesh, translation, false); } if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) { translate_pointcloud(*pointcloud, translation);