Blender  V3.3
mball.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
14 #include <ctype.h>
15 #include <float.h>
16 #include <math.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 
21 #include "MEM_guardedalloc.h"
22 
23 /* Allow using deprecated functionality for .blend file I/O. */
24 #define DNA_DEPRECATED_ALLOW
25 
26 #include "DNA_defaults.h"
27 #include "DNA_material_types.h"
28 #include "DNA_meta_types.h"
29 #include "DNA_object_types.h"
30 #include "DNA_scene_types.h"
31 
32 #include "BLI_blenlib.h"
33 #include "BLI_math.h"
34 #include "BLI_string_utils.h"
35 #include "BLI_utildefines.h"
36 
37 #include "BLT_translation.h"
38 
39 #include "BKE_main.h"
40 
41 #include "BKE_anim_data.h"
42 #include "BKE_curve.h"
43 #include "BKE_displist.h"
44 #include "BKE_idtype.h"
45 #include "BKE_lib_id.h"
46 #include "BKE_lib_query.h"
47 #include "BKE_material.h"
48 #include "BKE_mball.h"
49 #include "BKE_object.h"
50 #include "BKE_scene.h"
51 
52 #include "DEG_depsgraph.h"
53 
54 #include "BLO_read_write.h"
55 
56 static void metaball_init_data(ID *id)
57 {
58  MetaBall *metaball = (MetaBall *)id;
59 
61 
63 }
64 
65 static void metaball_copy_data(Main *UNUSED(bmain),
66  ID *id_dst,
67  const ID *id_src,
68  const int UNUSED(flag))
69 {
70  MetaBall *metaball_dst = (MetaBall *)id_dst;
71  const MetaBall *metaball_src = (const MetaBall *)id_src;
72 
73  BLI_duplicatelist(&metaball_dst->elems, &metaball_src->elems);
74 
75  metaball_dst->mat = MEM_dupallocN(metaball_src->mat);
76 
77  metaball_dst->editelems = NULL;
78  metaball_dst->lastelem = NULL;
79  metaball_dst->batch_cache = NULL;
80 }
81 
82 static void metaball_free_data(ID *id)
83 {
84  MetaBall *metaball = (MetaBall *)id;
85 
87 
88  MEM_SAFE_FREE(metaball->mat);
89 
90  BLI_freelistN(&metaball->elems);
91  if (metaball->disp.first) {
93  }
94 }
95 
97 {
98  MetaBall *metaball = (MetaBall *)id;
99  for (int i = 0; i < metaball->totcol; i++) {
101  }
102 }
103 
104 static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_address)
105 {
106  MetaBall *mb = (MetaBall *)id;
107 
108  /* Clean up, important in undo case to reduce false detection of changed datablocks. */
109  BLI_listbase_clear(&mb->disp);
110  mb->editelems = NULL;
111  /* Must always be cleared (meta's don't have their own edit-data). */
112  mb->needs_flush_to_id = 0;
113  mb->lastelem = NULL;
114  mb->batch_cache = NULL;
115 
116  /* write LibData */
117  BLO_write_id_struct(writer, MetaBall, id_address, &mb->id);
118  BKE_id_blend_write(writer, &mb->id);
119 
120  /* direct data */
121  BLO_write_pointer_array(writer, mb->totcol, mb->mat);
122  if (mb->adt) {
123  BKE_animdata_blend_write(writer, mb->adt);
124  }
125 
126  LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
127  BLO_write_struct(writer, MetaElem, ml);
128  }
129 }
130 
131 static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
132 {
133  MetaBall *mb = (MetaBall *)id;
134  BLO_read_data_address(reader, &mb->adt);
135  BKE_animdata_blend_read_data(reader, mb->adt);
136 
137  BLO_read_pointer_array(reader, (void **)&mb->mat);
138 
139  BLO_read_list(reader, &(mb->elems));
140 
141  BLI_listbase_clear(&mb->disp);
142  mb->editelems = NULL;
143  /* Must always be cleared (meta's don't have their own edit-data). */
144  mb->needs_flush_to_id = 0;
145  // mb->edit_elems.first = mb->edit_elems.last = NULL;
146  mb->lastelem = NULL;
147  mb->batch_cache = NULL;
148 }
149 
150 static void metaball_blend_read_lib(BlendLibReader *reader, ID *id)
151 {
152  MetaBall *mb = (MetaBall *)id;
153  for (int a = 0; a < mb->totcol; a++) {
154  BLO_read_id_address(reader, mb->id.lib, &mb->mat[a]);
155  }
156 
157  BLO_read_id_address(reader, mb->id.lib, &mb->ipo); // XXX deprecated - old animation system
158 }
159 
160 static void metaball_blend_read_expand(BlendExpander *expander, ID *id)
161 {
162  MetaBall *mb = (MetaBall *)id;
163  for (int a = 0; a < mb->totcol; a++) {
164  BLO_expand(expander, mb->mat[a]);
165  }
166 }
167 
169  .id_code = ID_MB,
170  .id_filter = FILTER_ID_MB,
171  .main_listbase_index = INDEX_ID_MB,
172  .struct_size = sizeof(MetaBall),
173  .name = "Metaball",
174  .name_plural = "metaballs",
175  .translation_context = BLT_I18NCONTEXT_ID_METABALL,
177  .asset_type_info = NULL,
178 
180  .copy_data = metaball_copy_data,
181  .free_data = metaball_free_data,
182  .make_local = NULL,
183  .foreach_id = metaball_foreach_id,
184  .foreach_cache = NULL,
185  .foreach_path = NULL,
186  .owner_get = NULL,
187 
188  .blend_write = metaball_blend_write,
189  .blend_read_data = metaball_blend_read_data,
190  .blend_read_lib = metaball_blend_read_lib,
191  .blend_read_expand = metaball_blend_read_expand,
192 
193  .blend_read_undo_preserve = NULL,
194 
195  .lib_override_apply_post = NULL,
196 };
197 
198 /* Functions */
199 
200 MetaBall *BKE_mball_add(Main *bmain, const char *name)
201 {
202  MetaBall *mb;
203 
204  mb = BKE_id_new(bmain, ID_MB, name);
205 
206  return mb;
207 }
208 
210 {
211  MetaElem *ml = MEM_callocN(sizeof(MetaElem), "metaelem");
212 
213  unit_qt(ml->quat);
214 
215  ml->rad = 2.0;
216  ml->s = 2.0;
217  ml->flag = MB_SCALE_RAD;
218 
219  switch (type) {
220  case MB_BALL:
221  ml->type = MB_BALL;
222  ml->expx = ml->expy = ml->expz = 1.0;
223 
224  break;
225  case MB_TUBE:
226  ml->type = MB_TUBE;
227  ml->expx = ml->expy = ml->expz = 1.0;
228 
229  break;
230  case MB_PLANE:
231  ml->type = MB_PLANE;
232  ml->expx = ml->expy = ml->expz = 1.0;
233 
234  break;
235  case MB_ELIPSOID:
236  ml->type = MB_ELIPSOID;
237  ml->expx = 1.2f;
238  ml->expy = 0.8f;
239  ml->expz = 1.0;
240 
241  break;
242  case MB_CUBE:
243  ml->type = MB_CUBE;
244  ml->expx = ml->expy = ml->expz = 1.0;
245 
246  break;
247  default:
248  break;
249  }
250 
251  BLI_addtail(&mb->elems, ml);
252 
253  return ml;
254 }
256 {
257  DispList *dl;
258  BoundBox *bb;
259  float *data, min[3], max[3] /*, loc[3], size[3] */;
260  int tot;
261  bool do_it = false;
262 
263  if (ob->runtime.bb == NULL) {
264  ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "mb boundbox");
265  }
266  bb = ob->runtime.bb;
267 
268  /* Weird one, this. */
269  // INIT_MINMAX(min, max);
270  (min)[0] = (min)[1] = (min)[2] = 1.0e30f;
271  (max)[0] = (max)[1] = (max)[2] = -1.0e30f;
272 
273  dl = ob->runtime.curve_cache->disp.first;
274  while (dl) {
275  tot = dl->nr;
276  if (tot) {
277  do_it = true;
278  }
279  data = dl->verts;
280  while (tot--) {
281  /* Also weird... but longer. From utildefines. */
283  data += 3;
284  }
285  dl = dl->next;
286  }
287 
288  if (!do_it) {
289  min[0] = min[1] = min[2] = -1.0f;
290  max[0] = max[1] = max[2] = 1.0f;
291  }
292 
294 
295  bb->flag &= ~BOUNDBOX_DIRTY;
296 }
297 
299 {
300  BLI_assert(ob->type == OB_MBALL);
301 
302  if (ob->runtime.bb != NULL && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
303  return ob->runtime.bb;
304  }
305 
306  /* This should always only be called with evaluated objects,
307  * but currently RNA is a problem here... */
308  if (ob->runtime.curve_cache != NULL) {
310  }
311 
312  return ob->runtime.bb;
313 }
314 
315 float *BKE_mball_make_orco(Object *ob, ListBase *dispbase)
316 {
317  BoundBox *bb;
318  DispList *dl;
319  float *data, *orco, *orcodata;
320  float loc[3], size[3];
321  int a;
322 
323  /* restore size and loc */
324  bb = ob->runtime.bb;
325  loc[0] = (bb->vec[0][0] + bb->vec[4][0]) / 2.0f;
326  size[0] = bb->vec[4][0] - loc[0];
327  loc[1] = (bb->vec[0][1] + bb->vec[2][1]) / 2.0f;
328  size[1] = bb->vec[2][1] - loc[1];
329  loc[2] = (bb->vec[0][2] + bb->vec[1][2]) / 2.0f;
330  size[2] = bb->vec[1][2] - loc[2];
331 
332  dl = dispbase->first;
333  orcodata = MEM_mallocN(sizeof(float[3]) * dl->nr, "MballOrco");
334 
335  data = dl->verts;
336  orco = orcodata;
337  a = dl->nr;
338  while (a--) {
339  orco[0] = (data[0] - loc[0]) / size[0];
340  orco[1] = (data[1] - loc[1]) / size[1];
341  orco[2] = (data[2] - loc[2]) / size[2];
342 
343  data += 3;
344  orco += 3;
345  }
346 
347  return orcodata;
348 }
349 
350 bool BKE_mball_is_basis(const Object *ob)
351 {
352  /* Meta-Ball Basis Notes from Blender-2.5x
353  * =======================================
354  *
355  * NOTE(@campbellbarton): This is a can of worms.
356  *
357  * This really needs a rewrite/refactor its totally broken in anything other than basic cases
358  * Multiple Scenes + Set Scenes & mixing meta-ball basis _should_ work but fails to update the
359  * depsgraph on rename and linking into scenes or removal of basis meta-ball.
360  * So take care when changing this code.
361  *
362  * Main idiot thing here is that the system returns #BKE_mball_basis_find()
363  * objects which fail a #BKE_mball_is_basis() test.
364  *
365  * Not only that but the depsgraph and their areas depend on this behavior,
366  * so making small fixes here isn't worth it. */
367 
368  /* Just a quick test. */
369  const int len = strlen(ob->id.name);
370  return (!isdigit(ob->id.name[len - 1]));
371 }
372 
373 bool BKE_mball_is_same_group(const Object *ob1, const Object *ob2)
374 {
375  int basis1nr, basis2nr;
376  char basis1name[MAX_ID_NAME], basis2name[MAX_ID_NAME];
377 
378  if (ob1->id.name[2] != ob2->id.name[2]) {
379  /* Quick return in case first char of both ID's names is not the same... */
380  return false;
381  }
382 
383  BLI_split_name_num(basis1name, &basis1nr, ob1->id.name + 2, '.');
384  BLI_split_name_num(basis2name, &basis2nr, ob2->id.name + 2, '.');
385 
386  return STREQ(basis1name, basis2name);
387 }
388 
389 bool BKE_mball_is_basis_for(const Object *ob1, const Object *ob2)
390 {
391  return BKE_mball_is_same_group(ob1, ob2) && BKE_mball_is_basis(ob1);
392 }
393 
395 {
396  for (const MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) {
397  if (ml->flag & SELECT) {
398  return true;
399  }
400  }
401  return false;
402 }
403 
404 bool BKE_mball_is_any_selected_multi(Base **bases, int bases_len)
405 {
406  for (uint base_index = 0; base_index < bases_len; base_index++) {
407  Object *obedit = bases[base_index]->object;
408  MetaBall *mb = (MetaBall *)obedit->data;
410  return true;
411  }
412  }
413  return false;
414 }
415 
417 {
418  for (const MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) {
419  if ((ml->flag & SELECT) == 0) {
420  return true;
421  }
422  }
423  return false;
424 }
425 
426 static void mball_data_properties_copy(MetaBall *mb_dst, MetaBall *mb_src)
427 {
428  mb_dst->wiresize = mb_src->wiresize;
429  mb_dst->rendersize = mb_src->rendersize;
430  mb_dst->thresh = mb_src->thresh;
431  mb_dst->flag = mb_src->flag;
432  DEG_id_tag_update(&mb_dst->id, 0);
433 }
434 
435 void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
436 {
454  for (Object *ob_src = bmain->objects.first; ob_src != NULL && !ID_IS_LINKED(ob_src);) {
455  if (ob_src->data != metaball_src) {
456  ob_src = ob_src->id.next;
457  continue;
458  }
459 
460  /* In this code we take advantage of two facts:
461  * - MetaBalls of the same family have the same basis name,
462  * - IDs are sorted by name in their Main listbase.
463  * So, all MetaBall objects of the same family are contiguous in bmain list (potentially mixed
464  * with non-meta-ball objects with same basis names).
465  *
466  * Using this, it is possible to process the whole set of meta-balls with a single loop on the
467  * whole list of Objects, though additionally going backward on part of the list in some cases.
468  */
469  Object *ob_iter = NULL;
470  int obactive_nr, ob_nr;
471  char obactive_name[MAX_ID_NAME], ob_name[MAX_ID_NAME];
472  BLI_split_name_num(obactive_name, &obactive_nr, ob_src->id.name + 2, '.');
473 
474  for (ob_iter = ob_src->id.prev; ob_iter != NULL; ob_iter = ob_iter->id.prev) {
475  if (ob_iter->id.name[2] != obactive_name[0]) {
476  break;
477  }
478  if (ob_iter->type != OB_MBALL || ob_iter->data == metaball_src) {
479  continue;
480  }
481  BLI_split_name_num(ob_name, &ob_nr, ob_iter->id.name + 2, '.');
482  if (!STREQ(obactive_name, ob_name)) {
483  break;
484  }
485 
486  mball_data_properties_copy(ob_iter->data, metaball_src);
487  }
488 
489  for (ob_iter = ob_src->id.next; ob_iter != NULL; ob_iter = ob_iter->id.next) {
490  if (ob_iter->id.name[2] != obactive_name[0] || ID_IS_LINKED(ob_iter)) {
491  break;
492  }
493  if (ob_iter->type != OB_MBALL || ob_iter->data == metaball_src) {
494  continue;
495  }
496  BLI_split_name_num(ob_name, &ob_nr, ob_iter->id.name + 2, '.');
497  if (!STREQ(obactive_name, ob_name)) {
498  break;
499  }
500 
501  mball_data_properties_copy(ob_iter->data, metaball_src);
502  }
503 
504  ob_src = ob_iter;
505  }
506 }
507 
509 {
510  Object *bob = object;
511  int basisnr, obnr;
512  char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
513 
514  BLI_split_name_num(basisname, &basisnr, object->id.name + 2, '.');
515 
516  LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
517  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
518  Object *ob = base->object;
519  if ((ob->type == OB_MBALL) && !(base->flag & BASE_FROM_DUPLI)) {
520  if (ob != bob) {
521  BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
522 
523  /* Object ob has to be in same "group" ... it means,
524  * that it has to have same base of its name. */
525  if (STREQ(obname, basisname)) {
526  if (obnr < basisnr) {
527  object = ob;
528  basisnr = obnr;
529  }
530  }
531  }
532  }
533  }
534  }
535 
536  return object;
537 }
538 
540  const MetaBall *mb, float min[3], float max[3], const float obmat[4][4], const short flag)
541 {
542  const float scale = obmat ? mat4_to_scale(obmat) : 1.0f;
543  bool changed = false;
544  float centroid[3], vec[3];
545 
546  INIT_MINMAX(min, max);
547 
548  LISTBASE_FOREACH (const MetaElem *, ml, &mb->elems) {
549  if ((ml->flag & flag) == flag) {
550  const float scale_mb = (ml->rad * 0.5f) * scale;
551 
552  if (obmat) {
553  mul_v3_m4v3(centroid, obmat, &ml->x);
554  }
555  else {
556  copy_v3_v3(centroid, &ml->x);
557  }
558 
559  /* TODO(campbell): non circle shapes cubes etc, probably nobody notices. */
560  for (int i = -1; i != 3; i += 2) {
561  copy_v3_v3(vec, centroid);
562  add_v3_fl(vec, scale_mb * i);
563  minmax_v3v3_v3(min, max, vec);
564  }
565  changed = true;
566  }
567  }
568 
569  return changed;
570 }
571 
572 bool BKE_mball_minmax(const MetaBall *mb, float min[3], float max[3])
573 {
574  INIT_MINMAX(min, max);
575 
576  LISTBASE_FOREACH (const MetaElem *, ml, &mb->elems) {
577  minmax_v3v3_v3(min, max, &ml->x);
578  }
579 
580  return (BLI_listbase_is_empty(&mb->elems) == false);
581 }
582 
583 bool BKE_mball_center_median(const MetaBall *mb, float r_cent[3])
584 {
585  int total = 0;
586 
587  zero_v3(r_cent);
588 
589  LISTBASE_FOREACH (const MetaElem *, ml, &mb->elems) {
590  add_v3_v3(r_cent, &ml->x);
591  total++;
592  }
593 
594  if (total) {
595  mul_v3_fl(r_cent, 1.0f / (float)total);
596  }
597 
598  return (total != 0);
599 }
600 
601 bool BKE_mball_center_bounds(const MetaBall *mb, float r_cent[3])
602 {
603  float min[3], max[3];
604 
605  if (BKE_mball_minmax(mb, min, max)) {
606  mid_v3_v3v3(r_cent, min, max);
607  return true;
608  }
609 
610  return false;
611 }
612 
613 void BKE_mball_transform(MetaBall *mb, const float mat[4][4], const bool do_props)
614 {
615  float quat[4];
616  const float scale = mat4_to_scale(mat);
617  const float scale_sqrt = sqrtf(scale);
618 
619  mat4_to_quat(quat, mat);
620 
621  LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
622  mul_m4_v3(mat, &ml->x);
623  mul_qt_qtqt(ml->quat, quat, ml->quat);
624 
625  if (do_props) {
626  ml->rad *= scale;
627  /* hrmf, probably elems shouldn't be
628  * treating scale differently - campbell */
629  if (!MB_TYPE_SIZE_SQUARED(ml->type)) {
630  mul_v3_fl(&ml->expx, scale);
631  }
632  else {
633  mul_v3_fl(&ml->expx, scale_sqrt);
634  }
635  }
636  }
637 }
638 
639 void BKE_mball_translate(MetaBall *mb, const float offset[3])
640 {
641  LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
642  add_v3_v3(&ml->x, offset);
643  }
644 }
645 
647 {
648  int sel = 0;
649  LISTBASE_FOREACH (const MetaElem *, ml, mb->editelems) {
650  if (ml->flag & SELECT) {
651  sel++;
652  }
653  }
654  return sel;
655 }
656 
657 int BKE_mball_select_count_multi(Base **bases, int bases_len)
658 {
659  int sel = 0;
660  for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
661  const Object *obedit = bases[ob_index]->object;
662  const MetaBall *mb = (MetaBall *)obedit->data;
663  sel += BKE_mball_select_count(mb);
664  }
665  return sel;
666 }
667 
669 {
670  bool changed = false;
671  LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
672  if ((ml->flag & SELECT) == 0) {
673  ml->flag |= SELECT;
674  changed = true;
675  }
676  }
677  return changed;
678 }
679 
680 bool BKE_mball_select_all_multi_ex(Base **bases, int bases_len)
681 {
682  bool changed_multi = false;
683  for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
684  Object *obedit = bases[ob_index]->object;
685  MetaBall *mb = obedit->data;
686  changed_multi |= BKE_mball_select_all(mb);
687  }
688  return changed_multi;
689 }
690 
692 {
693  bool changed = false;
694  LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
695  if ((ml->flag & SELECT) != 0) {
696  ml->flag &= ~SELECT;
697  changed = true;
698  }
699  }
700  return changed;
701 }
702 
703 bool BKE_mball_deselect_all_multi_ex(Base **bases, int bases_len)
704 {
705  bool changed_multi = false;
706  for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
707  Object *obedit = bases[ob_index]->object;
708  MetaBall *mb = obedit->data;
709  changed_multi |= BKE_mball_deselect_all(mb);
711  }
712  return changed_multi;
713 }
714 
716 {
717  bool changed = false;
718  LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
719  ml->flag ^= SELECT;
720  changed = true;
721  }
722  return changed;
723 }
724 
725 bool BKE_mball_select_swap_multi_ex(Base **bases, int bases_len)
726 {
727  bool changed_multi = false;
728  for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
729  Object *obedit = bases[ob_index]->object;
730  MetaBall *mb = (MetaBall *)obedit->data;
731  changed_multi |= BKE_mball_select_swap(mb);
732  }
733  return changed_multi;
734 }
735 
736 /* **** Depsgraph evaluation **** */
737 
738 /* Draw Engine */
739 
742 
744 {
745  if (mb->batch_cache) {
747  }
748 }
750 {
751  if (mb->batch_cache) {
753  }
754 }
void BKE_animdata_blend_read_data(struct BlendDataReader *reader, struct AnimData *adt)
Definition: anim_data.c:1443
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1421
display list (or rather multi purpose list) stuff.
void BKE_displist_free(struct ListBase *lb)
Definition: displist.cc:69
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition: BKE_idtype.h:39
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2008
void * BKE_id_new(struct Main *bmain, short type, const char *name)
Definition: lib_id.c:1159
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
General operations, lookup, etc. for materials.
General operations, lookup, etc. for blender objects.
void BKE_boundbox_init_from_minmax(struct BoundBox *bb, const float min[3], const float max[3])
Definition: object.cc:3645
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2185
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void unit_qt(float q[4])
Definition: math_rotation.c:27
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:46
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])
Definition: math_vector.c:867
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])
Definition: math_vector.c:237
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
size_t BLI_split_name_num(char *left, int *nr, const char *name, char delim)
Definition: string_utils.c:25
unsigned int uint
Definition: BLI_sys_types.h:67
#define INIT_MINMAX(min, max)
#define UNUSED(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5172
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
Definition: readfile.c:5245
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
Definition: writefile.c:1591
#define BLT_I18NCONTEXT_ID_METABALL
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SELECT
Definition: DNA_ID.h:818
@ INDEX_ID_MB
Definition: DNA_ID.h:1028
#define FILTER_ID_MB
Definition: DNA_ID.h:911
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define MAX_ID_NAME
Definition: DNA_ID.h:337
@ ID_MB
Definition: DNA_ID_enums.h:50
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ BASE_FROM_DUPLI
#define MB_BALL
#define MB_TUBE
#define MB_TYPE_SIZE_SQUARED(type)
#define MB_ELIPSOID
#define MB_SCALE_RAD
struct MetaBall MetaBall
#define MB_PLANE
#define MB_CUBE
Object is a sort of wrapper for general info.
@ OB_MBALL
@ BOUNDBOX_DIRTY
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void init_data(ModifierData *md)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define SELECT
Scene scene
SyclQueue void void size_t num_bytes void
int len
Definition: draw_manager.c:108
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: mball.c:104
bool BKE_mball_select_all_multi_ex(Base **bases, int bases_len)
Definition: mball.c:680
bool BKE_mball_is_same_group(const Object *ob1, const Object *ob2)
Definition: mball.c:373
int BKE_mball_select_count(const MetaBall *mb)
Definition: mball.c:646
void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
Definition: mball.c:435
bool BKE_mball_select_swap_multi_ex(Base **bases, int bases_len)
Definition: mball.c:725
void(* BKE_mball_batch_cache_dirty_tag_cb)(MetaBall *mb, int mode)
Definition: mball.c:740
bool BKE_mball_deselect_all(MetaBall *mb)
Definition: mball.c:691
float * BKE_mball_make_orco(Object *ob, ListBase *dispbase)
Definition: mball.c:315
BoundBox * BKE_mball_boundbox_get(Object *ob)
Definition: mball.c:298
MetaBall * BKE_mball_add(Main *bmain, const char *name)
Definition: mball.c:200
static void metaball_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int UNUSED(flag))
Definition: mball.c:65
bool BKE_mball_minmax_ex(const MetaBall *mb, float min[3], float max[3], const float obmat[4][4], const short flag)
Definition: mball.c:539
bool BKE_mball_center_bounds(const MetaBall *mb, float r_cent[3])
Definition: mball.c:601
int BKE_mball_select_count_multi(Base **bases, int bases_len)
Definition: mball.c:657
bool BKE_mball_is_any_unselected(const MetaBall *mb)
Definition: mball.c:416
void BKE_mball_texspace_calc(Object *ob)
Definition: mball.c:255
static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
Definition: mball.c:131
void BKE_mball_translate(MetaBall *mb, const float offset[3])
Definition: mball.c:639
bool BKE_mball_is_any_selected_multi(Base **bases, int bases_len)
Definition: mball.c:404
bool BKE_mball_minmax(const MetaBall *mb, float min[3], float max[3])
Definition: mball.c:572
static void metaball_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: mball.c:150
static void mball_data_properties_copy(MetaBall *mb_dst, MetaBall *mb_src)
Definition: mball.c:426
bool BKE_mball_center_median(const MetaBall *mb, float r_cent[3])
Definition: mball.c:583
void BKE_mball_batch_cache_free(MetaBall *mb)
Definition: mball.c:749
static void metaball_init_data(ID *id)
Definition: mball.c:56
bool BKE_mball_deselect_all_multi_ex(Base **bases, int bases_len)
Definition: mball.c:703
static void metaball_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: mball.c:96
void(* BKE_mball_batch_cache_free_cb)(MetaBall *mb)
Definition: mball.c:741
IDTypeInfo IDType_ID_MB
Definition: mball.c:168
bool BKE_mball_is_basis(const Object *ob)
Definition: mball.c:350
static void metaball_free_data(ID *id)
Definition: mball.c:82
bool BKE_mball_select_swap(MetaBall *mb)
Definition: mball.c:715
bool BKE_mball_is_any_selected(const MetaBall *mb)
Definition: mball.c:394
Object * BKE_mball_basis_find(Scene *scene, Object *object)
Definition: mball.c:508
void BKE_mball_transform(MetaBall *mb, const float mat[4][4], const bool do_props)
Definition: mball.c:613
bool BKE_mball_select_all(MetaBall *mb)
Definition: mball.c:668
void BKE_mball_batch_cache_dirty_tag(MetaBall *mb, int mode)
Definition: mball.c:743
static void metaball_blend_read_expand(BlendExpander *expander, ID *id)
Definition: mball.c:160
MetaElem * BKE_mball_element_add(MetaBall *mb, const int type)
Definition: mball.c:209
bool BKE_mball_is_basis_for(const Object *ob1, const Object *ob2)
Definition: mball.c:389
static float metaball(PROCESS *process, float x, float y, float z)
#define sqrtf(x)
Definition: metal/compat.h:243
static unsigned a[3]
Definition: RandGen.cpp:78
#define min(a, b)
Definition: sort.c:35
struct Object * object
float vec[8][3]
ListBase disp
Definition: BKE_curve.h:33
float * verts
Definition: BKE_displist.h:58
struct DispList * next
Definition: BKE_displist.h:54
short id_code
Definition: BKE_idtype.h:114
Definition: DNA_ID.h:368
struct Library * lib
Definition: DNA_ID.h:372
void * prev
Definition: DNA_ID.h:369
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase objects
Definition: BKE_main.h:170
MetaElem * lastelem
float thresh
ListBase elems
float rendersize
void * batch_cache
ListBase disp
short totcol
float wiresize
struct AnimData * adt
ListBase * editelems
char needs_flush_to_id
struct Material ** mat
float expy
short type
float expx
float expz
float quat[4]
short flag
struct CurveCache * curve_cache
struct BoundBox * bb
Object_Runtime runtime
void * data
ListBase view_layers
float max