[Bf-blender-cvs] [6cf4861c3ac] master: Cleanup: refactor image loading to use abstract ImageLoader base class

Brecht Van Lommel noreply at git.blender.org
Wed Mar 11 20:48:42 CET 2020


Commit: 6cf4861c3ac09fd65a765e8f8e3584713cc5303b
Author: Brecht Van Lommel
Date:   Sun Mar 8 14:21:29 2020 +0100
Branches: master
https://developer.blender.org/rB6cf4861c3ac09fd65a765e8f8e3584713cc5303b

Cleanup: refactor image loading to use abstract ImageLoader base class

Rather than passing around void pointers, various Blender image sources now
subclass this. OIIO is also just another type of image loader.

Also fixes T67718: Cycles viewport render crash editing point density settings

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

M	intern/cycles/blender/CMakeLists.txt
M	intern/cycles/blender/blender_image.cpp
A	intern/cycles/blender/blender_image.h
M	intern/cycles/blender/blender_session.cpp
M	intern/cycles/blender/blender_session.h
M	intern/cycles/blender/blender_shader.cpp
M	intern/cycles/blender/blender_volume.cpp
M	intern/cycles/render/CMakeLists.txt
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/attribute.h
M	intern/cycles/render/image.cpp
M	intern/cycles/render/image.h
A	intern/cycles/render/image_oiio.cpp
A	intern/cycles/render/image_oiio.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	source/blender/makesrna/intern/makesrna.c

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

diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index d9a2ebf8571..ae191b6c0f7 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -38,6 +38,7 @@ set(SRC
   CCL_api.h
   blender_device.h
   blender_id_map.h
+  blender_image.h
   blender_object_cull.h
   blender_sync.h
   blender_session.h
diff --git a/intern/cycles/blender/blender_image.cpp b/intern/cycles/blender/blender_image.cpp
index 55ce6a295d1..459dc1779fb 100644
--- a/intern/cycles/blender/blender_image.cpp
+++ b/intern/cycles/blender/blender_image.cpp
@@ -14,206 +14,71 @@
  * limitations under the License.
  */
 
-#include "render/image.h"
+#include "MEM_guardedalloc.h"
 
-#include "blender/blender_sync.h"
+#include "blender/blender_image.h"
 #include "blender/blender_session.h"
 #include "blender/blender_util.h"
 
 CCL_NAMESPACE_BEGIN
 
-/* builtin image file name is actually an image datablock name with
- * absolute sequence frame number concatenated via '@' character
- *
- * this function splits frame from builtin name
- */
-int BlenderSession::builtin_image_frame(const string &builtin_name)
+/* Packed Images */
+
+BlenderImageLoader::BlenderImageLoader(BL::Image b_image, int frame)
+    : b_image(b_image), frame(frame), free_cache(!b_image.has_data())
 {
-  int last = builtin_name.find_last_of('@');
-  return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
 }
 
-void BlenderSession::builtin_image_info(const string &builtin_name,
-                                        void *builtin_data,
-                                        ImageMetaData &metadata)
+bool BlenderImageLoader::load_metadata(ImageMetaData &metadata)
 {
-  /* empty image */
-  metadata.width = 1;
-  metadata.height = 1;
-
-  if (!builtin_data)
-    return;
-
-  /* recover ID pointer */
-  PointerRNA ptr;
-  RNA_id_pointer_create((ID *)builtin_data, &ptr);
-  BL::ID b_id(ptr);
-
-  if (b_id.is_a(&RNA_Image)) {
-    /* image data */
-    BL::Image b_image(b_id);
+  metadata.width = b_image.size()[0];
+  metadata.height = b_image.size()[1];
+  metadata.depth = 1;
+  metadata.channels = b_image.channels();
 
-    metadata.builtin_free_cache = !b_image.has_data();
-    metadata.is_float = b_image.is_float();
-    metadata.width = b_image.size()[0];
-    metadata.height = b_image.size()[1];
-    metadata.depth = 1;
-    metadata.channels = b_image.channels();
-
-    if (metadata.is_float) {
-      /* Float images are already converted on the Blender side,
-       * no need to do anything in Cycles. */
-      metadata.colorspace = u_colorspace_raw;
+  if (b_image.is_float()) {
+    if (metadata.channels == 1) {
+      metadata.type = IMAGE_DATA_TYPE_FLOAT;
     }
-  }
-  else if (b_id.is_a(&RNA_Object)) {
-    /* smoke volume data */
-    BL::Object b_ob(b_id);
-    BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
-
-    metadata.is_float = true;
-    metadata.depth = 1;
-    metadata.channels = 1;
-
-    if (!b_domain)
-      return;
-
-    if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
-        builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) ||
-        builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) ||
-        builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE))
-      metadata.channels = 1;
-    else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
-      metadata.channels = 4;
-    else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY))
-      metadata.channels = 3;
-    else
-      return;
-
-    int3 resolution = get_int3(b_domain.domain_resolution());
-    int amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1;
-
-    /* Velocity and heat data is always low-resolution. */
-    if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
-        builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
-      amplify = 1;
+    else if (metadata.channels == 4) {
+      metadata.type = IMAGE_DATA_TYPE_FLOAT4;
     }
-
-    metadata.width = resolution.x * amplify;
-    metadata.height = resolution.y * amplify;
-    metadata.depth = resolution.z * amplify;
-  }
-  else {
-    /* TODO(sergey): Check we're indeed in shader node tree. */
-    PointerRNA ptr;
-    RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
-    BL::Node b_node(ptr);
-    if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
-      BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
-      metadata.channels = 4;
-      metadata.width = b_point_density_node.resolution();
-      metadata.height = metadata.width;
-      metadata.depth = metadata.width;
-      metadata.is_float = true;
+    else {
+      return false;
     }
-  }
-}
 
-bool BlenderSession::builtin_image_pixels(const string &builtin_name,
-                                          void *builtin_data,
-                                          int tile,
-                                          unsigned char *pixels,
-                                          const size_t pixels_size,
-                                          const bool associate_alpha,
-                                          const bool free_cache)
-{
-  if (!builtin_data) {
-    return false;
-  }
-
-  const int frame = builtin_image_frame(builtin_name);
-
-  PointerRNA ptr;
-  RNA_id_pointer_create((ID *)builtin_data, &ptr);
-  BL::Image b_image(ptr);
-
-  const int width = b_image.size()[0];
-  const int height = b_image.size()[1];
-  const int channels = b_image.channels();
-
-  unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame, tile);
-  const size_t num_pixels = ((size_t)width) * height;
-
-  if (image_pixels && num_pixels * channels == pixels_size) {
-    memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
+    /* Float images are already converted on the Blender side,
+     * no need to do anything in Cycles. */
+    metadata.colorspace = u_colorspace_raw;
   }
   else {
-    if (channels == 1) {
-      memset(pixels, 0, pixels_size * sizeof(unsigned char));
+    if (metadata.channels == 1) {
+      metadata.type = IMAGE_DATA_TYPE_BYTE;
+    }
+    else if (metadata.channels == 4) {
+      metadata.type = IMAGE_DATA_TYPE_BYTE4;
     }
     else {
-      const size_t num_pixels_safe = pixels_size / channels;
-      unsigned char *cp = pixels;
-      for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
-        cp[0] = 255;
-        cp[1] = 0;
-        cp[2] = 255;
-        if (channels == 4) {
-          cp[3] = 255;
-        }
-      }
+      return false;
     }
   }
 
-  if (image_pixels) {
-    MEM_freeN(image_pixels);
-  }
-
-  /* Free image buffers to save memory during render. */
-  if (free_cache) {
-    b_image.buffers_free();
-  }
-
-  if (associate_alpha) {
-    /* Premultiply, byte images are always straight for Blender. */
-    unsigned char *cp = pixels;
-    for (size_t i = 0; i < num_pixels; i++, cp += channels) {
-      cp[0] = (cp[0] * cp[3]) >> 8;
-      cp[1] = (cp[1] * cp[3]) >> 8;
-      cp[2] = (cp[2] * cp[3]) >> 8;
-    }
-  }
   return true;
 }
 
-bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
-                                                void *builtin_data,
-                                                int tile,
-                                                float *pixels,
-                                                const size_t pixels_size,
-                                                const bool,
-                                                const bool free_cache)
+bool BlenderImageLoader::load_pixels(const ImageMetaData &metadata,
+                                     void *pixels,
+                                     const size_t pixels_size,
+                                     const bool associate_alpha)
 {
-  if (!builtin_data) {
-    return false;
-  }
+  const size_t num_pixels = ((size_t)metadata.width) * metadata.height;
+  const int channels = metadata.channels;
+  const int tile = 0; /* TODO(lukas): Support tiles here? */
 
-  PointerRNA ptr;
-  RNA_id_pointer_create((ID *)builtin_data, &ptr);
-  BL::ID b_id(ptr);
-
-  if (b_id.is_a(&RNA_Image)) {
+  if (b_image.is_float()) {
     /* image data */
-    BL::Image b_image(b_id);
-    int frame = builtin_image_frame(builtin_name);
-
-    const int width = b_image.size()[0];
-    const int height = b_image.size()[1];
-    const int channels = b_image.channels();
-
     float *image_pixels;
     image_pixels = image_get_float_pixels_for_frame(b_image, frame, tile);
-    const size_t num_pixels = ((size_t)width) * height;
 
     if (image_pixels && num_pixels * channels == pixels_size) {
       memcpy(pixels, image_pixels, pixels_size * sizeof(float));
@@ -224,7 +89,7 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
       }
       else {
         const size_t num_pixels_safe = pixels_size / channels;
-        float *fp = pixels;
+        float *fp = (float *)pixels;
         for (int i = 0; i < num_pixels_safe; i++, fp += channels) {
           fp[0] = 1.0f;
           fp[1] = 0.0f;
@@ -239,107 +104,91 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
     if (image_pixels) {
       MEM_freeN(image_pixels);
     }
-
-    /* Free image buffers to save memory during render. */
-    if (free_cache) {
-      b_image.buffers_free();
-    }
-
-    return true;
   }
-  else if (b_id.is_a(&RNA_Object)) {
-    /* smoke volume data */
-    BL::Object b_ob(b_id);
-    BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
-
-    if (!b_domain) {
-      return false;
-    }
-#ifdef WITH_FLUID
-    int3 resolution = get_int3(b_domain.domain_resolution());
-    int length, amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1;
-
-    /* Velocity and heat data is always low-resolution. */
-    if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
-        builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
-      amplify = 1;
-    }
-
-    const int width = resolution.x * amplify;
-    const int height = resolution.y * amplify;
-    const in

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list