Geometry: Skip recomputing bounds after translation #106159
|
@ -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<float3>> 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<float3> &r_data) { r_data = *bounds; });
|
||||
}
|
||||
}
|
||||
|
||||
void CurvesGeometry::transform(const float4x4 &matrix)
|
||||
|
|
|
@ -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<float3> positions, const float3 &translation)
|
||||
{
|
||||
MutableSpan<float3> 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<float3>> 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<float3 *>(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)
|
||||
|
|
|
@ -54,14 +54,6 @@ static void transform_positions(MutableSpan<float3> 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<float3>> 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<float3>(
|
||||
"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<float3> &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);
|
||||
|
|
Loading…
Reference in New Issue