Blender V5.0
layer_utils.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstring>
10
11#include "BKE_collection.hh"
12#include "BKE_customdata.hh"
13#include "BKE_editmesh.hh"
14#include "BKE_layer.hh"
15#include "BKE_mesh_types.hh"
16
17#include "DNA_ID.h"
18#include "DNA_layer_types.h"
19#include "DNA_mesh_types.h"
20#include "DNA_object_types.h"
21
22/* -------------------------------------------------------------------- */
25
26using blender::Vector;
27
29 ViewLayer *view_layer, const View3D *v3d, const ObjectsInViewLayerParams *params)
30{
31 if (params->no_dup_data) {
32 FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob_iter) {
33 ID *id = static_cast<ID *>(ob_iter->data);
34 if (id) {
35 id->tag |= ID_TAG_DOIT;
36 }
37 }
39 }
40
41 Vector<Object *> objects;
42
43 FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob_iter) {
44 if (params->filter_fn) {
45 if (!params->filter_fn(ob_iter, params->filter_userdata)) {
46 continue;
47 }
48 }
49
50 if (params->no_dup_data) {
51 ID *id = static_cast<ID *>(ob_iter->data);
52 if (id) {
53 if (id->tag & ID_TAG_DOIT) {
54 id->tag &= ~ID_TAG_DOIT;
55 }
56 else {
57 continue;
58 }
59 }
60 }
61
62 objects.append(ob_iter);
63 }
65
66 return objects;
67}
68
70
71/* -------------------------------------------------------------------- */
74
76 ViewLayer *view_layer,
77 const View3D *v3d,
79{
80 if (params->no_dup_data) {
81 FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, v3d, -1, params->object_mode, base_iter) {
82 ID *id = static_cast<ID *>(base_iter->object->data);
83 if (id) {
84 id->tag |= ID_TAG_DOIT;
85 }
86 }
88 }
89
90 Vector<Base *> bases;
91
92 FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, v3d, -1, params->object_mode, base_iter) {
93 if (params->filter_fn) {
94 if (!params->filter_fn(base_iter->object, params->filter_userdata)) {
95 continue;
96 }
97 }
98 if (params->no_dup_data) {
99 ID *id = static_cast<ID *>(base_iter->object->data);
100 if (id) {
101 if (id->tag & ID_TAG_DOIT) {
102 id->tag &= ~ID_TAG_DOIT;
103 }
104 else {
105 continue;
106 }
107 }
108 }
109 bases.append(base_iter);
110 }
112
113 return bases;
114}
115
117 const Scene *scene,
118 ViewLayer *view_layer,
119 const View3D *v3d,
121{
123 scene, view_layer, v3d, params);
124 Vector<Object *> objects(bases.size());
125 std::transform(
126 bases.begin(), bases.end(), objects.begin(), [](Base *base) { return base->object; });
127 return objects;
128}
129
131 ViewLayer *view_layer,
132 const View3D *v3d)
133{
135 params.object_mode = OB_MODE_EDIT;
136 return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, &params);
137}
138
140 ViewLayer *view_layer,
141 const View3D *v3d)
142{
144 params.object_mode = OB_MODE_EDIT;
145 return BKE_view_layer_array_from_bases_in_mode_params(scene, view_layer, v3d, &params);
146}
147
149 ViewLayer *view_layer,
150 const View3D *v3d)
151{
153 params.object_mode = OB_MODE_EDIT;
154 params.no_dup_data = true;
155 return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, &params);
156}
157
159 ViewLayer *view_layer,
160 const View3D *v3d)
161{
163 params.object_mode = OB_MODE_EDIT;
164 params.no_dup_data = true;
165 return BKE_view_layer_array_from_bases_in_mode_params(scene, view_layer, v3d, &params);
166}
167
169 const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
170{
172 params.object_mode = OB_MODE_EDIT;
173 params.no_dup_data = true;
175 return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, &params);
176}
177
179 ViewLayer *view_layer,
180 const View3D *v3d,
181 const eObjectMode mode)
182{
184 params.object_mode = mode;
185 params.no_dup_data = true;
186 return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, &params);
187}
188
190{
191 BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
192 "Object Bases out of sync, invoke BKE_view_layer_synced_ensure.");
193 return &view_layer->object_bases;
194}
195
197{
198 BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
199 "Active Base out of sync, invoke BKE_view_layer_synced_ensure.");
200 return view_layer->basact;
201}
202
204{
205 BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
206 "Active Collection out of sync, invoke BKE_view_layer_synced_ensure.");
207 return view_layer->active_collection;
208}
209
211
212/* -------------------------------------------------------------------- */
215
216bool BKE_view_layer_filter_edit_mesh_has_uvs(const Object *ob, void * /*user_data*/)
217{
218 if (ob->type == OB_MESH) {
219 const Mesh *mesh = static_cast<const Mesh *>(ob->data);
220 if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
221 if (CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) {
222 return true;
223 }
224 }
225 }
226 return false;
227}
228
229bool BKE_view_layer_filter_edit_mesh_has_edges(const Object *ob, void * /*user_data*/)
230{
231 if (ob->type == OB_MESH) {
232 const Mesh *mesh = static_cast<const Mesh *>(ob->data);
233 if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
234 if (em->bm->totedge != 0) {
235 return true;
236 }
237 }
238 }
239 return false;
240}
241
243 ViewLayer *view_layer,
244 const View3D *v3d)
245{
246 BKE_view_layer_synced_ensure(scene, view_layer);
247 Object *ob_active = BKE_view_layer_active_object_get(view_layer);
248 Object *ob_result = nullptr;
249 FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob_iter) {
250 if (ob_iter == ob_active) {
251 continue;
252 }
253
254 if (ob_result == nullptr) {
255 ob_result = ob_iter;
256 }
257 else {
258 ob_result = nullptr;
259 break;
260 }
261 }
263 return ob_result;
264}
265
267
268/* -------------------------------------------------------------------- */
271
273{
274 Base *base = BKE_view_layer_active_base_get((ViewLayer *)view_layer);
275 return base ? base->object : nullptr;
276}
277
279{
281 if (ob == nullptr) {
282 return nullptr;
283 }
284 if (!(ob->mode & OB_MODE_EDIT)) {
285 return nullptr;
286 }
287 return ob;
288}
289
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
bool BKE_view_layer_filter_edit_mesh_has_uvs(const Object *ob, void *user_data)
#define FOREACH_BASE_IN_MODE_END
Definition BKE_layer.hh:367
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
#define FOREACH_SELECTED_OBJECT_BEGIN(_view_layer, _v3d, _instance)
Definition BKE_layer.hh:298
#define FOREACH_BASE_IN_MODE_BEGIN(_scene, _view_layer, _v3d, _object_type, _object_mode, _instance)
Definition BKE_layer.hh:349
#define FOREACH_SELECTED_OBJECT_END
Definition BKE_layer.hh:310
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
ID and Library types, which are fundamental for SDNA.
@ ID_TAG_DOIT
Definition DNA_ID.h:1036
@ CD_PROP_FLOAT2
@ VIEW_LAYER_OUT_OF_SYNC
eObjectMode
@ OB_MODE_EDIT
Object is a sort of wrapper for general info.
@ OB_MESH
int64_t size() const
void append(const T &value)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
bool BKE_view_layer_filter_edit_mesh_has_uvs(const Object *ob, void *)
Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
Vector< Base * > BKE_view_layer_array_from_bases_in_mode_params(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, const ObjectsInModeParams *params)
LayerCollection * BKE_view_layer_active_collection_get(ViewLayer *view_layer)
Vector< Object * > BKE_view_layer_array_from_objects_in_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, const eObjectMode mode)
Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
Vector< Object * > BKE_view_layer_array_selected_objects_params(ViewLayer *view_layer, const View3D *v3d, const ObjectsInViewLayerParams *params)
Vector< Object * > BKE_view_layer_array_from_objects_in_mode_params(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, const ObjectsInModeParams *params)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
Vector< Base * > BKE_view_layer_array_from_bases_in_edit_mode(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
Object * BKE_view_layer_non_active_selected_object(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
Vector< Base * > BKE_view_layer_array_from_bases_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
Object * BKE_view_layer_edit_object_get(const ViewLayer *view_layer)
bool BKE_view_layer_filter_edit_mesh_has_edges(const Object *ob, void *)
Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
struct Object * object
Definition DNA_ID.h:414
int tag
Definition DNA_ID.h:442
MeshRuntimeHandle * runtime
LayerCollection * active_collection
struct Base * basact
ListBase object_bases