[Bf-blender-cvs] [1b1fcd79da5] functions: basic caching system so that particles can be rendered

Jacques Lucke noreply at git.blender.org
Tue Jul 9 18:01:41 CEST 2019


Commit: 1b1fcd79da586ae885dafd1e7ac86e934a51db8d
Author: Jacques Lucke
Date:   Tue Jul 9 15:56:38 2019 +0200
Branches: functions
https://developer.blender.org/rB1b1fcd79da586ae885dafd1e7ac86e934a51db8d

basic caching system so that particles can be rendered

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

M	source/blender/blenlib/BLI_array_ref.hpp
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/modifiers/intern/MOD_bparticles.c
M	source/blender/simulations/BParticles.h
M	source/blender/simulations/bparticles/c_wrapper.cpp

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

diff --git a/source/blender/blenlib/BLI_array_ref.hpp b/source/blender/blenlib/BLI_array_ref.hpp
index 5a03c041475..d17f1e8662d 100644
--- a/source/blender/blenlib/BLI_array_ref.hpp
+++ b/source/blender/blenlib/BLI_array_ref.hpp
@@ -243,6 +243,11 @@ template<typename T> class ArrayRef {
   }
 };
 
+template<typename T> ArrayRef<T> ref_c_array(T *array, uint size)
+{
+  return ArrayRef<T>(array, size);
+}
+
 template<typename ArrayT, typename ValueT, ValueT (*GetValue)(ArrayT &item)> class MappedArrayRef {
  private:
   ArrayT *m_start = nullptr;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index e750b84efa0..61855d8f14e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5800,6 +5800,30 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
         }
       }
     }
+    else if (md->type == eModifierType_BParticles) {
+      BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+      bpmd->cached_frames = newdataadr(fd, bpmd->cached_frames);
+
+      for (uint frame_index = 0; frame_index < bpmd->num_cached_frames; frame_index++) {
+        BParticlesFrameCache *cached_frame = &bpmd->cached_frames[frame_index];
+        cached_frame->particle_types = newdataadr(fd, cached_frame->particle_types);
+
+        for (uint type = 0; type < cached_frame->num_particle_types; type++) {
+          BParticlesTypeCache *cached_type = &cached_frame->particle_types[type];
+          cached_type->attributes_float3 = newdataadr(fd, cached_type->attributes_float3);
+
+          for (uint i = 0; i < cached_type->num_attributes_float3; i++) {
+            BParticlesAttributeCacheFloat3 *cached_attribute = &cached_type->attributes_float3[i];
+            cached_attribute->values = newdataadr(fd, cached_attribute->values);
+
+            if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+              BLI_endian_switch_float_array(cached_attribute->values,
+                                            cached_type->particle_amount * 3);
+            }
+          }
+        }
+      }
+    }
   }
 }
 
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 115387a697b..e5c6115b9a0 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1758,6 +1758,36 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
         }
       }
     }
+    else if (md->type == eModifierType_BParticles) {
+      BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+      writestruct(wd, DATA, BParticlesFrameCache, bpmd->num_cached_frames, bpmd->cached_frames);
+
+      for (uint frame_index = 0; frame_index < bpmd->num_cached_frames; frame_index++) {
+        BParticlesFrameCache *cached_frame = &bpmd->cached_frames[frame_index];
+        writestruct(wd,
+                    DATA,
+                    BParticlesTypeCache,
+                    cached_frame->num_particle_types,
+                    cached_frame->particle_types);
+
+        for (uint type = 0; type < cached_frame->num_particle_types; type++) {
+          BParticlesTypeCache *cached_type = &cached_frame->particle_types[type];
+          writestruct(wd,
+                      DATA,
+                      BParticlesAttributeCacheFloat3,
+                      cached_type->num_attributes_float3,
+                      cached_type->attributes_float3);
+
+          for (uint i = 0; i < cached_type->num_attributes_float3; i++) {
+            BParticlesAttributeCacheFloat3 *attribute_cache = &cached_type->attributes_float3[i];
+            writedata(wd,
+                      DATA,
+                      sizeof(float) * 3 * cached_type->particle_amount,
+                      attribute_cache->values);
+          }
+        }
+      }
+    }
   }
 }
 
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 3a6f0b60efc..77d93de2ac8 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1963,9 +1963,31 @@ typedef struct FunctionPointsModifierData {
   struct bNodeTree *function_tree;
 } FunctionPointsModifierData;
 
+typedef struct BParticlesAttributeCacheFloat3 {
+  char name[64];
+  float *values;
+} BParticlesAttributeCacheFloat3;
+
+typedef struct BParticlesTypeCache {
+  char name[64];
+  unsigned int num_attributes_float3;
+  unsigned int particle_amount;
+  BParticlesAttributeCacheFloat3 *attributes_float3;
+} BParticlesTypeCache;
+
+typedef struct BParticlesFrameCache {
+  unsigned int num_particle_types;
+  float frame;
+  BParticlesTypeCache *particle_types;
+} BParticlesFrameCache;
+
 typedef struct BParticlesModifierData {
   ModifierData modifier;
   struct bNodeTree *bparticles_tree;
+
+  unsigned int num_cached_frames;
+  char _pad[4];
+  BParticlesFrameCache *cached_frames;
 } BParticlesModifierData;
 
 #endif /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/modifiers/intern/MOD_bparticles.c b/source/blender/modifiers/intern/MOD_bparticles.c
index 17beb36111c..aa5f29ff37e 100644
--- a/source/blender/modifiers/intern/MOD_bparticles.c
+++ b/source/blender/modifiers/intern/MOD_bparticles.c
@@ -104,6 +104,17 @@ static Mesh *applyModifier(ModifierData *md,
                            Mesh *UNUSED(mesh))
 {
   BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+  BParticlesModifierData *bpmd_orig = (BParticlesModifierData *)modifier_get_original(md);
+
+  Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+  float current_frame = BKE_scene_frame_get(scene);
+
+  for (uint i = 0; i < bpmd_orig->num_cached_frames; i++) {
+    if (bpmd_orig->cached_frames[i].frame == current_frame) {
+      return BParticles_modifier_mesh_from_cache(&bpmd_orig->cached_frames[i]);
+    }
+  }
+
   RuntimeData *runtime = get_runtime_struct(bpmd);
 
   if (runtime->particles_state == NULL) {
@@ -111,9 +122,6 @@ static Mesh *applyModifier(ModifierData *md,
     runtime->world_state = BParticles_new_world_state();
   }
 
-  Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
-  float current_frame = BKE_scene_frame_get(scene);
-
   if (current_frame == runtime->last_simulated_frame) {
     /* do nothing */
   }
@@ -128,9 +136,12 @@ static Mesh *applyModifier(ModifierData *md,
     runtime->particles_state = BParticles_new_empty_state();
     runtime->world_state = BParticles_new_world_state();
     runtime->last_simulated_frame = current_frame;
+    BParticles_modifier_free_cache(bpmd_orig);
   }
 
-  return BParticles_test_mesh_from_state(runtime->particles_state);
+  BParticles_modifier_cache_state(bpmd_orig, runtime->particles_state, current_frame);
+  return BParticles_modifier_mesh_from_cache(
+      &bpmd_orig->cached_frames[bpmd_orig->num_cached_frames - 1]);
 }
 
 static void initData(ModifierData *UNUSED(md))
@@ -141,6 +152,16 @@ static void freeData(ModifierData *md)
 {
   BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
   free_modifier_runtime_data(bpmd);
+  BParticles_modifier_free_cache(bpmd);
+}
+
+static void copyData(const ModifierData *md, ModifierData *target, const int flag)
+{
+  BParticlesModifierData *tbpmd = (BParticlesModifierData *)target;
+
+  modifier_copyData_generic(md, target, flag);
+  tbpmd->num_cached_frames = 0;
+  tbpmd->cached_frames = NULL;
 }
 
 static void freeRuntimeData(void *runtime_data_v)
@@ -183,7 +204,7 @@ ModifierTypeInfo modifierType_BParticles = {
     /* structSize */ sizeof(BParticlesModifierData),
     /* type */ eModifierTypeType_Constructive,
     /* flags */ eModifierTypeFlag_AcceptsMesh,
-    /* copyData */ modifier_copyData_generic,
+    /* copyData */ copyData,
 
     /* deformVerts */ NULL,
     /* deformMatrices */ NULL,
diff --git a/source/blender/simulations/BParticles.h b/source/blender/simulations/BParticles.h
index a5380840bf4..a8e23716f92 100644
--- a/source/blender/simulations/BParticles.h
+++ b/source/blender/simulations/BParticles.h
@@ -11,6 +11,7 @@ extern "C" {
 struct Mesh;
 struct Depsgraph;
 struct BParticlesModifierData;
+struct BParticlesFrameCache;
 
 typedef struct OpaqueBParticlesState *BParticlesState;
 typedef struct OpaqueBParticlesWorldState *BParticlesWorldState;
@@ -21,7 +22,7 @@ void BParticles_state_free(BParticlesState particles_state);
 BParticlesWorldState BParticles_new_world_state(void);
 void BParticles_world_state_free(BParticlesWorldState world_state);
 
-void BParticles_simulate_modifier(BParticlesModifierData *bpmd,
+void BParticles_simulate_modifier(struct BParticlesModifierData *bpmd,
                                   Depsgraph *depsgraph,
                                   BParticlesState particles_state,
                                   BParticlesWorldState world_state);
@@ -29,7 +30,11 @@ void BParticles_simulate_modifier(BParticlesModifierData *bpmd,
 uint BParticles_state_particle_count(BParticlesState particles_state);
 void BParticles_state_get_positions(BParticlesState particles_state, float (*dst)[3]);
 
-struct Mesh *BParticles_test_mesh_from_state(BParticlesState particles_state);
+void BParticles_modifier_free_cache(struct BParticlesModifierData *bpmd);
+struct Mesh *BParticles_modifier_mesh_from_cache(struct BParticlesFrameCache *cached_frame);
+void BParticles_modifier_cache_state(struct BParticlesModifierData *bpmd,
+                                     BParticlesState particles_state,
+                                     float frame);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index 8cd441ee968..27d0bb35634 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -6,6 +6,7 @@
 
 #include "BLI_timeit.hpp"
 #include "BLI_task.hpp"
+#include "BLI_string.h"
 
 #include "BKE_mesh.h"
 #include "BKE_customdata.h"
@@ -176,20 +177,47 @@ static Mesh *distribute_tetrahedons(ArrayRef<float3> centers, float scale)
   return mesh;
 }
 
-Mesh *BParticles_test_mesh_from_state(BParticlesState state_c)
+void BParticles_modifier_free_cache(BParticlesModifierData *bpmd)
 {
-  SCOPE

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list