Blender  V2.93
MOD_particleinstance.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_utildefines.h"
27 
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30 #include "BLI_rand.h"
31 #include "BLI_string.h"
32 
33 #include "BLT_translation.h"
34 
35 #include "DNA_defaults.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_meshdata_types.h"
38 #include "DNA_screen_types.h"
39 
40 #include "BKE_context.h"
41 #include "BKE_effect.h"
42 #include "BKE_lattice.h"
43 #include "BKE_lib_query.h"
44 #include "BKE_mesh.h"
45 #include "BKE_modifier.h"
46 #include "BKE_particle.h"
47 #include "BKE_pointcache.h"
48 #include "BKE_screen.h"
49 
50 #include "UI_interface.h"
51 #include "UI_resources.h"
52 
53 #include "RNA_access.h"
54 
55 #include "DEG_depsgraph_build.h"
56 #include "DEG_depsgraph_query.h"
57 
58 #include "MOD_modifiertypes.h"
59 #include "MOD_ui_common.h"
60 
61 static void initData(ModifierData *md)
62 {
64 
65  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(pimd, modifier));
66 
68 }
69 
70 static void requiredDataMask(Object *UNUSED(ob),
71  ModifierData *md,
72  CustomData_MeshMasks *r_cddata_masks)
73 {
75 
76  if (pimd->index_layer_name[0] != '\0' || pimd->value_layer_name[0] != '\0') {
77  r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
78  }
79 }
80 
81 static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRenderParams)
82 {
84  ParticleSystem *psys;
85  ModifierData *ob_md;
86 
87  /* The object type check is only needed here in case we have a placeholder
88  * object assigned (because the library containing the mesh is missing).
89  *
90  * In other cases it should be impossible to have a type mismatch.
91  */
92  if (!pimd->ob || pimd->ob->type != OB_MESH) {
93  return true;
94  }
95 
96  psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
97  if (psys == NULL) {
98  return true;
99  }
100 
101  /* If the psys modifier is disabled we cannot use its data.
102  * First look up the psys modifier from the object, then check if it is enabled.
103  */
104  for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) {
105  if (ob_md->type == eModifierType_ParticleSystem) {
107  if (psmd->psys == psys) {
108  int required_mode;
109 
110  if (useRenderParams) {
111  required_mode = eModifierMode_Render;
112  }
113  else {
114  required_mode = eModifierMode_Realtime;
115  }
116 
117  if (!BKE_modifier_is_enabled(scene, ob_md, required_mode)) {
118  return true;
119  }
120 
121  break;
122  }
123  }
124  }
125 
126  return false;
127 }
128 
130 {
132  if (pimd->ob != NULL) {
134  ctx->node, pimd->ob, DEG_OB_COMP_TRANSFORM, "Particle Instance Modifier");
136  ctx->node, pimd->ob, DEG_OB_COMP_GEOMETRY, "Particle Instance Modifier");
137  }
138 }
139 
140 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
141 {
143 
144  walk(userData, ob, (ID **)&pimd->ob, IDWALK_CB_NOP);
145 }
146 
148 {
149  const bool between = (psys->part->childtype == PART_CHILD_FACES);
150  ParticleData *pa;
151  int totpart, randp, minp, maxp;
152 
153  if (p >= psys->totpart) {
154  ChildParticle *cpa = psys->child + (p - psys->totpart);
155  pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
156  }
157  else {
158  pa = psys->particles + p;
159  }
160 
161  if (pa) {
162  if (pa->alive == PARS_UNBORN && (pimd->flag & eParticleInstanceFlag_Unborn) == 0) {
163  return true;
164  }
165  if (pa->alive == PARS_ALIVE && (pimd->flag & eParticleInstanceFlag_Alive) == 0) {
166  return true;
167  }
168  if (pa->alive == PARS_DEAD && (pimd->flag & eParticleInstanceFlag_Dead) == 0) {
169  return true;
170  }
171  if (pa->flag & (PARS_UNEXIST | PARS_NO_DISP)) {
172  return true;
173  }
174  }
175 
176  if (pimd->particle_amount == 1.0f) {
177  /* Early output, all particles are to be instanced. */
178  return false;
179  }
180 
181  /* Randomly skip particles based on desired amount of visible particles. */
182 
183  totpart = psys->totpart + psys->totchild;
184 
185  /* TODO make randomization optional? */
186  randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart;
187 
188  minp = (int)(totpart * pimd->particle_offset) % (totpart + 1);
189  maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1);
190 
191  if (maxp > minp) {
192  return randp < minp || randp >= maxp;
193  }
194  if (maxp < minp) {
195  return randp < minp && randp >= maxp;
196  }
197 
198  return true;
199 
200  return false;
201 }
202 
203 static void store_float_in_vcol(MLoopCol *vcol, float float_value)
204 {
205  const uchar value = unit_float_to_uchar_clamp(float_value);
206  vcol->r = vcol->g = vcol->b = value;
207  vcol->a = 1.0f;
208 }
209 
211 {
212  Mesh *result;
216  ParticleSystem *psys = NULL;
217  ParticleData *pa = NULL;
218  MPoly *mpoly, *orig_mpoly;
219  MLoop *mloop, *orig_mloop;
220  MVert *mvert, *orig_mvert;
221  int totvert, totpoly, totloop, totedge;
222  int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start;
223  int k, p, p_skip;
224  short track = ctx->object->trackflag % 3, trackneg, axis = pimd->axis;
225  float max_co = 0.0, min_co = 0.0, temp_co[3];
226  float *size = NULL;
227  float spacemat[4][4];
228  const bool use_parents = pimd->flag & eParticleInstanceFlag_Parents;
229  const bool use_children = pimd->flag & eParticleInstanceFlag_Children;
230  bool between;
231 
232  trackneg = ((ctx->object->trackflag > 2) ? 1 : 0);
233 
234  if (pimd->ob == ctx->object) {
235  pimd->ob = NULL;
236  return mesh;
237  }
238 
239  if (pimd->ob) {
240  psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
241  if (psys == NULL || psys->totpart == 0) {
242  return mesh;
243  }
244  }
245  else {
246  return mesh;
247  }
248 
249  part_start = use_parents ? 0 : psys->totpart;
250 
251  part_end = 0;
252  if (use_parents) {
253  part_end += psys->totpart;
254  }
255  if (use_children) {
256  part_end += psys->totchild;
257  }
258 
259  if (part_end == 0) {
260  return mesh;
261  }
262 
263  sim.depsgraph = ctx->depsgraph;
264  sim.scene = scene;
265  sim.ob = pimd->ob;
266  sim.psys = psys;
267  sim.psmd = psys_get_modifier(pimd->ob, psys);
268  between = (psys->part->childtype == PART_CHILD_FACES);
269 
270  if (pimd->flag & eParticleInstanceFlag_UseSize) {
271  float *si;
272  si = size = MEM_calloc_arrayN(part_end, sizeof(float), "particle size array");
273 
274  if (pimd->flag & eParticleInstanceFlag_Parents) {
275  for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++, si++) {
276  *si = pa->size;
277  }
278  }
279 
280  if (pimd->flag & eParticleInstanceFlag_Children) {
281  ChildParticle *cpa = psys->child;
282 
283  for (p = 0; p < psys->totchild; p++, cpa++, si++) {
284  *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
285  }
286  }
287  }
288 
289  switch (pimd->space) {
291  /* particle states are in world space already */
292  unit_m4(spacemat);
293  break;
295  /* get particle states in the particle object's local space */
296  invert_m4_m4(spacemat, pimd->ob->obmat);
297  break;
298  default:
299  /* should not happen */
300  BLI_assert(false);
301  break;
302  }
303 
304  totvert = mesh->totvert;
305  totpoly = mesh->totpoly;
306  totloop = mesh->totloop;
307  totedge = mesh->totedge;
308 
309  /* count particles */
310  maxvert = 0;
311  maxpoly = 0;
312  maxloop = 0;
313  maxedge = 0;
314 
315  for (p = part_start; p < part_end; p++) {
316  if (particle_skip(pimd, psys, p)) {
317  continue;
318  }
319 
320  maxvert += totvert;
321  maxpoly += totpoly;
322  maxloop += totloop;
323  maxedge += totedge;
324  }
325 
327 
328  if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
329  float min[3], max[3];
330  INIT_MINMAX(min, max);
332  min_co = min[track];
333  max_co = max[track];
334  }
335 
336  result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly);
337 
338  mvert = result->mvert;
339  orig_mvert = mesh->mvert;
340  mpoly = result->mpoly;
341  orig_mpoly = mesh->mpoly;
342  mloop = result->mloop;
343  orig_mloop = mesh->mloop;
344 
345  MLoopCol *mloopcols_index = CustomData_get_layer_named(
346  &result->ldata, CD_MLOOPCOL, pimd->index_layer_name);
347  MLoopCol *mloopcols_value = CustomData_get_layer_named(
348  &result->ldata, CD_MLOOPCOL, pimd->value_layer_name);
349  int *vert_part_index = NULL;
350  float *vert_part_value = NULL;
351  if (mloopcols_index != NULL) {
352  vert_part_index = MEM_calloc_arrayN(maxvert, sizeof(int), "vertex part index array");
353  }
354  if (mloopcols_value) {
355  vert_part_value = MEM_calloc_arrayN(maxvert, sizeof(float), "vertex part value array");
356  }
357 
358  for (p = part_start, p_skip = 0; p < part_end; p++) {
359  float prev_dir[3];
360  float frame[4]; /* frame orientation quaternion */
361  float p_random = psys_frand(psys, 77091 + 283 * p);
362 
363  /* skip particle? */
364  if (particle_skip(pimd, psys, p)) {
365  continue;
366  }
367 
368  /* set vertices coordinates */
369  for (k = 0; k < totvert; k++) {
371  MVert *inMV;
372  int vindex = p_skip * totvert + k;
373  MVert *mv = mvert + vindex;
374 
375  inMV = orig_mvert + k;
376  CustomData_copy_data(&mesh->vdata, &result->vdata, k, p_skip * totvert + k, 1);
377  *mv = *inMV;
378 
379  if (vert_part_index != NULL) {
380  vert_part_index[vindex] = p;
381  }
382  if (vert_part_value != NULL) {
383  vert_part_value[vindex] = p_random;
384  }
385 
386  /*change orientation based on object trackflag*/
387  copy_v3_v3(temp_co, mv->co);
388  mv->co[axis] = temp_co[track];
389  mv->co[(axis + 1) % 3] = temp_co[(track + 1) % 3];
390  mv->co[(axis + 2) % 3] = temp_co[(track + 2) % 3];
391 
392  /* get particle state */
393  if ((psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) &&
394  (pimd->flag & eParticleInstanceFlag_Path)) {
395  float ran = 0.0f;
396  if (pimd->random_position != 0.0f) {
397  ran = pimd->random_position * BLI_hash_frand(psys->seed + p);
398  }
399 
401  state.time = pimd->position * (1.0f - ran);
402  }
403  else {
404  state.time = (mv->co[axis] - min_co) / (max_co - min_co) * pimd->position * (1.0f - ran);
405 
406  if (trackneg) {
407  state.time = 1.0f - state.time;
408  }
409 
410  mv->co[axis] = 0.0;
411  }
412 
413  psys_get_particle_on_path(&sim, p, &state, 1);
414 
415  normalize_v3(state.vel);
416 
417  /* Incrementally Rotating Frame (Bishop Frame) */
418  if (k == 0) {
419  float hairmat[4][4];
420  float mat[3][3];
421 
422  if (p < psys->totpart) {
423  pa = psys->particles + p;
424  }
425  else {
426  ChildParticle *cpa = psys->child + (p - psys->totpart);
427  pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
428  }
429  psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
430  copy_m3_m4(mat, hairmat);
431  /* to quaternion */
432  mat3_to_quat(frame, mat);
433 
434  if (pimd->rotation > 0.0f || pimd->random_rotation > 0.0f) {
435  float angle = 2.0f * M_PI *
436  (pimd->rotation +
437  pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
438  const float eul[3] = {0.0f, 0.0f, angle};
439  float rot[4];
440 
441  eul_to_quat(rot, eul);
442  mul_qt_qtqt(frame, frame, rot);
443  }
444 
445  /* note: direction is same as normal vector currently,
446  * but best to keep this separate so the frame can be
447  * rotated later if necessary
448  */
449  copy_v3_v3(prev_dir, state.vel);
450  }
451  else {
452  float rot[4];
453 
454  /* incrementally rotate along bend direction */
455  rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
456  mul_qt_qtqt(frame, rot, frame);
457 
458  copy_v3_v3(prev_dir, state.vel);
459  }
460 
461  copy_qt_qt(state.rot, frame);
462 #if 0
463  /* Absolute Frame (Frenet Frame) */
464  if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
465  unit_qt(state.rot);
466  }
467  else {
468  float cross[3];
469  float temp[3] = {0.0f, 0.0f, 0.0f};
470  temp[axis] = 1.0f;
471 
472  cross_v3_v3v3(cross, temp, state.vel);
473 
474  /* state.vel[axis] is the only component surviving from a dot product with the axis */
475  axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
476  }
477 #endif
478  }
479  else {
480  state.time = -1.0;
481  psys_get_particle_state(&sim, p, &state, 1);
482  }
483 
484  mul_qt_v3(state.rot, mv->co);
485  if (pimd->flag & eParticleInstanceFlag_UseSize) {
486  mul_v3_fl(mv->co, size[p]);
487  }
488  add_v3_v3(mv->co, state.co);
489 
490  mul_m4_v3(spacemat, mv->co);
491  }
492 
493  /* create edges and adjust edge vertex indices*/
494  CustomData_copy_data(&mesh->edata, &result->edata, 0, p_skip * totedge, totedge);
495  MEdge *me = &result->medge[p_skip * totedge];
496  for (k = 0; k < totedge; k++, me++) {
497  me->v1 += p_skip * totvert;
498  me->v2 += p_skip * totvert;
499  }
500 
501  /* create polys and loops */
502  for (k = 0; k < totpoly; k++) {
503 
504  MPoly *inMP = orig_mpoly + k;
505  MPoly *mp = mpoly + p_skip * totpoly + k;
506 
507  CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1);
508  *mp = *inMP;
509  mp->loopstart += p_skip * totloop;
510 
511  {
512  MLoop *inML = orig_mloop + inMP->loopstart;
513  MLoop *ml = mloop + mp->loopstart;
514  int j = mp->totloop;
515 
516  CustomData_copy_data(&mesh->ldata, &result->ldata, inMP->loopstart, mp->loopstart, j);
517  for (; j; j--, ml++, inML++) {
518  ml->v = inML->v + (p_skip * totvert);
519  ml->e = inML->e + (p_skip * totedge);
520  const int ml_index = (ml - mloop);
521  if (mloopcols_index != NULL) {
522  const int part_index = vert_part_index[ml->v];
523  store_float_in_vcol(&mloopcols_index[ml_index],
524  (float)part_index / (float)(psys->totpart - 1));
525  }
526  if (mloopcols_value != NULL) {
527  const float part_value = vert_part_value[ml->v];
528  store_float_in_vcol(&mloopcols_value[ml_index], part_value);
529  }
530  }
531  }
532  }
533  p_skip++;
534  }
535 
536  if (psys->lattice_deform_data) {
538  psys->lattice_deform_data = NULL;
539  }
540 
541  if (size) {
542  MEM_freeN(size);
543  }
544 
545  MEM_SAFE_FREE(vert_part_index);
546  MEM_SAFE_FREE(vert_part_value);
547 
548  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
549 
550  return result;
551 }
552 
553 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
554 {
555  uiLayout *row;
556  uiLayout *layout = panel->layout;
558 
559  PointerRNA ob_ptr;
561 
562  PointerRNA particle_obj_ptr = RNA_pointer_get(ptr, "object");
563 
564  uiLayoutSetPropSep(layout, true);
565 
566  uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
567  if (!RNA_pointer_is_null(&particle_obj_ptr)) {
568  uiItemPointerR(layout,
569  ptr,
570  "particle_system",
571  &particle_obj_ptr,
572  "particle_systems",
573  "Particle System",
574  ICON_NONE);
575  }
576  else {
577  uiItemR(layout, ptr, "particle_system_index", 0, IFACE_("Particle System"), ICON_NONE);
578  }
579 
580  uiItemS(layout);
581 
582  row = uiLayoutRowWithHeading(layout, true, IFACE_("Create Instances"));
583  uiItemR(row, ptr, "use_normal", toggles_flag, NULL, ICON_NONE);
584  uiItemR(row, ptr, "use_children", toggles_flag, NULL, ICON_NONE);
585  uiItemR(row, ptr, "use_size", toggles_flag, NULL, ICON_NONE);
586 
587  row = uiLayoutRowWithHeading(layout, true, IFACE_("Show"));
588  uiItemR(row, ptr, "show_alive", toggles_flag, NULL, ICON_NONE);
589  uiItemR(row, ptr, "show_dead", toggles_flag, NULL, ICON_NONE);
590  uiItemR(row, ptr, "show_unborn", toggles_flag, NULL, ICON_NONE);
591 
592  uiItemR(layout, ptr, "particle_amount", 0, IFACE_("Amount"), ICON_NONE);
593  uiItemR(layout, ptr, "particle_offset", 0, IFACE_("Offset"), ICON_NONE);
594 
595  uiItemS(layout);
596 
597  uiItemR(layout, ptr, "space", 0, IFACE_("Coordinate Space"), ICON_NONE);
598  row = uiLayoutRow(layout, true);
599  uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
600 
601  modifier_panel_end(layout, ptr);
602 }
603 
604 static void path_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
605 {
606  uiLayout *layout = panel->layout;
607 
609 
610  uiItemR(layout, ptr, "use_path", 0, IFACE_("Create Along Paths"), ICON_NONE);
611 }
612 
613 static void path_panel_draw(const bContext *UNUSED(C), Panel *panel)
614 {
615  uiLayout *col;
616  uiLayout *layout = panel->layout;
617 
618  PointerRNA ob_ptr;
620 
621  uiLayoutSetPropSep(layout, true);
622 
623  uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_path"));
624 
625  col = uiLayoutColumn(layout, true);
626  uiItemR(col, ptr, "position", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
627  uiItemR(col, ptr, "random_position", UI_ITEM_R_SLIDER, IFACE_("Random"), ICON_NONE);
628  col = uiLayoutColumn(layout, true);
629  uiItemR(col, ptr, "rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
630  uiItemR(col, ptr, "random_rotation", UI_ITEM_R_SLIDER, IFACE_("Random"), ICON_NONE);
631 
632  uiItemR(layout, ptr, "use_preserve_shape", 0, NULL, ICON_NONE);
633 }
634 
635 static void layers_panel_draw(const bContext *UNUSED(C), Panel *panel)
636 {
637  uiLayout *col;
638  uiLayout *layout = panel->layout;
639 
640  PointerRNA ob_ptr;
642 
643  PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data");
644 
645  uiLayoutSetPropSep(layout, true);
646 
647  col = uiLayoutColumn(layout, false);
649  col, ptr, "index_layer_name", &obj_data_ptr, "vertex_colors", IFACE_("Index"), ICON_NONE);
651  col, ptr, "value_layer_name", &obj_data_ptr, "vertex_colors", IFACE_("Value"), ICON_NONE);
652 }
653 
654 static void panelRegister(ARegionType *region_type)
655 {
656  PanelType *panel_type = modifier_panel_register(
659  region_type, "paths", "", path_panel_draw_header, path_panel_draw, panel_type);
660  modifier_subpanel_register(region_type, "layers", "Layers", NULL, layers_panel_draw, panel_type);
661 }
662 
664  /* name */ "ParticleInstance",
665  /* structName */ "ParticleInstanceModifierData",
666  /* structSize */ sizeof(ParticleInstanceModifierData),
667  /* srna */ &RNA_ParticleInstanceModifier,
671  /* icon */ ICON_MOD_PARTICLE_INSTANCE,
672 
673  /* copyData */ BKE_modifier_copydata_generic,
674 
675  /* deformVerts */ NULL,
676  /* deformMatrices */ NULL,
677  /* deformVertsEM */ NULL,
678  /* deformMatricesEM */ NULL,
679  /* modifyMesh */ modifyMesh,
680  /* modifyHair */ NULL,
681  /* modifyGeometrySet */ NULL,
682  /* modifyVolume */ NULL,
683 
684  /* initData */ initData,
685  /* requiredDataMask */ requiredDataMask,
686  /* freeData */ NULL,
687  /* isDisabled */ isDisabled,
688  /* updateDepsgraph */ updateDepsgraph,
689  /* dependsOnTime */ NULL,
690  /* dependsOnNormals */ NULL,
691  /* foreachIDLink */ foreachIDLink,
692  /* foreachTexLink */ NULL,
693  /* freeRuntimeData */ NULL,
694  /* panelRegister */ panelRegister,
695  /* blendWrite */ NULL,
696  /* blendRead */ NULL,
697 };
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
Definition: customdata.c:3217
void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count)
void BKE_lattice_deform_data_destroy(struct LatticeDeformData *lattice_deform_data)
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:47
struct Mesh * BKE_mesh_new_nomain_from_template(const struct Mesh *me_src, int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
bool BKE_mesh_minmax(const struct Mesh *me, float r_min[3], float r_max[3])
bool BKE_modifier_is_enabled(const struct Scene *scene, struct ModifierData *md, int required_mode)
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:120
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:82
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:92
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:83
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:80
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:61
struct LatticeDeformData * psys_create_lattice_deform_data(struct ParticleSimulationData *sim)
Definition: particle.c:696
void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, const bool vel)
Definition: particle.c:4585
void psys_mat_hair_to_global(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
Definition: particle.c:3909
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always)
Definition: particle.c:4854
struct ParticleSystemModifierData * psys_get_modifier(struct Object *ob, struct ParticleSystem *psys)
Definition: particle.c:2201
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time)
BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
Definition: BKE_particle.h:266
#define BLI_assert(a)
Definition: BLI_assert.h:58
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float saacos(float fac)
#define M_PI
Definition: BLI_math_base.h:38
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
void mat3_to_quat(float q[4], const float mat[3][3])
void axis_angle_to_quat(float r[4], const float axis[3], const float angle)
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:97
void unit_qt(float q[4])
Definition: math_rotation.c:46
void eul_to_quat(float quat[4], const float eul[3])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:65
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:52
MINLINE float normalize_v3(float r[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
Random number functions.
float BLI_hash_frand(unsigned int seed) ATTR_WARN_UNUSED_RESULT
Definition: rand.cc:200
unsigned char uchar
Definition: BLI_sys_types.h:86
#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 IFACE_(msgid)
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define CD_MASK_NORMAL
#define CD_MASK_MLOOPCOL
@ CD_MLOOPCOL
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
@ eModifierMode_Render
@ eModifierMode_Realtime
@ eParticleInstanceFlag_Parents
@ eParticleInstanceFlag_Alive
@ eParticleInstanceFlag_Dead
@ eParticleInstanceFlag_Children
@ eParticleInstanceFlag_Unborn
@ eParticleInstanceFlag_Path
@ eParticleInstanceFlag_UseSize
@ eParticleInstanceFlag_KeepShape
struct ParticleInstanceModifierData ParticleInstanceModifierData
@ eModifierType_ParticleSystem
@ eModifierType_ParticleInstance
@ eParticleInstanceSpace_World
@ eParticleInstanceSpace_Local
@ OB_MESH
#define PARS_UNEXIST
#define PARS_NO_DISP
#define PSYS_KEYED
#define PART_CHILD_FACES
#define PARS_DEAD
#define PARS_ALIVE
#define PARS_UNBORN
#define PSYS_HAIR_DONE
#define PTCACHE_BAKED
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
ModifierTypeInfo modifierType_ParticleInstance
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRenderParams)
static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psys, int p)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static void store_float_in_vcol(MLoopCol *vcol, float float_value)
static void path_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void path_panel_draw(const bContext *UNUSED(C), Panel *panel)
static void panelRegister(ARegionType *region_type)
static void layers_panel_draw(const bContext *UNUSED(C), Panel *panel)
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
StructRNA RNA_ParticleInstanceModifier
#define C
Definition: RandGen.cpp:39
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
void uiLayoutSetActive(uiLayout *layout, bool active)
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_FORCE_BLANK_DECORATE
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_SLIDER
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Scene scene
#define rot(x, k)
uint col
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
static ulong state[N]
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
bool RNA_pointer_is_null(const PointerRNA *ptr)
Definition: rna_access.c:174
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
#define min(a, b)
Definition: sort.c:51
Definition: DNA_ID.h:273
void * first
Definition: DNA_listBase.h:47
unsigned int v1
unsigned int v2
unsigned char a
unsigned char b
unsigned char r
unsigned char g
unsigned int e
unsigned int v
struct CustomData pdata ldata
struct MVert * mvert
int totedge
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
struct ModifierData * next
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:153
struct Object * object
Definition: BKE_modifier.h:154
struct DepsNodeHandle * node
Definition: BKE_modifier.h:147
ListBase particlesystem
ListBase modifiers
float obmat[4][4]
short trackflag
struct uiLayout * layout
struct Depsgraph * depsgraph
Definition: BKE_particle.h:87
struct ParticleSystemModifierData * psmd
Definition: BKE_particle.h:91
struct Scene * scene
Definition: BKE_particle.h:88
struct ParticleSystem * psys
Definition: BKE_particle.h:90
struct Object * ob
Definition: BKE_particle.h:89
struct ParticleSystem * psys
ChildParticle * child
ParticleData * particles
ParticleSettings * part
struct PointCache * pointcache
struct LatticeDeformData * lattice_deform_data
float max
__forceinline avxf cross(const avxf &a, const avxf &b)
Definition: util_avxf.h:119
PointerRNA * ptr
Definition: wm_files.c:3157