Blender V4.3
mball.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#include <cctype>
13#include <cfloat>
14#include <cmath>
15#include <cstdio>
16#include <cstdlib>
17#include <cstring>
18#include <optional>
19
20#include "MEM_guardedalloc.h"
21
22/* Allow using deprecated functionality for .blend file I/O. */
23#define DNA_DEPRECATED_ALLOW
24
25#include "DNA_defaults.h"
26#include "DNA_material_types.h"
27#include "DNA_mesh_types.h"
28#include "DNA_meta_types.h"
29#include "DNA_object_types.h"
30#include "DNA_scene_types.h"
31
32#include "BLI_math_matrix.h"
33#include "BLI_math_rotation.h"
34#include "BLI_math_vector.h"
35#include "BLI_string_utils.hh"
36#include "BLI_utildefines.h"
37
38#include "BLT_translation.hh"
39
40#include "BKE_main.hh"
41
42#include "BKE_geometry_set.hh"
43#include "BKE_idtype.hh"
44#include "BKE_lattice.hh"
45#include "BKE_layer.hh"
46#include "BKE_lib_id.hh"
47#include "BKE_lib_query.hh"
48#include "BKE_mball.hh"
50#include "BKE_object.hh"
51#include "BKE_object_types.hh"
52
53#include "DEG_depsgraph.hh"
54
55#include "BLO_read_write.hh"
56
57using blender::Span;
58
67
68static void metaball_copy_data(Main * /*bmain*/,
69 std::optional<Library *> /*owner_library*/,
70 ID *id_dst,
71 const ID *id_src,
72 const int /*flag*/)
73{
74 MetaBall *metaball_dst = (MetaBall *)id_dst;
75 const MetaBall *metaball_src = (const MetaBall *)id_src;
76
77 BLI_duplicatelist(&metaball_dst->elems, &metaball_src->elems);
78
79 metaball_dst->mat = static_cast<Material **>(MEM_dupallocN(metaball_src->mat));
80
81 metaball_dst->editelems = nullptr;
82 metaball_dst->lastelem = nullptr;
83}
84
85static void metaball_free_data(ID *id)
86{
87 MetaBall *metaball = (MetaBall *)id;
88
90
91 BLI_freelistN(&metaball->elems);
92}
93
95{
96 MetaBall *metaball = reinterpret_cast<MetaBall *>(id);
98
99 for (int i = 0; i < metaball->totcol; i++) {
101 }
102
105 }
106}
107
108static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_address)
109{
110 MetaBall *mb = (MetaBall *)id;
111
112 /* Clean up, important in undo case to reduce false detection of changed datablocks. */
113 mb->editelems = nullptr;
114 /* Must always be cleared (meta's don't have their own edit-data). */
115 mb->needs_flush_to_id = 0;
116 mb->lastelem = nullptr;
117
118 /* write LibData */
119 BLO_write_id_struct(writer, MetaBall, id_address, &mb->id);
120 BKE_id_blend_write(writer, &mb->id);
121
122 /* direct data */
123 BLO_write_pointer_array(writer, mb->totcol, mb->mat);
124
125 LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
126 BLO_write_struct(writer, MetaElem, ml);
127 }
128}
129
131{
132 MetaBall *mb = (MetaBall *)id;
133
134 BLO_read_pointer_array(reader, mb->totcol, (void **)&mb->mat);
135
136 BLO_read_struct_list(reader, MetaElem, &(mb->elems));
137
138 mb->editelems = nullptr;
139 /* Must always be cleared (meta's don't have their own edit-data). */
140 mb->needs_flush_to_id = 0;
141 // mb->edit_elems.first = mb->edit_elems.last = nullptr;
142 mb->lastelem = nullptr;
143}
144
146 /*id_code*/ ID_MB,
147 /*id_filter*/ FILTER_ID_MB,
148 /*dependencies_id_types*/ FILTER_ID_MA,
149 /*main_listbase_index*/ INDEX_ID_MB,
150 /*struct_size*/ sizeof(MetaBall),
151 /*name*/ "Metaball",
152 /*name_plural*/ N_("metaballs"),
153 /*translation_context*/ BLT_I18NCONTEXT_ID_METABALL,
155 /*asset_type_info*/ nullptr,
156
157 /*init_data*/ metaball_init_data,
158 /*copy_data*/ metaball_copy_data,
159 /*free_data*/ metaball_free_data,
160 /*make_local*/ nullptr,
161 /*foreach_id*/ metaball_foreach_id,
162 /*foreach_cache*/ nullptr,
163 /*foreach_path*/ nullptr,
164 /*owner_pointer_get*/ nullptr,
165
166 /*blend_write*/ metaball_blend_write,
167 /*blend_read_data*/ metaball_blend_read_data,
168 /*blend_read_after_liblink*/ nullptr,
169
170 /*blend_read_undo_preserve*/ nullptr,
171
172 /*lib_override_apply_post*/ nullptr,
173};
174
175/* Functions */
176
177MetaBall *BKE_mball_add(Main *bmain, const char *name)
178{
179 MetaBall *mb = static_cast<MetaBall *>(BKE_id_new(bmain, ID_MB, name));
180 return mb;
181}
182
184{
185 MetaElem *ml = MEM_cnew<MetaElem>(__func__);
186
187 unit_qt(ml->quat);
188
189 ml->rad = 2.0;
190 ml->s = 2.0;
191 ml->flag = MB_SCALE_RAD;
192
193 switch (type) {
194 case MB_BALL:
195 ml->type = MB_BALL;
196 ml->expx = ml->expy = ml->expz = 1.0;
197
198 break;
199 case MB_TUBE:
200 ml->type = MB_TUBE;
201 ml->expx = ml->expy = ml->expz = 1.0;
202
203 break;
204 case MB_PLANE:
205 ml->type = MB_PLANE;
206 ml->expx = ml->expy = ml->expz = 1.0;
207
208 break;
209 case MB_ELIPSOID:
210 ml->type = MB_ELIPSOID;
211 ml->expx = 1.2f;
212 ml->expy = 0.8f;
213 ml->expz = 1.0;
214
215 break;
216 case MB_CUBE:
217 ml->type = MB_CUBE;
218 ml->expx = ml->expy = ml->expz = 1.0;
219
220 break;
221 default:
222 break;
223 }
224
225 BLI_addtail(&mb->elems, ml);
226
227 return ml;
228}
229
231{
232 /* Meta-Ball Basis Notes from Blender-2.5x
233 * =======================================
234 *
235 * NOTE(@ideasman42): This is a can of worms.
236 *
237 * This really needs a rewrite/refactor its totally broken in anything other than basic cases
238 * Multiple Scenes + Set Scenes & mixing meta-ball basis _should_ work but fails to update the
239 * depsgraph on rename and linking into scenes or removal of basis meta-ball.
240 * So take care when changing this code.
241 *
242 * Main idiot thing here is that the system returns #BKE_mball_basis_find()
243 * objects which fail a #BKE_mball_is_basis() test.
244 *
245 * Not only that but the depsgraph and their areas depend on this behavior,
246 * so making small fixes here isn't worth it. */
247
248 /* Just a quick test. */
249 const int len = strlen(ob->id.name);
250 return !isdigit(ob->id.name[len - 1]);
251}
252
253bool BKE_mball_is_same_group(const Object *ob1, const Object *ob2)
254{
255 int basis1nr, basis2nr;
256 char basis1name[MAX_ID_NAME], basis2name[MAX_ID_NAME];
257
258 if (ob1->id.name[2] != ob2->id.name[2]) {
259 /* Quick return in case first char of both ID's names is not the same... */
260 return false;
261 }
262
263 BLI_string_split_name_number(ob1->id.name + 2, '.', basis1name, &basis1nr);
264 BLI_string_split_name_number(ob2->id.name + 2, '.', basis2name, &basis2nr);
265
266 return STREQ(basis1name, basis2name);
267}
268
269bool BKE_mball_is_basis_for(const Object *ob1, const Object *ob2)
270{
271 return BKE_mball_is_same_group(ob1, ob2) && BKE_mball_is_basis(ob1);
272}
273
275{
276 LISTBASE_FOREACH (const MetaElem *, ml, mb->editelems) {
277 if (ml->flag & SELECT) {
278 return true;
279 }
280 }
281 return false;
282}
283
285{
286 for (Base *base : bases) {
287 Object *obedit = base->object;
288 MetaBall *mb = (MetaBall *)obedit->data;
290 return true;
291 }
292 }
293 return false;
294}
295
297{
298 LISTBASE_FOREACH (const MetaElem *, ml, mb->editelems) {
299 if ((ml->flag & SELECT) == 0) {
300 return true;
301 }
302 }
303 return false;
304}
305
306static void mball_data_properties_copy(MetaBall *mb_dst, MetaBall *mb_src)
307{
308 mb_dst->wiresize = mb_src->wiresize;
309 mb_dst->rendersize = mb_src->rendersize;
310 mb_dst->thresh = mb_src->thresh;
311 mb_dst->flag = mb_src->flag;
312 DEG_id_tag_update(&mb_dst->id, 0);
313}
314
315void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
316{
334 for (Object *ob_src = static_cast<Object *>(bmain->objects.first);
335 ob_src != nullptr && ID_IS_EDITABLE(ob_src);)
336 {
337 if (ob_src->data != metaball_src) {
338 ob_src = static_cast<Object *>(ob_src->id.next);
339 continue;
340 }
341
342 /* In this code we take advantage of two facts:
343 * - MetaBalls of the same family have the same basis name,
344 * - IDs are sorted by name in their Main listbase.
345 * So, all MetaBall objects of the same family are contiguous in bmain list (potentially mixed
346 * with non-meta-ball objects with same basis names).
347 *
348 * Using this, it is possible to process the whole set of meta-balls with a single loop on the
349 * whole list of Objects, though additionally going backward on part of the list in some cases.
350 */
351 Object *ob_iter = nullptr;
352 int obactive_nr, ob_nr;
353 char obactive_name[MAX_ID_NAME], ob_name[MAX_ID_NAME];
354 BLI_string_split_name_number(ob_src->id.name + 2, '.', obactive_name, &obactive_nr);
355
356 for (ob_iter = static_cast<Object *>(ob_src->id.prev); ob_iter != nullptr;
357 ob_iter = static_cast<Object *>(ob_iter->id.prev))
358 {
359 if (ob_iter->id.name[2] != obactive_name[0]) {
360 break;
361 }
362 if (ob_iter->type != OB_MBALL || ob_iter->data == metaball_src) {
363 continue;
364 }
365 BLI_string_split_name_number(ob_iter->id.name + 2, '.', ob_name, &ob_nr);
366 if (!STREQ(obactive_name, ob_name)) {
367 break;
368 }
369
370 mball_data_properties_copy(static_cast<MetaBall *>(ob_iter->data), metaball_src);
371 }
372
373 for (ob_iter = static_cast<Object *>(ob_src->id.next); ob_iter != nullptr;
374 ob_iter = static_cast<Object *>(ob_iter->id.next))
375 {
376 if (ob_iter->id.name[2] != obactive_name[0] || !ID_IS_EDITABLE(ob_iter)) {
377 break;
378 }
379 if (ob_iter->type != OB_MBALL || ob_iter->data == metaball_src) {
380 continue;
381 }
382 BLI_string_split_name_number(ob_iter->id.name + 2, '.', ob_name, &ob_nr);
383 if (!STREQ(obactive_name, ob_name)) {
384 break;
385 }
386
387 mball_data_properties_copy(static_cast<MetaBall *>(ob_iter->data), metaball_src);
388 }
389
390 ob_src = ob_iter;
391 }
392}
393
395{
396 Object *bob = object;
397 int basisnr, obnr;
398 char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
399
400 BLI_string_split_name_number(object->id.name + 2, '.', basisname, &basisnr);
401
402 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
403 BKE_view_layer_synced_ensure(scene, view_layer);
405 Object *ob = base->object;
406 if ((ob->type == OB_MBALL) && !(base->flag & BASE_FROM_DUPLI)) {
407 if (ob != bob) {
408 BLI_string_split_name_number(ob->id.name + 2, '.', obname, &obnr);
409
410 /* Object ob has to be in same "group" ... it means,
411 * that it has to have same base of its name. */
412 if (STREQ(obname, basisname)) {
413 if (obnr < basisnr) {
414 object = ob;
415 basisnr = obnr;
416 }
417 }
418 }
419 }
420 }
421 }
422
423 return object;
424}
425
427 const MetaBall *mb, float min[3], float max[3], const float obmat[4][4], const short flag)
428{
429 const float scale = obmat ? mat4_to_scale(obmat) : 1.0f;
430 bool changed = false;
431 float centroid[3], vec[3];
432
433 INIT_MINMAX(min, max);
434
435 LISTBASE_FOREACH (const MetaElem *, ml, &mb->elems) {
436 if ((ml->flag & flag) == flag) {
437 const float scale_mb = (ml->rad * 0.5f) * scale;
438
439 if (obmat) {
440 mul_v3_m4v3(centroid, obmat, &ml->x);
441 }
442 else {
443 copy_v3_v3(centroid, &ml->x);
444 }
445
446 /* TODO(@ideasman42): non circle shapes cubes etc, probably nobody notices. */
447 for (int i = -1; i != 3; i += 2) {
448 copy_v3_v3(vec, centroid);
449 add_v3_fl(vec, scale_mb * i);
450 minmax_v3v3_v3(min, max, vec);
451 }
452 changed = true;
453 }
454 }
455
456 return changed;
457}
458
459bool BKE_mball_minmax(const MetaBall *mb, float min[3], float max[3])
460{
461 INIT_MINMAX(min, max);
462
463 LISTBASE_FOREACH (const MetaElem *, ml, &mb->elems) {
464 minmax_v3v3_v3(min, max, &ml->x);
465 }
466
467 return (BLI_listbase_is_empty(&mb->elems) == false);
468}
469
470bool BKE_mball_center_median(const MetaBall *mb, float r_cent[3])
471{
472 int total = 0;
473
474 zero_v3(r_cent);
475
476 LISTBASE_FOREACH (const MetaElem *, ml, &mb->elems) {
477 add_v3_v3(r_cent, &ml->x);
478 total++;
479 }
480
481 if (total) {
482 mul_v3_fl(r_cent, 1.0f / float(total));
483 }
484
485 return (total != 0);
486}
487
488bool BKE_mball_center_bounds(const MetaBall *mb, float r_cent[3])
489{
490 float min[3], max[3];
491
492 if (BKE_mball_minmax(mb, min, max)) {
493 mid_v3_v3v3(r_cent, min, max);
494 return true;
495 }
496
497 return false;
498}
499
500void BKE_mball_transform(MetaBall *mb, const float mat[4][4], const bool do_props)
501{
502 float quat[4];
503 const float scale = mat4_to_scale(mat);
504 const float scale_sqrt = sqrtf(scale);
505
506 mat4_to_quat(quat, mat);
507
508 LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
509 mul_m4_v3(mat, &ml->x);
510 mul_qt_qtqt(ml->quat, quat, ml->quat);
511
512 if (do_props) {
513 ml->rad *= scale;
514 /* hrmf, probably elems shouldn't be
515 * treating scale differently - campbell */
516 if (!MB_TYPE_SIZE_SQUARED(ml->type)) {
517 mul_v3_fl(&ml->expx, scale);
518 }
519 else {
520 mul_v3_fl(&ml->expx, scale_sqrt);
521 }
522 }
523 }
524}
525
526void BKE_mball_translate(MetaBall *mb, const float offset[3])
527{
528 LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
529 add_v3_v3(&ml->x, offset);
530 }
531}
532
534{
535 int sel = 0;
536 LISTBASE_FOREACH (const MetaElem *, ml, mb->editelems) {
537 if (ml->flag & SELECT) {
538 sel++;
539 }
540 }
541 return sel;
542}
543
545{
546 int sel = 0;
547 for (Base *base : bases) {
548 Object *obedit = base->object;
549 const MetaBall *mb = (MetaBall *)obedit->data;
550 sel += BKE_mball_select_count(mb);
551 }
552 return sel;
553}
554
556{
557 bool changed = false;
558 LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
559 if ((ml->flag & SELECT) == 0) {
560 ml->flag |= SELECT;
561 changed = true;
562 }
563 }
564 return changed;
565}
566
568{
569 bool changed_multi = false;
570 for (Base *base : bases) {
571 Object *obedit = base->object;
572 MetaBall *mb = static_cast<MetaBall *>(obedit->data);
573 changed_multi |= BKE_mball_select_all(mb);
574 }
575 return changed_multi;
576}
577
579{
580 bool changed = false;
581 LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
582 if ((ml->flag & SELECT) != 0) {
583 ml->flag &= ~SELECT;
584 changed = true;
585 }
586 }
587 return changed;
588}
589
591{
592 bool changed_multi = false;
593 for (Base *base : bases) {
594 Object *obedit = base->object;
595 MetaBall *mb = static_cast<MetaBall *>(obedit->data);
596 changed_multi |= BKE_mball_deselect_all(mb);
598 }
599 return changed_multi;
600}
601
603{
604 bool changed = false;
605 LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
606 ml->flag ^= SELECT;
607 changed = true;
608 }
609 return changed;
610}
611
613{
614 bool changed_multi = false;
615 for (Base *base : bases) {
616 Object *obedit = base->object;
617 MetaBall *mb = (MetaBall *)obedit->data;
618 changed_multi |= BKE_mball_select_swap(mb);
619 }
620 return changed_multi;
621}
622
623/* **** Depsgraph evaluation **** */
624
625void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
626{
627 using namespace blender;
628 using namespace blender::bke;
629 BLI_assert(ob->type == OB_MBALL);
630
632
633 const Object *basis_object = BKE_mball_basis_find(scene, ob);
634 if (ob != basis_object) {
635 return;
636 }
637
638 Mesh *mesh = BKE_mball_polygonize(depsgraph, scene, ob);
639 if (mesh == nullptr) {
640 return;
641 }
642
643 const MetaBall *mball = static_cast<MetaBall *>(ob->data);
644 mesh->mat = static_cast<Material **>(MEM_dupallocN(mball->mat));
645 mesh->totcol = mball->totcol;
646
647 if (ob->parent && ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
649 ob->parent,
650 ob,
651 reinterpret_cast<float(*)[3]>(mesh->vert_positions_for_write().data()),
652 mesh->verts_num,
653 0,
654 nullptr,
655 1.0f);
656 mesh->tag_positions_changed();
657 }
658
659 ob->runtime->geometry_set_eval = new GeometrySet(GeometrySet::from_mesh(mesh));
660};
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition BKE_idtype.hh:39
void BKE_lattice_deform_coords(const Object *ob_lattice, const Object *ob_target, float(*vert_coords)[3], int vert_coords_len, short flag, const char *defgrp_name, float fac)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1482
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2560
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
@ IDWALK_CB_USER
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:120
@ IDWALK_DO_DEPRECATED_POINTERS
#define BKE_LIB_FOREACHID_PROCESS_ID_NOCHECK(data_, id_, cb_flag_)
Mesh * BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
General operations, lookup, etc. for blender objects.
void BKE_object_free_derived_caches(Object *ob)
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
float mat4_to_scale(const float mat[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void unit_qt(float q[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
void mat4_to_quat(float q[4], const float mat[4][4])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void add_v3_fl(float r[3], float f)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
size_t BLI_string_split_name_number(const char *name, char delim, char *r_name_left, int *r_number) ATTR_NONNULL(1
#define INIT_MINMAX(min, max)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
void BLO_read_pointer_array(BlendDataReader *reader, int array_size, void **ptr_p)
Definition readfile.cc:5052
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
#define BLT_I18NCONTEXT_ID_METABALL
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SELECT
Definition DNA_ID.h:1068
#define FILTER_ID_MA
Definition DNA_ID.h:1175
#define FILTER_ID_MB
Definition DNA_ID.h:1176
#define MAX_ID_NAME
Definition DNA_ID.h:377
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
@ INDEX_ID_MB
Definition DNA_ID.h:1295
@ ID_MB
#define DNA_struct_default_get(struct_name)
@ BASE_FROM_DUPLI
#define MB_TYPE_SIZE_SQUARED(type)
@ MB_SCALE_RAD
struct MetaBall MetaBall
@ MB_PLANE
@ MB_ELIPSOID
@ MB_TUBE
@ MB_CUBE
@ MB_BALL
Object is a sort of wrapper for general info.
@ PARSKEL
@ OB_LATTICE
@ OB_MBALL
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define SELECT
const Depsgraph * depsgraph
#define sqrtf(x)
int len
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition mball.cc:108
void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
Definition mball.cc:625
Object * BKE_mball_basis_find(Scene *scene, Object *object)
Definition mball.cc:394
bool BKE_mball_is_same_group(const Object *ob1, const Object *ob2)
Definition mball.cc:253
int BKE_mball_select_count(const MetaBall *mb)
Definition mball.cc:533
void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
Definition mball.cc:315
bool BKE_mball_deselect_all(MetaBall *mb)
Definition mball.cc:578
bool BKE_mball_is_any_selected_multi(const Span< Base * > bases)
Definition mball.cc:284
bool BKE_mball_minmax_ex(const MetaBall *mb, float min[3], float max[3], const float obmat[4][4], const short flag)
Definition mball.cc:426
bool BKE_mball_center_bounds(const MetaBall *mb, float r_cent[3])
Definition mball.cc:488
bool BKE_mball_is_any_unselected(const MetaBall *mb)
Definition mball.cc:296
bool BKE_mball_select_swap_multi_ex(const Span< Base * > bases)
Definition mball.cc:612
MetaBall * BKE_mball_add(Main *bmain, const char *name)
Definition mball.cc:177
static void metaball_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int)
Definition mball.cc:68
static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
Definition mball.cc:130
void BKE_mball_translate(MetaBall *mb, const float offset[3])
Definition mball.cc:526
bool BKE_mball_minmax(const MetaBall *mb, float min[3], float max[3])
Definition mball.cc:459
static void mball_data_properties_copy(MetaBall *mb_dst, MetaBall *mb_src)
Definition mball.cc:306
bool BKE_mball_center_median(const MetaBall *mb, float r_cent[3])
Definition mball.cc:470
static void metaball_init_data(ID *id)
Definition mball.cc:59
static void metaball_foreach_id(ID *id, LibraryForeachIDData *data)
Definition mball.cc:94
IDTypeInfo IDType_ID_MB
Definition mball.cc:145
bool BKE_mball_is_basis(const Object *ob)
Definition mball.cc:230
static void metaball_free_data(ID *id)
Definition mball.cc:85
bool BKE_mball_select_swap(MetaBall *mb)
Definition mball.cc:602
bool BKE_mball_is_any_selected(const MetaBall *mb)
Definition mball.cc:274
bool BKE_mball_deselect_all_multi_ex(const Span< Base * > bases)
Definition mball.cc:590
void BKE_mball_transform(MetaBall *mb, const float mat[4][4], const bool do_props)
Definition mball.cc:500
bool BKE_mball_select_all(MetaBall *mb)
Definition mball.cc:555
bool BKE_mball_select_all_multi_ex(const Span< Base * > bases)
Definition mball.cc:567
int BKE_mball_select_count_multi(const Span< Base * > bases)
Definition mball.cc:544
MetaElem * BKE_mball_element_add(MetaBall *mb, const int type)
Definition mball.cc:183
bool BKE_mball_is_basis_for(const Object *ob1, const Object *ob2)
Definition mball.cc:269
static float metaball(PROCESS *process, float x, float y, float z)
#define min(a, b)
Definition sort.c:32
Definition DNA_ID.h:413
void * prev
Definition DNA_ID.h:416
void * next
Definition DNA_ID.h:416
char name[66]
Definition DNA_ID.h:425
void * first
ListBase objects
Definition BKE_main.hh:212
MetaElem * lastelem
ListBase elems
float rendersize
float wiresize
ListBase * editelems
char needs_flush_to_id
struct Material ** mat
float quat[4]
ObjectRuntimeHandle * runtime
struct Object * parent
#define N_(msgid)
uint8_t flag
Definition wm_window.cc:138