Blender V5.0
pointcloud/intern/join.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_map.hh"
6
7#include "DNA_scene_types.h"
8
9#include "BKE_context.hh"
10#include "BKE_instances.hh"
11#include "BKE_pointcloud.hh"
12#include "BKE_report.hh"
13
14#include "DEG_depsgraph.hh"
16
17#include "WM_api.hh"
18#include "WM_types.hh"
19
20#include "ED_object.hh"
21#include "ED_pointcloud.hh"
22
24
26
28{
29 Main *bmain = CTX_data_main(C);
30 Scene *scene = CTX_data_scene(C);
31 Object *active_object = CTX_data_active_object(C);
32 BLI_assert(active_object);
33 BLI_assert(active_object->type == OB_POINTCLOUD);
34 PointCloud &active_pointcloud = *static_cast<PointCloud *>(active_object->data);
35 const float4x4 &world_to_active = active_object->world_to_object();
36
37 Vector<Object *> objects{active_object};
38 bool active_object_selected = false;
39 CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) {
40 if (object == active_object) {
41 active_object_selected = true;
42 continue;
43 }
44 if (object->type != OB_POINTCLOUD) {
45 continue;
46 }
47 objects.append(object);
48 }
50
51 if (!active_object_selected) {
52 BKE_report(op->reports, RPT_WARNING, "Active object is not a selected point cloud object");
53 return OPERATOR_CANCELLED;
54 }
55
56 bke::Instances instances;
57 instances.resize(objects.size());
58 MutableSpan<float4x4> transforms = instances.transforms_for_write();
59 MutableSpan<int> references = instances.reference_handles_for_write();
60 Map<const PointCloud *, int> reference_by_orig_points;
61 for (const int i : objects.index_range()) {
62 transforms[i] = world_to_active * objects[i]->object_to_world();
63 const PointCloud *orig_points = static_cast<const PointCloud *>(objects[i]->data);
64 references[i] = reference_by_orig_points.lookup_or_add_cb(orig_points, [&]() {
66 return instances.add_new_reference(std::move(geometry));
67 });
68 }
69
74 .geometry;
75
76 if (!realized_geometry.has_pointcloud()) {
77 BKE_report(op->reports, RPT_WARNING, "No point cloud data to join");
78 return OPERATOR_CANCELLED;
79 }
80
81 PointCloud *realized_points =
82 realized_geometry.get_component_for_write<bke::PointCloudComponent>().release();
83 BKE_pointcloud_nomain_to_pointcloud(realized_points, &active_pointcloud);
84
85 for (Object *object : objects.as_span().drop_front(1)) {
86 object::base_free_and_unlink(bmain, scene, object);
87 }
88
94
95 return OPERATOR_FINISHED;
96}
97
98} // namespace blender::ed::pointcloud
#define CTX_DATA_BEGIN(C, Type, instance, member)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
#define CTX_DATA_END
General operations for point clouds.
PointCloud * BKE_pointcloud_copy_for_eval(const PointCloud *pointcloud_src)
void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src, PointCloud *pointcloud_dst)
@ RPT_WARNING
Definition BKE_report.hh:38
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert(a)
Definition BLI_assert.h:46
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1054
@ ID_RECALC_SELECT
Definition DNA_ID.h:1101
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ OB_POINTCLOUD
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
#define C
Definition RandGen.cpp:29
#define ND_OB_ACTIVE
Definition WM_types.hh:440
#define NC_SCENE
Definition WM_types.hh:378
#define ND_LAYER_CONTENT
Definition WM_types.hh:453
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
Definition BLI_map.hh:620
int64_t size() const
void append(const T &value)
IndexRange index_range() const
Span< T > as_span() const
MutableSpan< int > reference_handles_for_write()
Definition instances.cc:222
int add_new_reference(const InstanceReference &reference)
Definition instances.cc:269
void resize(int capacity)
Definition instances.cc:191
MutableSpan< float4x4 > transforms_for_write()
Definition instances.cc:235
void base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
wmOperatorStatus join_objects_exec(bContext *C, wmOperator *op)
RealizeInstancesResult realize_instances(bke::GeometrySet geometry_set, const RealizeInstancesOptions &options)
MatBase< float, 4, 4 > float4x4
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
static GeometrySet from_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet from_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
struct ReportList * reports
i
Definition text_draw.cc:230
void WM_event_add_notifier(const bContext *C, uint type, void *reference)