[Bf-blender-cvs] [adb4dd911b9] master: Point Cloud: Support set origin and apply scale operators
Hans Goudey
noreply at git.blender.org
Mon Jan 2 17:16:53 CET 2023
Commit: adb4dd911b9183e1fb903e553f75a4a0df2d6717
Author: Hans Goudey
Date: Mon Jan 2 10:49:57 2023 -0500
Branches: master
https://developer.blender.org/rBadb4dd911b9183e1fb903e553f75a4a0df2d6717
Point Cloud: Support set origin and apply scale operators
Move some functions for transforming a span of vectors to a header
and call them from these functions, just like was done for curves
objects recently.
Resolves T102027, T102026
Differential Revision: https://developer.blender.org/D16883
===================================================================
M source/blender/editors/object/object_transform.cc
===================================================================
diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc
index 672c04d8db6..539260cd27f 100644
--- a/source/blender/editors/object/object_transform.cc
+++ b/source/blender/editors/object/object_transform.cc
@@ -19,6 +19,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
+#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "BLI_array.hh"
@@ -44,6 +45,7 @@
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_object.h"
+#include "BKE_pointcloud.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_tracking.h"
@@ -639,6 +641,17 @@ static bool apply_objects_internal_need_single_user(bContext *C)
return (ID_REAL_USERS(ob->data) > CTX_DATA_COUNT(C, selected_editable_objects));
}
+static void transform_positions(blender::MutableSpan<blender::float3> positions,
+ const blender::float4x4 &matrix)
+{
+ using namespace blender;
+ threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) {
+ for (float3 &position : positions.slice(range)) {
+ position = matrix * position;
+ }
+ });
+}
+
static int apply_objects_internal(bContext *C,
ReportList *reports,
bool apply_loc,
@@ -647,6 +660,7 @@ static int apply_objects_internal(bContext *C,
bool do_props,
bool do_single_user)
{
+ using namespace blender;
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -696,7 +710,8 @@ static int apply_objects_internal(bContext *C,
OB_SURF,
OB_FONT,
OB_GPENCIL,
- OB_CURVES)) {
+ OB_CURVES,
+ OB_POINTCLOUD)) {
ID *obdata = static_cast<ID *>(ob->data);
if (!do_multi_user && ID_REAL_USERS(obdata) > 1) {
BKE_reportf(reports,
@@ -932,6 +947,14 @@ static int apply_objects_internal(bContext *C,
blender::bke::CurvesGeometry::wrap(curves.geometry).transform(mat);
blender::bke::CurvesGeometry::wrap(curves.geometry).calculate_bezier_auto_handles();
}
+ else if (ob->type == OB_POINTCLOUD) {
+ PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
+ bke::MutableAttributeAccessor attributes = pointcloud.attributes_for_write();
+ bke::SpanAttributeWriter position = attributes.lookup_or_add_for_write_span<float3>(
+ "position", ATTR_DOMAIN_POINT);
+ transform_positions(position.span, float4x4(mat));
+ position.finish();
+ }
else if (ob->type == OB_CAMERA) {
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
@@ -1230,8 +1253,29 @@ enum {
ORIGIN_TO_CENTER_OF_MASS_VOLUME,
};
+static float3 calculate_mean(const blender::Span<blender::float3> values)
+{
+ if (values.is_empty()) {
+ return float3(0);
+ }
+ /* TODO: Use a method that avoids overflow. */
+ return std::accumulate(values.begin(), values.end(), float3(0)) / values.size();
+}
+
+static void translate_positions(blender::MutableSpan<blender::float3> positions,
+ const blender::float3 &translation)
+{
+ using namespace blender;
+ threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) {
+ for (float3 &position : positions.slice(range)) {
+ position += translation;
+ }
+ });
+}
+
static int object_origin_set_exec(bContext *C, wmOperator *op)
{
+ using namespace blender;
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
@@ -1653,9 +1697,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
}
}
else if (around == V3D_AROUND_CENTER_MEDIAN) {
- Span<float3> positions = curves.positions();
- cent = std::accumulate(positions.begin(), positions.end(), float3(0)) /
- curves.points_num();
+ cent = calculate_mean(curves.positions());
}
tot_change++;
@@ -1663,6 +1705,39 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
curves_id.id.tag |= LIB_TAG_DOIT;
do_inverse_offset = true;
}
+ else if (ob->type == OB_POINTCLOUD) {
+ PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
+ bke::MutableAttributeAccessor attributes = pointcloud.attributes_for_write();
+ bke::SpanAttributeWriter positions = attributes.lookup_or_add_for_write_span<float3>(
+ "position", ATTR_DOMAIN_POINT);
+ if (ELEM(centermode, ORIGIN_TO_CENTER_OF_MASS_SURFACE, ORIGIN_TO_CENTER_OF_MASS_VOLUME) ||
+ !ELEM(around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN)) {
+ BKE_report(op->reports,
+ RPT_WARNING,
+ "Point cloud object does not support this set origin operation");
+ continue;
+ }
+
+ if (centermode == ORIGIN_TO_CURSOR) {
+ /* Done. */
+ }
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
+ float3 min(std::numeric_limits<float>::max());
+ float3 max(-std::numeric_limits<float>::max());
+ if (pointcloud.bounds_min_max(min, max)) {
+ cent = math::midpoint(min, max);
+ }
+ }
+ else if (around == V3D_AROUND_CENTER_MEDIAN) {
+ cent = calculate_mean(positions.span);
+ }
+
+ tot_change++;
+ translate_positions(positions.span, -cent);
+ positions.finish();
+ pointcloud.id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
+ }
/* offset other selected objects */
if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
More information about the Bf-blender-cvs
mailing list