Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/blender/blender_session.cpp83
-rw-r--r--intern/cycles/blender/blender_session.h7
-rw-r--r--intern/cycles/blender/blender_shader.cpp26
-rw-r--r--intern/cycles/blender/blender_util.h18
-rw-r--r--source/blender/blenkernel/BKE_image.h4
-rw-r--r--source/blender/blenkernel/intern/image.c54
-rw-r--r--source/blender/makesrna/intern/rna_image.c5
7 files changed, 172 insertions, 25 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 60dfe37c9f8..3913323c21c 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -612,8 +612,25 @@ void BlenderSession::test_cancel()
session->progress.set_cancel("Cancelled");
}
-void BlenderSession::builtin_image_info(const string &name, bool &is_float, int &width, int &height, int &channels)
+/* builtin image file name is actually an image datablock name with
+ * absolute sequence frame number concatenated via '@' character
+ *
+ * this function splits image id name and frame number from a
+ * builtin image name
+ */
+void BlenderSession::builtin_name_split(const string &builtin_name, string &name, int &frame)
+{
+ int last = builtin_name.find_last_of('@');
+ name = builtin_name.substr(0, last);
+ frame = atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
+}
+
+void BlenderSession::builtin_image_info(const string &builtin_name, bool &is_float, int &width, int &height, int &channels)
{
+ string name;
+ int frame;
+ builtin_name_split(builtin_name, name, frame);
+
BL::Image b_image = b_data.images[name];
if(b_image) {
@@ -630,8 +647,12 @@ void BlenderSession::builtin_image_info(const string &name, bool &is_float, int
}
}
-bool BlenderSession::builtin_image_pixels(const string &name, unsigned char *pixels)
+bool BlenderSession::builtin_image_pixels(const string &builtin_name, unsigned char *pixels)
{
+ string name;
+ int frame;
+ builtin_name_split(builtin_name, name, frame);
+
BL::Image b_image = b_data.images[name];
if(b_image) {
@@ -639,16 +660,27 @@ bool BlenderSession::builtin_image_pixels(const string &name, unsigned char *pix
int height = b_image.size()[1];
int channels = b_image.channels();
- BL::DynamicArray<float> pixels_array = b_image.pixels();
- float *float_pixels = pixels_array.data;
+ unsigned char *image_pixels;
+ image_pixels = image_get_pixels_for_frame(b_image, frame);
- /* a bit of shame, but Py API currently only returns float array,
- * which need to be converted back to char buffer
- */
- unsigned char *cp = pixels;
- float *fp = float_pixels;
- for(int i = 0; i < channels * width * height; i++, cp++, fp++) {
- *cp = *fp * 255;
+ if(image_pixels) {
+ memcpy(pixels, image_pixels, width * height * channels * sizeof(unsigned char));
+ MEM_freeN(image_pixels);
+ }
+ else {
+ if(channels == 1) {
+ memset(pixels, 0, width * height * sizeof(unsigned char));
+ }
+ else {
+ unsigned char *cp = pixels;
+ for(int i = 0; i < width * height; i++, cp += channels) {
+ cp[0] = 255;
+ cp[1] = 0;
+ cp[2] = 255;
+ if(channels == 4)
+ cp[3] = 255;
+ }
+ }
}
return true;
@@ -657,8 +689,12 @@ bool BlenderSession::builtin_image_pixels(const string &name, unsigned char *pix
return false;
}
-bool BlenderSession::builtin_image_float_pixels(const string &name, float *pixels)
+bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, float *pixels)
{
+ string name;
+ int frame;
+ builtin_name_split(builtin_name, name, frame);
+
BL::Image b_image = b_data.images[name];
if(b_image) {
@@ -666,9 +702,28 @@ bool BlenderSession::builtin_image_float_pixels(const string &name, float *pixel
int height = b_image.size()[1];
int channels = b_image.channels();
- BL::DynamicArray<float> pixels_array = b_image.pixels();
+ float *image_pixels;
+ image_pixels = image_get_float_pixels_for_frame(b_image, frame);
- memcpy(pixels, pixels_array.data, width * height * channels * sizeof(float));
+ if(image_pixels) {
+ memcpy(pixels, image_pixels, width * height * channels * sizeof(float));
+ MEM_freeN(image_pixels);
+ }
+ else {
+ if(channels == 1) {
+ memset(pixels, 0, width * height * sizeof(float));
+ }
+ else {
+ float *fp = pixels;
+ for(int i = 0; i < width * height; i++, fp += channels) {
+ fp[0] = 1.0f;
+ fp[1] = 0.0f;
+ fp[2] = 1.0f;
+ if(channels == 4)
+ fp[3] = 1.0f;
+ }
+ }
+ }
return true;
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index dfa487bd244..686ff3d1be9 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -94,9 +94,10 @@ protected:
void do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only);
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
- void builtin_image_info(const string &name, bool &is_float, int &width, int &height, int &channels);
- bool builtin_image_pixels(const string &name, unsigned char *pixels);
- bool builtin_image_float_pixels(const string &name, float *pixels);
+ void builtin_name_split(const string &builtin_name, string &name, int &frame);
+ void builtin_image_info(const string &builtin_name, bool &is_float, int &width, int &height, int &channels);
+ bool builtin_image_pixels(const string &builtin_name, unsigned char *pixels);
+ bool builtin_image_float_pixels(const string &builtin_name, float *pixels);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 3bb02bbfe74..b1eaedba47a 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -511,17 +511,24 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeTexImage b_image_node(b_node);
BL::Image b_image(b_image_node.image());
ImageTextureNode *image = new ImageTextureNode();
- /* todo: handle movie images */
- if(b_image && b_image.source() != BL::Image::source_MOVIE) {
+ if(b_image) {
/* builtin images will use callback-based reading because
* they could only be loaded correct from blender side
*/
bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED;
+ b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE;
if(is_builtin) {
- /* for builtin images we're using image datablock name to find an image to read pixels from later */
- image->filename = b_image.name();
+ /* for builtin images we're using image datablock name to find an image to
+ * read pixels from later
+ *
+ * also store frame number as well, so there's no differences in handling
+ * builtin names for packed images and movies
+ */
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_image_node.image_user(), scene_frame);
+ image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
image->is_builtin = true;
}
else {
@@ -542,12 +549,15 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeTexEnvironment b_env_node(b_node);
BL::Image b_image(b_env_node.image());
EnvironmentTextureNode *env = new EnvironmentTextureNode();
- if(b_image && b_image.source() != BL::Image::source_MOVIE) {
+ if(b_image) {
bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED;
+ b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE;
if(is_builtin) {
- env->filename = b_image.name();
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_env_node.image_user(), scene_frame);
+ env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
env->is_builtin = true;
}
else {
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 88c98860794..f134416f2d0 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -33,6 +33,8 @@ extern "C" {
void BLI_timestr(double _time, char *str);
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
+unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
+float *BKE_image_get_float_pixels_for_frame(void *image, int frame);
}
CCL_NAMESPACE_BEGIN
@@ -100,6 +102,22 @@ static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, in
return string(filepath);
}
+static inline int image_user_frame_number(BL::ImageUser iuser, int cfra)
+{
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
+ return iuser.frame_current();
+}
+
+static inline unsigned char *image_get_pixels_for_frame(BL::Image image, int frame)
+{
+ return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
+}
+
+static inline float *image_get_float_pixels_for_frame(BL::Image image, int frame)
+{
+ return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
+}
+
/* Utilities */
static inline Transform get_transform(BL::Array<float, 16> array)
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 499609932d1..597f2f25575 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -219,6 +219,10 @@ void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width,
void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int height, int width);
void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int height, int width);
+/* Cycles hookup */
+unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame);
+float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 21417386d65..5124406b641 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -3199,3 +3199,57 @@ void BKE_image_get_aspect(Image *image, float *aspx, float *aspy)
else
*aspy = 1.0f;
}
+
+unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame)
+{
+ ImageUser iuser = {0};
+ void *lock;
+ ImBuf *ibuf;
+ unsigned char *pixels = NULL;
+
+ iuser.framenr = frame;
+ iuser.ok = TRUE;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf) {
+ pixels = (unsigned char *) ibuf->rect;
+
+ if (pixels)
+ pixels = MEM_dupallocN(pixels);
+
+ BKE_image_release_ibuf(image, ibuf, lock);
+ }
+
+ if (!pixels)
+ return NULL;
+
+ return pixels;
+}
+
+float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame)
+{
+ ImageUser iuser = {0};
+ void *lock;
+ ImBuf *ibuf;
+ float *pixels = NULL;
+
+ iuser.framenr = frame;
+ iuser.ok = TRUE;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf) {
+ pixels = ibuf->rect_float;
+
+ if (pixels)
+ pixels = MEM_dupallocN(pixels);
+
+ BKE_image_release_ibuf(image, ibuf, lock);
+ }
+
+ if (!pixels)
+ return NULL;
+
+ return pixels;
+}
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 81dbfff13b2..180a5a180fd 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -427,6 +427,11 @@ static void rna_def_imageuser(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_ImageUser_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ prop = RNA_def_property(srna, "frame_current", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "framenr");
+ RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
+ RNA_def_property_ui_text(prop, "Current Frame", "Current frame number in image sequence or movie");
+
/* animation */
prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cycl", 0);