[Bf-blender-cvs] [8725d1252ea] new-object-types: Volume: initial support for frame sequences

Brecht Van Lommel noreply at git.blender.org
Wed Feb 5 19:14:09 CET 2020


Commit: 8725d1252ea3b2161eb84ed6162456b0d17d0ce7
Author: Brecht Van Lommel
Date:   Wed Feb 5 11:25:21 2020 +0100
Branches: new-object-types
https://developer.blender.org/rB8725d1252ea3b2161eb84ed6162456b0d17d0ce7

Volume: initial support for frame sequences

There is frame duration/start/offset just like images. A difference is
that there are more playback modes: clip, extend, repeat, ping-pong.

Still missing is auto detect of frame sequences, the duration has to be
manually entered now.

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

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/blender/blender_sync.cpp
M	release/scripts/startup/bl_ui/properties_data_volume.py
M	source/blender/blenkernel/BKE_volume.h
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenloader/intern/readfile.c
M	source/blender/depsgraph/CMakeLists.txt
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
M	source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
A	source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
A	source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
M	source/blender/makesdna/DNA_volume_types.h
M	source/blender/makesrna/intern/rna_volume.c

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 86be9ee9a0f..40fe139c9b6 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -370,7 +370,7 @@ static void create_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene
       VoxelAttribute *volume_data = attr->data_voxel();
       ImageMetaData metadata;
       const bool animated = false;
-      const float frame = 0.0f;
+      const float frame = b_volume.grids.frame();
 
       volume_data->manager = scene->image_manager;
       volume_data->slot = scene->image_manager->add_image(name.c_str(),
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 20dbe23cdb7..9e89d36a380 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -173,6 +173,11 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
         world_recalc = true;
       }
     }
+    /* Volume */
+    else if (b_id.is_a(&RNA_Volume)) {
+      BL::Volume b_volume(b_id);
+      mesh_map.set_recalc(b_volume);
+    }
   }
 
   BlenderViewportParameters new_viewport_parameters(b_v3d);
diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py
index e95aee645ae..ae68123f3de 100644
--- a/release/scripts/startup/bl_ui/properties_data_volume.py
+++ b/release/scripts/startup/bl_ui/properties_data_volume.py
@@ -51,8 +51,8 @@ class DATA_PT_context_volume(DataButtonsPanel, Panel):
             layout.template_ID(space, "pin_id")
 
 
-class DATA_PT_volume(DataButtonsPanel, Panel):
-    bl_label = "Volume"
+class DATA_PT_volume_file(DataButtonsPanel, Panel):
+    bl_label = "OpenVDB File"
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
 
     def draw(self, context):
@@ -63,8 +63,21 @@ class DATA_PT_volume(DataButtonsPanel, Panel):
 
         layout.prop(volume, "filepath", text="")
 
+        if len(volume.filepath):
+            layout.use_property_split = True
+            layout.use_property_decorate = False
+
+            col = layout.column(align=True)
+            col.prop(volume, "is_sequence")
+            if volume.is_sequence:
+                col.prop(volume, "frame_duration", text="Frames")
+                col.prop(volume, "frame_start", text="Start")
+                col.prop(volume, "frame_offset", text="Offset")
+                col.prop(volume, "sequence_mode", text="Mode")
+
         error_msg = volume.grids.error_message
         if len(error_msg):
+          layout.separator()
           col = layout.column(align=True)
           col.label(text="Failed to load volume:")
           col.label(text=error_msg)
@@ -96,8 +109,8 @@ class DATA_PT_custom_props_volume(DataButtonsPanel, PropertyPanel, Panel):
 
 classes = (
     DATA_PT_context_volume,
-    DATA_PT_volume,
     DATA_PT_volume_grids,
+    DATA_PT_volume_file,
     DATA_PT_custom_props_volume,
     VOLUME_UL_grids,
 )
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 9224e95327b..7e0e47be5e8 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -62,6 +62,7 @@ struct BoundBox *BKE_volume_boundbox_get(struct Object *ob);
 struct Volume *BKE_volume_new_for_eval(const struct Volume *volume_src);
 struct Volume *BKE_volume_copy_for_eval(struct Volume *volume_src, bool reference);
 
+void BKE_volume_eval_geometry(struct Depsgraph *depsgraph, struct Volume *volume);
 void BKE_volume_data_update(struct Depsgraph *depsgraph,
                             struct Scene *scene,
                             struct Object *object);
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index d6da0594188..60df9bf0fea 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -25,6 +25,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 #include "DNA_volume_types.h"
 
 #include "BLI_fileops.h"
@@ -42,6 +43,7 @@
 #include "BKE_modifier.h"
 #include "BKE_object.h"
 #include "BKE_packedFile.h"
+#include "BKE_scene.h"
 #include "BKE_volume.h"
 
 #include "DEG_depsgraph_query.h"
@@ -50,6 +52,8 @@
 
 static CLG_LogRef LOG = {"bke.volume"};
 
+#define VOLUME_FRAME_NONE INT_MAX
+
 #ifdef WITH_OPENVDB
 #  include <mutex>
 #  include <openvdb/openvdb.h>
@@ -111,14 +115,17 @@ void BKE_volume_init(Volume *volume)
   volume->filepath[0] = '\0';
   volume->packedfile = NULL;
   volume->flag = 0;
+  volume->frame_start = 1;
+  volume->frame_offset = 0;
+  volume->frame_duration = 0;
   BKE_volume_init_grids(volume);
 }
 
 void BKE_volume_init_grids(Volume *volume)
 {
 #ifdef WITH_OPENVDB
-  if (volume->grids == NULL) {
-    volume->grids = OBJECT_GUARDED_NEW(VolumeGridVector);
+  if (volume->runtime.grids == NULL) {
+    volume->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector);
   }
 #else
   UNUSED_VARS(volume);
@@ -145,9 +152,9 @@ void BKE_volume_copy_data(Main *UNUSED(bmain),
 
   volume_dst->mat = (Material **)MEM_dupallocN(volume_src->mat);
 #ifdef WITH_OPENVDB
-  if (volume_src->grids) {
-    const VolumeGridVector &grids_src = *(volume_src->grids);
-    volume_dst->grids = OBJECT_GUARDED_NEW(VolumeGridVector, grids_src);
+  if (volume_src->runtime.grids) {
+    const VolumeGridVector &grids_src = *(volume_src->runtime.grids);
+    volume_dst->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector, grids_src);
   }
 #endif
 }
@@ -170,15 +177,97 @@ void BKE_volume_free(Volume *volume)
   BKE_volume_batch_cache_free(volume);
   MEM_SAFE_FREE(volume->mat);
 #ifdef WITH_OPENVDB
-  OBJECT_GUARDED_SAFE_DELETE(volume->grids, VolumeGridVector);
+  OBJECT_GUARDED_SAFE_DELETE(volume->runtime.grids, VolumeGridVector);
 #endif
 }
 
+/* Sequence */
+
+static int volume_sequence_frame(const Depsgraph *depsgraph, const Volume *volume)
+{
+  if (!volume->is_sequence) {
+    return 0;
+  }
+
+  const int scene_frame = DEG_get_ctime(depsgraph);
+  const VolumeSequenceMode mode = (VolumeSequenceMode)volume->sequence_mode;
+  const int frame_duration = volume->frame_duration;
+  const int frame_start = volume->frame_start;
+  const int frame_offset = volume->frame_offset;
+
+  if (frame_duration == 0) {
+    return VOLUME_FRAME_NONE;
+  }
+
+  int frame = scene_frame - frame_start + 1;
+
+  switch (mode) {
+    case VOLUME_SEQUENCE_CLIP: {
+      if (frame < 1 || frame > frame_duration) {
+        return VOLUME_FRAME_NONE;
+      }
+      break;
+    }
+    case VOLUME_SEQUENCE_EXTEND: {
+      frame = clamp_i(frame, 1, frame_duration);
+      break;
+    }
+    case VOLUME_SEQUENCE_REPEAT: {
+      frame = frame % frame_duration;
+      if (frame < 0) {
+        frame += frame_duration;
+      }
+      if (frame == 0) {
+        frame = frame_duration;
+      }
+      break;
+    }
+    case VOLUME_SEQUENCE_PING_PONG: {
+      const int pingpong_duration = frame_duration * 2 - 2;
+      frame = frame % pingpong_duration;
+      if (frame < 0) {
+        frame += pingpong_duration;
+      }
+      if (frame == 0) {
+        frame = pingpong_duration;
+      }
+      if (frame > frame_duration) {
+        frame = frame_duration * 2 - frame;
+      }
+      break;
+    }
+  }
+
+  /* important to apply after else we cant loop on frames 100 - 110 for eg. */
+  frame += frame_offset;
+
+  return frame;
+}
+
+static void volume_filepath_get(const Main *bmain, const Volume *volume, char r_filepath[FILE_MAX])
+{
+  BLI_strncpy(r_filepath, volume->filepath, FILE_MAX);
+  BLI_path_abs(r_filepath, ID_BLEND_PATH(bmain, &volume->id));
+
+  int fframe;
+  int frame_len;
+
+  /* TODO: check for filepath validity earlier, to avoid unnecessary computations. */
+  if (volume->is_sequence && BLI_path_frame_get(r_filepath, &fframe, &frame_len)) {
+    char ext[32];
+    BLI_path_frame_strip(r_filepath, ext);
+    BLI_path_frame(r_filepath, volume->runtime.frame, frame_len);
+    BLI_path_extension_ensure(r_filepath, FILE_MAX, ext);
+  }
+}
+
+/* File Load */
+
 bool BKE_volume_is_loaded(const Volume *volume)
 {
 #ifdef WITH_OPENVDB
   /* Test if there is a file to load, or if already loaded. */
-  return (volume->filepath[0] == '\0' || volume->grids->filepath[0] != '\0');
+  return (volume->filepath[0] == '\0' || volume->runtime.grids->filepath[0] != '\0');
 #else
   UNUSED_VARS(volume);
   return true;
@@ -188,7 +277,12 @@ bool BKE_volume_is_loaded(const Volume *volume)
 bool BKE_volume_load(Volume *volume, Main *bmain)
 {
 #ifdef WITH_OPENVDB
-  VolumeGridVector &grids = *volume->grids;
+  VolumeGridVector &grids = *volume->runtime.grids;
+
+  if (volume->runtime.frame == VOLUME_FRAME_NONE) {
+    /* Skip loading this frame, outside of sequence range. */
+    return true;
+  }
 
   if (BKE_volume_is_loaded(volume)) {
     return grids.error_msg.empty();
@@ -200,9 +294,19 @@ bool BKE_volume_load(Volume *volume, Main *bmain)
     return grids.error_msg.empty();
   }
 
-  /* Get absolute file path. */
-  STRNCPY(grids.filepath, volume->filepath);
-  BLI_path_abs(grids.filepath, ID_BLEND_PATH(bmain, &volume->id));
+  /* Get absolute file path at current frame. */
+  volume_filepath_get(bmain, volume, grids.filepath);
+
+  CLOG_INFO(&LOG, 1, "Volume %s: load %s", volume->id.name + 2, grids.filepath);
+
+  /* Test if file exists. */
+  if (!BLI_exists(grids.filepath)) {
+    char filename[FILE_MAX];
+    BLI_split_file_part(grids.filepath, filename, sizeof(filename));
+    grids.error_msg = filename + std::string(" not found");
+    CLOG_INFO(&LOG, 1, "Volume %s: %s", volume->id.name + 2, grids.error_msg.c_str());
+    return false;
+  }
 
   CLOG_INFO(&LOG, 1, "Volume %s: load %s", volume->id.name + 2, grids.filepath);
 
@@ -246,7 +350,7 @@ bool BKE_volume_load(Volume *volume, Main *bmain)
 void BKE_volume_unload(Volume *volume)
 {
 #ifdef WITH_OPENVDB
-  VolumeGridVector &grids = *volume->grids;
+  VolumeGridVector &grids = *volume->runtime.grids;
   if (grids.filepath[0] != '\0') {
     CLOG_INFO(&LOG, 1, "Volume %s: unload", volume->id.name + 2);
     grids.clear();
@@ -384,6 +488,24 @@

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list