[Bf-blender-cvs] [6f96dfabe5c] master: Simulations: initial simulation state and cache

Jacques Lucke noreply at git.blender.org
Mon Jun 8 15:50:14 CEST 2020


Commit: 6f96dfabe5cbf6966282decd2307ade9aacdeaee
Author: Jacques Lucke
Date:   Mon Jun 8 15:41:41 2020 +0200
Branches: master
https://developer.blender.org/rB6f96dfabe5cbf6966282decd2307ade9aacdeaee

Simulations: initial simulation state and cache

The current particle state is stored in a `CustomData` instance and
the cache is stored in `PointCache`.

The current state exists on the copy-on-write copies of the simulation,
while the cache only exists in the original data block.

This patch implements a temporary trivial particle simulation that does not
use the node system yet. It is used for testing and will be replaced soon.

`PointCache` still has some limitations that need to be overcome using
separate refactorings. For example, we need to be able to store the number
of particles in the point cache. Also we need to change which attributes
are stored for a particle system more dynamically than is currently possible afaik.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D7836

===================================================================

M	source/blender/blenkernel/BKE_pointcache.h
M	source/blender/blenkernel/intern/pointcache.c
M	source/blender/blenkernel/intern/pointcloud.c
M	source/blender/blenkernel/intern/simulation.cc
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
M	source/blender/editors/space_action/action_draw.c
M	source/blender/makesdna/DNA_simulation_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_simulation.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 164783f4d14..2dd364f3c48 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -64,6 +64,7 @@ extern "C" {
 #define PTCACHE_TYPE_SMOKE_HIGHRES 4
 #define PTCACHE_TYPE_DYNAMICPAINT 5
 #define PTCACHE_TYPE_RIGIDBODY 6
+#define PTCACHE_TYPE_SIM_PARTICLES 7
 
 /* high bits reserved for flags that need to be stored in file */
 #define PTCACHE_TYPEFLAG_COMPRESS (1 << 16)
@@ -84,10 +85,12 @@ struct ListBase;
 struct Main;
 struct Object;
 struct ParticleKey;
+struct ParticleSimulationState;
 struct ParticleSystem;
 struct PointCache;
 struct RigidBodyWorld;
 struct Scene;
+struct Simulation;
 struct SoftBody;
 struct ViewLayer;
 
@@ -292,6 +295,7 @@ void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid,
                                       struct Object *ob,
                                       struct DynamicPaintSurface *surface);
 void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw);
+void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, struct ParticleSimulationState *state);
 
 PTCacheID BKE_ptcache_id_find(struct Object *ob, struct Scene *scene, struct PointCache *cache);
 void BKE_ptcache_ids_from_object(struct ListBase *lb,
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 5ee61667eca..17c41d992ed 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -41,6 +41,7 @@
 #include "DNA_particle_types.h"
 #include "DNA_rigidbody_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_simulation_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
@@ -1828,6 +1829,87 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r
   pid->file_type = PTCACHE_FILE_PTCACHE;
 }
 
+static int ptcache_sim_particle_totpoint(void *state_v, int UNUSED(cfra))
+{
+  ParticleSimulationState *state = (ParticleSimulationState *)state_v;
+  return state->tot_particles;
+}
+
+static void ptcache_sim_particle_error(void *UNUSED(state_v), const char *UNUSED(message))
+{
+}
+
+static int ptcache_sim_particle_write(int index, void *state_v, void **data, int UNUSED(cfra))
+{
+  ParticleSimulationState *state = (ParticleSimulationState *)state_v;
+
+  const float *positions = (const float *)CustomData_get_layer_named(
+      &state->attributes, CD_LOCATION, "Position");
+
+  PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, positions + (index * 3));
+
+  return 1;
+}
+static void ptcache_sim_particle_read(
+    int index, void *state_v, void **data, float UNUSED(cfra), float *UNUSED(old_data))
+{
+  ParticleSimulationState *state = (ParticleSimulationState *)state_v;
+
+  BLI_assert(index < state->tot_particles);
+  float *positions = (float *)CustomData_get_layer_named(
+      &state->attributes, CD_LOCATION, "Position");
+
+  PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, positions + (index * 3));
+}
+
+void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, ParticleSimulationState *state)
+{
+  memset(pid, 0, sizeof(PTCacheID));
+
+  ParticleSimulationState *state_orig;
+  if (state->head.orig_state != NULL) {
+    state_orig = (ParticleSimulationState *)state->head.orig_state;
+  }
+  else {
+    state_orig = state;
+  }
+
+  pid->calldata = state;
+  pid->type = PTCACHE_TYPE_SIM_PARTICLES;
+  pid->cache = state_orig->point_cache;
+  pid->cache_ptr = &state_orig->point_cache;
+  pid->ptcaches = &state_orig->ptcaches;
+  pid->totpoint = ptcache_sim_particle_totpoint;
+  pid->totwrite = ptcache_sim_particle_totpoint;
+  pid->error = ptcache_sim_particle_error;
+
+  pid->write_point = ptcache_sim_particle_write;
+  pid->read_point = ptcache_sim_particle_read;
+  pid->interpolate_point = NULL;
+
+  pid->write_stream = NULL;
+  pid->read_stream = NULL;
+
+  pid->write_openvdb_stream = NULL;
+  pid->read_openvdb_stream = NULL;
+
+  pid->write_extra_data = NULL;
+  pid->read_extra_data = NULL;
+  pid->interpolate_extra_data = NULL;
+
+  pid->write_header = NULL;
+  pid->read_header = NULL;
+
+  pid->data_types = 1 << BPHYS_DATA_LOCATION;
+  pid->info_types = 0;
+
+  pid->stack_index = 0;
+
+  pid->default_step = 1;
+  pid->max_step = 1;
+  pid->file_type = PTCACHE_FILE_PTCACHE;
+}
+
 /**
  * \param ob: Optional, may be NULL.
  * \param scene: Optional may be NULL.
@@ -1926,6 +2008,23 @@ static bool foreach_object_modifier_ptcache(Object *object,
         }
       }
     }
+    else if (md->type == eModifierType_Simulation) {
+      SimulationModifierData *smd = (SimulationModifierData *)md;
+      if (smd->simulation) {
+        LISTBASE_FOREACH (SimulationState *, state, &smd->simulation->states) {
+          switch ((eSimulationStateType)state->type) {
+            case SIM_STATE_TYPE_PARTICLES: {
+              ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+              BKE_ptcache_id_from_sim_particles(&pid, particle_state);
+              if (!callback(&pid, callback_user_data)) {
+                return false;
+              }
+              break;
+            }
+          }
+        }
+      }
+    }
   }
   return true;
 }
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c
index e03888dcad7..df5d93beccb 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.c
@@ -192,6 +192,7 @@ void BKE_pointcloud_update_customdata_pointers(PointCloud *pointcloud)
 PointCloud *BKE_pointcloud_new_for_eval(const PointCloud *pointcloud_src, int totpoint)
 {
   PointCloud *pointcloud_dst = BKE_id_new_nomain(ID_PT, NULL);
+  CustomData_free(&pointcloud_dst->pdata, pointcloud_dst->totpoint);
 
   STRNCPY(pointcloud_dst->id.name, pointcloud_src->id.name);
   pointcloud_dst->mat = MEM_dupallocN(pointcloud_src->mat);
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index d5ba345928b..20386869ca9 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -27,7 +27,9 @@
 #include "DNA_scene_types.h"
 #include "DNA_simulation_types.h"
 
+#include "BLI_array_ref.hh"
 #include "BLI_compiler_compat.h"
+#include "BLI_float3.hh"
 #include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_string.h"
@@ -35,12 +37,14 @@
 
 #include "BKE_anim_data.h"
 #include "BKE_animsys.h"
+#include "BKE_customdata.h"
 #include "BKE_idtype.h"
 #include "BKE_lib_id.h"
 #include "BKE_lib_query.h"
 #include "BKE_lib_remap.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
+#include "BKE_pointcache.h"
 #include "BKE_simulation.h"
 
 #include "NOD_simulation.h"
@@ -50,6 +54,10 @@
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
+using BLI::ArrayRef;
+using BLI::float3;
+using BLI::MutableArrayRef;
+
 static void simulation_init_data(ID *id)
 {
   Simulation *simulation = (Simulation *)id;
@@ -59,6 +67,14 @@ static void simulation_init_data(ID *id)
 
   bNodeTree *ntree = ntreeAddTree(nullptr, "Simulation Nodetree", ntreeType_Simulation->idname);
   simulation->nodetree = ntree;
+
+  /* Add a default particle simulation state for now. */
+  ParticleSimulationState *state = (ParticleSimulationState *)MEM_callocN(
+      sizeof(ParticleSimulationState), __func__);
+  CustomData_reset(&state->attributes);
+
+  state->point_cache = BKE_ptcache_add(&state->ptcaches);
+  BLI_addtail(&simulation->states, state);
 }
 
 static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
@@ -75,6 +91,21 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
                    (ID **)&simulation_dst->nodetree,
                    flag_private_id_data);
   }
+
+  BLI_listbase_clear(&simulation_dst->states);
+
+  LISTBASE_FOREACH (const SimulationState *, state_src, &simulation_src->states) {
+    switch ((eSimulationStateType)state_src->type) {
+      case SIM_STATE_TYPE_PARTICLES: {
+        ParticleSimulationState *particle_state_dst = (ParticleSimulationState *)MEM_callocN(
+            sizeof(ParticleSimulationState), __func__);
+        CustomData_reset(&particle_state_dst->attributes);
+
+        BLI_addtail(&simulation_dst->states, particle_state_dst);
+        break;
+      }
+    }
+  }
 }
 
 static void simulation_free_data(ID *id)
@@ -88,6 +119,18 @@ static void simulation_free_data(ID *id)
     MEM_freeN(simulation->nodetree);
     simulation->nodetree = nullptr;
   }
+
+  LISTBASE_FOREACH_MUTABLE (SimulationState *, state, &simulation->states) {
+    switch ((eSimulationStateType)state->type) {
+      case SIM_STATE_TYPE_PARTICLES: {
+        ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+        CustomData_free(&particle_state->attributes, particle_state->tot_particles);
+        BKE_ptcache_free_list(&particle_state->ptcaches);
+        break;
+      }
+    }
+    MEM_freeN(state);
+  }
 }
 
 static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -125,8 +168,94 @@ void *BKE_simulation_add(Main *bmain, const char *name)
   return simulation;
 }
 
-void BKE_simulation_data_update(Depsgraph *UNUSED(depsgraph),
-                                Scene *UNUSED(scene),
-                                Simulation *UNUSED(simulation))
+static MutableArrayRef<float3> get_particle_positions(ParticleSimulationState *state)
 {
+  return MutableArrayRef<float3>(
+      (float3 *)CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position"),
+      state->tot_particles);
+}
+
+static void ensure_attributes_exist(ParticleSimulationState *state)
+{
+  if (CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position") == nullptr) {
+    CustomData_add_layer_named(
+        &state->attributes, CD_LOCATION, CD_CALLOC, nullptr, state->tot_particles, "Position");
+  }
+}
+
+static void copy_particle_state_to_cow(ParticleSimulationState *state_orig,
+                                       ParticleSimulationState *state_cow)
+{
+  ensure_attributes_exist(state_cow);
+  CustomData_free(&state_cow->attributes, sta

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list