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
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-12-20 20:57:56 +0300
committerTon Roosendaal <ton@blender.org>2006-12-20 20:57:56 +0300
commit253432bfc7c2a1dae224a03fb3055de19743ec67 (patch)
tree2cea30606f9f29be51d5366ddf0d3747b9649b90 /source
parent0a0753b409221b66f5003d8c257426043ada227e (diff)
The Big Image refactor!
Please read: http://www.blender3d.org/cms/Imaging.834.0.html Or in short: - adding MultiLayer Image support - recoded entire Image API - better integration of movie/sequence Images Was a whole load of work... went down for a week to do this. So, will need a lot of testing! Will be in irc all evening.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_colortools.h4
-rw-r--r--source/blender/blenkernel/BKE_image.h116
-rw-r--r--source/blender/blenkernel/BKE_library.h1
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h4
-rw-r--r--source/blender/blenkernel/intern/colortools.c44
-rw-r--r--source/blender/blenkernel/intern/image.c1376
-rw-r--r--source/blender/blenkernel/intern/library.c33
-rw-r--r--source/blender/blenkernel/intern/node.c61
-rw-r--r--source/blender/blenkernel/intern/node_composite.c567
-rw-r--r--source/blender/blenkernel/intern/packedFile.c11
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/blenkernel/intern/texture.c32
-rw-r--r--source/blender/blenlib/BLI_blenlib.h4
-rw-r--r--source/blender/blenlib/intern/gsqueue.c9
-rw-r--r--source/blender/blenlib/intern/util.c4
-rw-r--r--source/blender/blenloader/intern/readfile.c215
-rw-r--r--source/blender/imbuf/IMB_imbuf.h2
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h34
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c23
-rw-r--r--source/blender/imbuf/intern/divers.c30
-rw-r--r--source/blender/imbuf/intern/filter.c25
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp402
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_multi.h23
-rw-r--r--source/blender/imbuf/intern/readimage.c2
-rw-r--r--source/blender/imbuf/intern/rectop.c2
-rw-r--r--source/blender/include/BIF_butspace.h2
-rw-r--r--source/blender/include/BIF_drawimage.h10
-rw-r--r--source/blender/include/BIF_editsima.h3
-rw-r--r--source/blender/include/BIF_renderwin.h1
-rw-r--r--source/blender/include/BIF_space.h1
-rw-r--r--source/blender/include/BIF_writeimage.h2
-rw-r--r--source/blender/include/BSE_filesel.h8
-rw-r--r--source/blender/include/BSE_node.h8
-rw-r--r--source/blender/include/blendef.h10
-rw-r--r--source/blender/include/butspace.h32
-rw-r--r--source/blender/makesdna/DNA_image_types.h47
-rw-r--r--source/blender/makesdna/DNA_node_types.h1
-rw-r--r--source/blender/makesdna/DNA_packedFile_types.h1
-rw-r--r--source/blender/makesdna/DNA_scene_types.h7
-rw-r--r--source/blender/makesdna/DNA_space_types.h55
-rw-r--r--source/blender/makesdna/DNA_texture_types.h26
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h5
-rw-r--r--source/blender/python/api2_2x/Draw.c32
-rw-r--r--source/blender/python/api2_2x/Image.c158
-rw-r--r--source/blender/python/api2_2x/Texture.c62
-rw-r--r--source/blender/python/api2_2x/sceneRender.c18
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h11
-rw-r--r--source/blender/render/intern/include/texture.h5
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/envmap.c64
-rw-r--r--source/blender/render/intern/source/imagetexture.c863
-rw-r--r--source/blender/render/intern/source/pipeline.c424
-rw-r--r--source/blender/render/intern/source/rendercore.c35
-rw-r--r--source/blender/render/intern/source/texture.c119
-rw-r--r--source/blender/src/butspace.c23
-rw-r--r--source/blender/src/buttons_scene.c22
-rw-r--r--source/blender/src/buttons_shading.c996
-rw-r--r--source/blender/src/drawimage.c516
-rw-r--r--source/blender/src/drawmesh.c81
-rw-r--r--source/blender/src/drawnode.c182
-rw-r--r--source/blender/src/drawview.c282
-rw-r--r--source/blender/src/editnode.c111
-rw-r--r--source/blender/src/editobject.c10
-rw-r--r--source/blender/src/editscreen.c28
-rw-r--r--source/blender/src/editsima.c403
-rw-r--r--source/blender/src/edittime.c3
-rw-r--r--source/blender/src/filesel.c161
-rw-r--r--source/blender/src/header_filesel.c4
-rw-r--r--source/blender/src/header_image.c270
-rw-r--r--source/blender/src/header_info.c17
-rw-r--r--source/blender/src/header_node.c7
-rw-r--r--source/blender/src/header_time.c4
-rw-r--r--source/blender/src/headerbuttons.c11
-rw-r--r--source/blender/src/imagepaint.c121
-rw-r--r--source/blender/src/interface.c30
-rw-r--r--source/blender/src/interface_icons.c6
-rw-r--r--source/blender/src/meshtools.c10
-rw-r--r--source/blender/src/previewrender.c2
-rw-r--r--source/blender/src/renderwin.c61
-rw-r--r--source/blender/src/space.c39
-rw-r--r--source/blender/src/toets.c7
-rw-r--r--source/blender/src/toolbox.c5
-rw-r--r--source/blender/src/verse_object.c2
-rw-r--r--source/blender/src/writeimage.c101
-rw-r--r--source/blender/yafray/intern/yafray_Render.h1
86 files changed, 5424 insertions, 3131 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 71ede8820db..e7029a01c09 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -44,7 +44,7 @@ struct ListBase;
struct MemFile;
#define BLENDER_VERSION 242
-#define BLENDER_SUBVERSION 2
+#define BLENDER_SUBVERSION 3
#define BLENDER_MINVERSION 240
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 53097b915f0..e78882220a9 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -31,7 +31,7 @@
struct CurveMapping;
struct CurveMap;
-struct Image;
+struct ImBuf;
struct rctf;
struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
@@ -53,7 +53,7 @@ float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value
void curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin);
void curvemapping_evaluateRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin);
void curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin);
-void curvemapping_do_image(struct CurveMapping *cumap, struct Image *ima);
+void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf);
void curvemapping_premultiply(struct CurveMapping *cumap, int restore);
int curvemapping_RGBA_does_something(struct CurveMapping *cumap);
void curvemapping_initialize(struct CurveMapping *cumap);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 98a93611204..1acaf004fb9 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -43,28 +43,108 @@ struct ImBuf;
struct Tex;
struct anim;
-void free_image(struct Image *me);
-void free_image_preview(struct Image *ima);
-void free_image_buffers(struct Image *ima);
-struct Image *add_image(char *name);
-void free_unused_animimages(void);
-struct Image *new_image(int width, int height, char *name, short uvtestgrid);
-
-int BKE_write_ibuf(struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
-void BKE_makepicstring(char *string, char *base, int frame, int imtype);
-void BKE_add_image_extension(char *string, int imtype);
-int BKE_imtype_is_movie(int imtype);
+/* call from library */
+void free_image(struct Image *me);
+
+int BKE_write_ibuf(struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
+void BKE_makepicstring(char *string, char *base, int frame, int imtype);
+void BKE_add_image_extension(char *string, int imtype);
+int BKE_ftype_to_imtype(int ftype);
+int BKE_imtype_to_ftype(int imtype);
+int BKE_imtype_is_movie(int imtype);
struct anim *openanim(char * name, int flags);
-void ima_ibuf_is_nul(struct Tex *tex, struct Image *ima);
-void load_image(struct Image * ima, int flags, char *relabase, int framenum);
-void converttopremul(struct ImBuf *ibuf);
-void image_de_interlace(struct Image *ima, int odd);
+
+void converttopremul(struct ImBuf *ibuf);
+void image_de_interlace(struct Image *ima, int odd);
-void tag_image_time(struct Image *ima);
-void free_old_images(void);
+void tag_image_time(struct Image *ima);
+void free_old_images(void);
+
+/* ********************************** NEW IMAGE API *********************** */
+
+/* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
+/* should be used in conjunction with an ID * to Image. */
+struct ImageUser;
+struct RenderPass;
+struct RenderResult;
+
+/* ima->source; where image comes from */
+#define IMA_SRC_CHECK 0
+#define IMA_SRC_FILE 1
+#define IMA_SRC_SEQUENCE 2
+#define IMA_SRC_MOVIE 3
+#define IMA_SRC_GENERATED 4
+#define IMA_SRC_VIEWER 5
+
+/* ima->type, how to handle/generate it */
+#define IMA_TYPE_IMAGE 0
+#define IMA_TYPE_MULTILAYER 1
+ /* generated */
+#define IMA_TYPE_UV_TEST 2
+#define IMA_TYPE_VERSE 3
+ /* viewers */
+#define IMA_TYPE_R_RESULT 4
+#define IMA_TYPE_COMPOSITE 5
+
+/* ima->ok */
+#define IMA_OK 1
+#define IMA_OK_LOADED 2
+
+/* signals */
+ /* reload only frees, doesn't read until image_get_ibuf() called */
+#define IMA_SIGNAL_RELOAD 0
+#define IMA_SIGNAL_FREE 1
+ /* pack signals are executed */
+#define IMA_SIGNAL_PACK 2
+#define IMA_SIGNAL_REPACK 3
+#define IMA_SIGNAL_UNPACK 4
+ /* source changes, from image to sequence or movie, etc */
+#define IMA_SIGNAL_SRC_CHANGE 5
+ /* image-user gets a new image, check settings */
+#define IMA_SIGNAL_USER_NEW_IMAGE 6
+
+/* depending Image type, and (optional) ImageUser setting it returns ibuf */
+/* always call to make signals work */
+struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
+
+/* returns existing Image when filename/type is same */
+struct Image *BKE_add_image_file(const char *name);
+
+/* adds image, adds ibuf, generates color or pattern */
+struct Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid);
+
+/* for reload, refresh, pack */
+void BKE_image_signal(struct Image *ima, struct ImageUser *iuser, int signal);
+
+/* ensures an Image exists for viewing nodes or render */
+struct Image *BKE_image_verify_viewer(int type, const char *name);
+
+/* force an ImBuf to become part of Image */
+void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
+
+/* called on frame change or before render */
+void BKE_image_user_calc_imanr(struct ImageUser *iuser, int cfra, int fieldnr);
+
+/* fix things in ImageUser when new image gets assigned */
+void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
+
+/* sets index offset for multilayer files */
+struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct ImageUser *iuser);
+
+/* for multilayer images as well as for render-viewer */
+struct RenderResult *BKE_image_get_renderresult(struct Image *ima);
+
+/* goes over all textures that use images */
+void BKE_image_free_all_textures(void);
+
+/* does one image! */
+void BKE_image_free_anim_ibufs(struct Image *ima, int except_frame);
+
+/* does all images with type MOVIE or SEQUENCE */
+void BKE_image_all_free_anim_ibufs(int except_frame);
-void free_all_imagetextures(void);
+void BKE_image_memorypack(struct Image *ima);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index c51ebe25226..cc6d15f7bcb 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -66,6 +66,7 @@ struct ID *find_id(char *type, char *name);
void clear_id_newpoins(void);
void IDnames_to_pupstring(char **str, char *title, char *extraops, struct ListBase *lb,struct ID* link, short *nr);
+void IMAnames_to_pupstring(char **str, char *title, char *extraops, struct ListBase *lb, struct ID *link, short *nr);
void IPOnames_to_pupstring(char **str, char *title, char *extraops, struct ListBase *lb, struct ID* link, short *nr, int blocktype);
#endif
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index f5fe91920b7..232a2a2cd9e 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -42,10 +42,12 @@
#define TRUE 1
#endif
-/* also fill in structs itself, dna cannot handle defines, duplicate in blendef.h still */
+/* these values need to be hardcoded in structs, dna does not recognize defines */
+/* also defined in DNA_space_types.h */
#ifndef FILE_MAXDIR
#define FILE_MAXDIR 160
#define FILE_MAXFILE 80
+#define FILE_MAX 240
#endif
#define ELEM(a, b, c) ( (a)==(b) || (a)==(c) )
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 93238137f95..6249bb2f21b 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -43,6 +43,7 @@
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_ipo.h"
+#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_utildefines.h"
@@ -623,30 +624,43 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const
#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
-void curvemapping_do_image(CurveMapping *cumap, Image *ima)
+void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
{
int pixel;
- if(ima==NULL || ima->ibuf==NULL)
+ if(ibuf==NULL)
return;
- if(ima->ibuf->rect_float==NULL)
- IMB_float_from_rect(ima->ibuf);
- else if(ima->ibuf->rect==NULL)
- imb_addrectImBuf(ima->ibuf);
+ if(ibuf->rect_float==NULL)
+ IMB_float_from_rect(ibuf);
+ else if(ibuf->rect==NULL)
+ imb_addrectImBuf(ibuf);
curvemapping_premultiply(cumap, 0);
- if(ima->ibuf->rect_float && ima->ibuf->rect) {
- float *pixf= ima->ibuf->rect_float;
+ if(ibuf->rect_float && ibuf->rect) {
+ float *pixf= ibuf->rect_float;
float col[3];
- char *pixc= (char *)ima->ibuf->rect;
+ int stride= 4;
+ char *pixc= (char *)ibuf->rect;
- for(pixel= ima->ibuf->x*ima->ibuf->y; pixel>0; pixel--, pixf+=4, pixc+=4) {
- curvemapping_evaluate_premulRGBF(cumap, col, pixf);
- pixc[0]= FTOCHAR(col[0]);
- pixc[1]= FTOCHAR(col[1]);
- pixc[2]= FTOCHAR(col[2]);
- pixc[3]= FTOCHAR(pixf[3]);
+ if(ibuf->channels)
+ stride= ibuf->channels;
+
+ for(pixel= ibuf->x*ibuf->y; pixel>0; pixel--, pixf+=stride, pixc+=4) {
+ if(stride<3) {
+ col[0]= curvemap_evaluateF(cumap->cm, *pixf);
+ pixc[1]= pixc[2]= pixc[3]= pixc[0]= FTOCHAR(col[0]);
+ }
+ else {
+ curvemapping_evaluate_premulRGBF(cumap, col, pixf);
+ pixc[0]= FTOCHAR(col[0]);
+ pixc[1]= FTOCHAR(col[1]);
+ pixc[2]= FTOCHAR(col[2]);
+ if(stride>3)
+ pixc[3]= FTOCHAR(pixf[3]);
+ else
+ pixc[3]= 255;
+ }
}
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index cf19d64ca03..b8a6ebf8928 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2,15 +2,12 @@
*
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,9 +23,9 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Blender Foundation, 2006
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
#include <stdio.h>
@@ -47,85 +44,278 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "intern/openexr/openexr_multi.h"
#include "DNA_image_types.h"
-#include "DNA_texture_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
-#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
#include "BKE_bmfont.h"
-#include "BKE_packedFile.h"
-#include "BKE_library.h"
#include "BKE_global.h"
-#include "BKE_main.h"
#include "BKE_icons.h"
#include "BKE_image.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_packedFile.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
#include "PIL_time.h"
+#include "RE_pipeline.h"
+
/* bad level; call to free_realtime_image */
#include "BKE_bad_level_calls.h"
-void free_image_buffers(Image *ima)
+/* max int, to indicate we don't store sequences in ibuf */
+#define IMA_NO_INDEX 0x7FEFEFEF
+
+/* quick lookup: supports 1 million frames, thousand passes */
+#define IMA_MAKE_INDEX(frame, index) ((frame)<<10)+index
+#define IMA_INDEX_FRAME(index) (index>>10)
+
+/* ******** IMAGE PROCESSING ************* */
+
+/* used by sequencer */
+void converttopremul(struct ImBuf *ibuf)
{
- unsigned int a;
+ int x, y, val;
+ char *cp;
+
+ if(ibuf==0) return;
+ if(ibuf->depth==24) { /* put alpha at 255 */
+
+ cp= (char *)(ibuf->rect);
+ for(y=0; y<ibuf->y; y++) {
+ for(x=0; x<ibuf->x; x++, cp+=4) {
+ cp[3]= 255;
+ }
+ }
+ return;
+ }
- if(ima->ibuf) {
- if (ima->ibuf->userdata) {
- MEM_freeN(ima->ibuf->userdata);
- ima->ibuf->userdata = NULL;
+ cp= (char *)(ibuf->rect);
+ for(y=0; y<ibuf->y; y++) {
+ for(x=0; x<ibuf->x; x++, cp+=4) {
+ if(cp[3]==0) {
+ cp[0]= cp[1]= cp[2]= 0;
+ }
+ else if(cp[3]!=255) {
+ val= cp[3];
+ cp[0]= (cp[0]*val)>>8;
+ cp[1]= (cp[1]*val)>>8;
+ cp[2]= (cp[2]*val)>>8;
+ }
}
- IMB_freeImBuf(ima->ibuf);
- ima->ibuf= NULL;
}
- if(ima->anim) IMB_free_anim(ima->anim);
- ima->anim= NULL;
+}
+
+static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
+{
+ struct ImBuf * tbuf1, * tbuf2;
- for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
- if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
- ima->mipmap[a]= NULL;
+ if (ibuf == 0) return;
+ if (ibuf->flags & IB_fields) return;
+ ibuf->flags |= IB_fields;
+
+ if (ibuf->rect) {
+ /* make copies */
+ tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
+ tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
+
+ ibuf->x *= 2;
+
+ IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
+ IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+
+ ibuf->x /= 2;
+ IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y);
+ IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y);
+
+ IMB_freeImBuf(tbuf1);
+ IMB_freeImBuf(tbuf2);
}
+ ibuf->y /= 2;
+}
+
+static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */
+{
+ struct ImBuf * tbuf1, * tbuf2;
- free_realtime_image(ima);
+ if (ibuf == 0) return;
+ if (ibuf->flags & IB_fields) return;
+ ibuf->flags |= IB_fields;
+
+ if (ibuf->rect) {
+ /* make copies */
+ tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
+ tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
+
+ ibuf->x *= 2;
+
+ IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
+ IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+
+ ibuf->x /= 2;
+ IMB_rectcpy(ibuf, tbuf2, 0, 0, 0, 0, tbuf2->x, tbuf2->y);
+ IMB_rectcpy(ibuf, tbuf1, 0, tbuf2->y, 0, 0, tbuf1->x, tbuf1->y);
+
+ IMB_freeImBuf(tbuf1);
+ IMB_freeImBuf(tbuf2);
+ }
+ ibuf->y /= 2;
+}
+
+void image_de_interlace(Image *ima, int odd)
+{
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ if(ibuf) {
+ if(odd)
+ de_interlace_st(ibuf);
+ else
+ de_interlace_ng(ibuf);
+ }
}
-void free_image_preview(struct Image *ima)
+/* ***************** ALLOC & FREE, DATA MANAGING *************** */
+
+static void image_free_buffers(Image *ima)
{
+ ImBuf *ibuf;
+
+ while((ibuf = ima->ibufs.first)) {
+ BLI_remlink(&ima->ibufs, ibuf);
+
+ if (ibuf->userdata) {
+ MEM_freeN(ibuf->userdata);
+ ibuf->userdata = NULL;
+ }
+ IMB_freeImBuf(ibuf);
+ }
+
+ if(ima->anim) IMB_free_anim(ima->anim);
+ ima->anim= NULL;
+
if (ima->preview) {
MEM_freeN(ima->preview->rect);
MEM_freeN(ima->preview);
- ima->preview = 0;
+ ima->preview = NULL;
}
+
+ if(ima->rr) {
+ RE_FreeRenderResult(ima->rr);
+ ima->rr= NULL;
+ }
+
+ free_realtime_image(ima);
+
+ ima->ok= IMA_OK;
}
+/* called by library too, do not free ima itself */
void free_image(Image *ima)
{
- free_image_buffers(ima);
+ image_free_buffers(ima);
if (ima->packedfile) {
freePackedFile(ima->packedfile);
ima->packedfile = NULL;
}
- free_image_preview(ima);
BKE_icon_delete(&ima->id);
ima->id.icon_id = 0;
}
+/* only image block itself */
+static Image *image_alloc(const char *name, short source, short type)
+{
+ Image *ima;
+
+ ima= alloc_libblock(&G.main->image, ID_IM, name);
+ if(ima) {
+ ima->ok= IMA_OK;
+
+ ima->xrep= ima->yrep= 1;
+ ima->gen_x= 256; ima->gen_y= 256;
+ ima->gen_type= 1; /* no defines yet? */
+
+ ima->source= source;
+ ima->type= type;
+ }
+ return ima;
+}
+
+/* get the ibuf from an image cache, local use here only */
+static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
+{
+ if(index==IMA_NO_INDEX)
+ return ima->ibufs.first;
+ else {
+ ImBuf *ibuf;
+
+ index= IMA_MAKE_INDEX(frame, index);
+ for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next)
+ if(ibuf->index==index)
+ return ibuf;
+ return NULL;
+ }
+}
+
+/* no ima->ibuf anymore, but listbase */
+static void image_remove_ibuf(Image *ima, ImBuf *ibuf)
+{
+ if(ibuf) {
+ BLI_remlink(&ima->ibufs, ibuf);
+ IMB_freeImBuf(ibuf);
+ }
+}
+
+
+/* no ima->ibuf anymore, but listbase */
+static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
+{
+ if(ibuf) {
+ ImBuf *link;
+
+ if(index!=IMA_NO_INDEX)
+ index= IMA_MAKE_INDEX(frame, index);
+
+ /* insert based on index */
+ for(link= ima->ibufs.first; link; link= link->next)
+ if(link->index>=index)
+ break;
+ /* now we don't want copies? */
+ if(link && ibuf->index==link->index) {
+ ImBuf *prev= ibuf->prev;
+ image_remove_ibuf(ima, link);
+ link= prev;
+ }
+
+ /* this function accepts link==NULL */
+ BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
+
+ ibuf->index= index;
+ }
+
+}
-Image *add_image(char *name)
+/* checks if image was already loaded, then returns same image */
+/* otherwise creates new. */
+/* does not load ibuf itself */
+Image *BKE_add_image_file(const char *name)
{
Image *ima;
int file, len;
- char *libname, str[256], strtest[256];
+ const char *libname;
+ char str[FILE_MAX], strtest[FILE_MAX];
- strcpy(str, name);
+ BLI_strncpy(str, name, sizeof(str));
BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
file= open(str, O_BINARY|O_RDONLY);
@@ -133,135 +323,188 @@ Image *add_image(char *name)
close(file);
/* first search an identical image */
- ima= G.main->image.first;
- while(ima) {
- strcpy(strtest, ima->name);
- BLI_convertstringcode(strtest, G.sce, G.scene->r.cfra);
- if( strcmp(strtest, str)==0 ) {
- if(ima->anim==0 || ima->id.us==0) {
- strcpy(ima->name, name); /* for stringcode */
- ima->id.us++; /* officially should not, it doesn't link here! */
- ima->ok= 1;
- return ima;
+ for(ima= G.main->image.first; ima; ima= ima->id.next) {
+ if(ima->source!=IMA_SRC_VIEWER) {
+ BLI_strncpy(strtest, ima->name, sizeof(ima->name));
+ BLI_convertstringcode(strtest, G.sce, G.scene->r.cfra);
+
+ if( strcmp(strtest, str)==0 ) {
+ if(ima->anim==NULL || ima->id.us==0) {
+ BLI_strncpy(ima->name, name, sizeof(ima->name)); /* for stringcode */
+ ima->id.us++; /* officially should not, it doesn't link here! */
+ if(ima->ok==0)
+ ima->ok= IMA_OK;
+ /* RETURN! */
+ return ima;
+ }
}
}
- ima= ima->id.next;
}
-
+ /* add new image */
+
+ /* create a short library name */
len= strlen(name);
while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') len--;
libname= name+len;
- ima= alloc_libblock(&G.main->image, ID_IM, libname);
- strcpy(ima->name, name);
- ima->ok= 1;
+ ima= image_alloc(libname, IMA_SRC_FILE, IMA_TYPE_IMAGE);
+ BLI_strncpy(ima->name, name, sizeof(ima->name));
- ima->xrep= ima->yrep= 1;
+ /* do a wild guess! */
+ if(BLI_testextensie(name, ".avi") || BLI_testextensie(name, ".mov")
+ || BLI_testextensie(name, ".mpg") || BLI_testextensie(name, ".mp4"))
+ ima->source= IMA_SRC_MOVIE;
return ima;
}
-Image *new_image(int width, int height, char *name, short uvtestgrid)
+static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid)
{
- Image *ima;
-
- ima = alloc_libblock(&G.main->image, ID_IM, name);
+ ImBuf *ibuf;
+ float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
+ unsigned char *rect;
+ int x, y;
+ int checkerwidth=21, dark=1;
- if (ima)
- {
- ImBuf *ibuf;
- unsigned char *rect;
- int x, y;
- int checkerwidth=21, dark=1;
- float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
-
- strcpy(ima->name, "Untitled");
-
- ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0);
- strcpy(ibuf->name, "Untitled");
- ima->ibuf= ibuf;
- ibuf->userflags |= IB_BITMAPDIRTY;
-
- rect= (unsigned char*)ibuf->rect;
+ ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0);
+ strcpy(ibuf->name, "Untitled");
+ ibuf->userflags |= IB_BITMAPDIRTY;
+
+ rect= (unsigned char*)ibuf->rect;
+
+ if (uvtestgrid) {
+ /* these two passes could be combined into one, but it's more readable and
+ * easy to tweak like this, speed isn't really that much of an issue in this situation... */
- if (uvtestgrid) {
- /* these two passes could be combined into one, but it's more readable and
- * easy to tweak like this, speed isn't really that much of an issue in this situation... */
-
- /* checkers */
- for(y=0; y<ibuf->y; y++) {
- dark = pow(-1, floor(y / checkerwidth));
+ /* checkers */
+ for(y=0; y<ibuf->y; y++) {
+ dark = pow(-1, floor(y / checkerwidth));
+
+ for(x=0; x<ibuf->x; x++, rect+=4) {
+ if (x % checkerwidth == 0) dark *= -1;
- for(x=0; x<ibuf->x; x++, rect+=4) {
- if (x % checkerwidth == 0) dark *= -1;
-
- if (dark > 0) {
- rect[0] = rect[1] = rect[2] = 64;
- rect[3] = 255;
- } else {
- rect[0] = rect[1] = rect[2] = 150;
- rect[3] = 255;
- }
+ if (dark > 0) {
+ rect[0] = rect[1] = rect[2] = 64;
+ rect[3] = 255;
+ } else {
+ rect[0] = rect[1] = rect[2] = 150;
+ rect[3] = 255;
}
}
-
- /* 2nd pass, coloured + */
- rect= (unsigned char*)ibuf->rect;
+ }
+
+ /* 2nd pass, coloured + */
+ rect= (unsigned char*)ibuf->rect;
+
+ for(y=0; y<ibuf->y; y++) {
+ hoffs = 0.125 * floor(y / checkerwidth);
- for(y=0; y<ibuf->y; y++) {
- hoffs = 0.125 * floor(y / checkerwidth);
+ for(x=0; x<ibuf->x; x++, rect+=4) {
+ h = 0.125 * floor(x / checkerwidth);
- for(x=0; x<ibuf->x; x++, rect+=4) {
- h = 0.125 * floor(x / checkerwidth);
-
- if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
- (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
+ if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
+ (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
+
+ if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
+ (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
- if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
- (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
+ hue = fmod(fabs(h-hoffs), 1.0);
+ hsv_to_rgb(hue, s, v, &r, &g, &b);
- hue = fmod(fabs(h-hoffs), 1.0);
- hsv_to_rgb(hue, s, v, &r, &g, &b);
-
- rect[0]= (char)(r * 255.0);
- rect[1]= (char)(g * 255.0);
- rect[2]= (char)(b * 255.0);
- rect[3]= 255;
- }
+ rect[0]= (char)(r * 255.0);
+ rect[1]= (char)(g * 255.0);
+ rect[2]= (char)(b * 255.0);
+ rect[3]= 255;
}
-
}
+
}
- } else { /* blank image */
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, rect+=4) {
- rect[0]= rect[1]= rect[2]= 0;
- rect[3]= 255;
- }
+ }
+ } else { /* blank image */
+ for(y=0; y<ibuf->y; y++) {
+ for(x=0; x<ibuf->x; x++, rect+=4) {
+ rect[0]= rect[1]= rect[2]= 0;
+ rect[3]= 255;
}
}
+ }
+ return ibuf;
+}
- ima->ok= 1;
- ima->xrep= ima->yrep= 1;
+/* adds new image block, creates ImBuf and initializes color */
+Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid)
+{
+ Image *ima;
+
+ /* on save, type is changed to FILE in editsima.c */
+ ima= image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
+
+ if (ima) {
+ ImBuf *ibuf;
+
+ BLI_strncpy(ima->name, name, FILE_MAX);
+ ima->gen_x= width;
+ ima->gen_y= height;
+ ima->gen_type= uvtestgrid;
+
+ ibuf= add_ibuf_size(width, height, name, uvtestgrid);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+
+ ima->ok= IMA_OK_LOADED;
}
return ima;
}
+/* packs rect from memory as PNG */
+void BKE_image_memorypack(Image *ima)
+{
+ ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+
+ if(ibuf==NULL)
+ return;
+ if (ima->packedfile) {
+ freePackedFile(ima->packedfile);
+ ima->packedfile = NULL;
+ }
+
+ ibuf->ftype= PNG;
+ ibuf->depth= 32;
+
+ IMB_saveiff(ibuf, ibuf->name, IB_rect | IB_mem);
+ if(ibuf->encodedbuffer==NULL) {
+ printf("memory save for pack error\n");
+ }
+ else {
+ PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile");
+
+ pf->data = ibuf->encodedbuffer;
+ pf->size = ibuf->encodedsize;
+ ima->packedfile= pf;
+ ibuf->encodedbuffer= NULL;
+ ibuf->encodedsize= 0;
+ ibuf->userflags &= ~IB_BITMAPDIRTY;
+
+ if(ima->source==IMA_SRC_GENERATED)
+ ima->source= IMA_SRC_FILE;
+ }
+}
+
void tag_image_time(Image *ima)
{
if (ima)
ima->lastused = (int)PIL_check_seconds_timer();
}
-void tag_all_images_time() {
+void tag_all_images_time()
+{
Image *ima;
int ctime = (int)PIL_check_seconds_timer();
ima= G.main->image.first;
while(ima) {
- if(ima->bindcode || ima->repbind || ima->ibuf) {
+ if(ima->bindcode || ima->repbind || ima->ibufs.first) {
ima->lastused = ctime;
}
}
@@ -294,29 +537,15 @@ void free_old_images()
ima->lastused = ctime;
}
/* Otherwise, just kill the buffers */
- else if (ima->ibuf) {
- free_image_buffers(ima);
+ else if (ima->ibufs.first) {
+ image_free_buffers(ima);
}
}
ima = ima->id.next;
}
}
-void free_unused_animimages()
-{
- Image *ima, *nima;
-
- ima= G.main->image.first;
- while(ima) {
- nima= ima->id.next;
- if(ima->id.us==0) {
- if(ima->flag & IMA_FROMANIM) free_libblock(&G.main->image, ima);
- }
- ima= nima;
- }
-}
-
-void free_all_imagetextures(void)
+void BKE_image_free_all_textures(void)
{
Tex *tex;
Image *ima;
@@ -330,19 +559,116 @@ void free_all_imagetextures(void)
tex->ima->id.flag |= LIB_DOIT;
for(ima= G.main->image.first; ima; ima= ima->id.next) {
- if(ima->ibuf && (ima->id.flag & LIB_DOIT)) {
- if(ima->mipmap[0])
- totsize+= 1.33*ima->ibuf->x*ima->ibuf->y*4;
- else
- totsize+= ima->ibuf->x*ima->ibuf->y*4;
- free_image_buffers(ima);
+ if(ima->ibufs.first && (ima->id.flag & LIB_DOIT)) {
+ ImBuf *ibuf;
+ for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) {
+ if(ibuf->mipmap[0])
+ totsize+= 1.33*ibuf->x*ibuf->y*4;
+ else
+ totsize+= ibuf->x*ibuf->y*4;
+ }
+ image_free_buffers(ima);
}
}
- printf("freed total %d MB\n", totsize/(1024*1024));
+ /* printf("freed total %d MB\n", totsize/(1024*1024)); */
}
+/* except_frame is weak, only works for seqs without offset... */
+void BKE_image_free_anim_ibufs(Image *ima, int except_frame)
+{
+ ImBuf *ibuf, *nbuf;
+
+ for(ibuf= ima->ibufs.first; ibuf; ibuf= nbuf) {
+ nbuf= ibuf->next;
+ if(ibuf->userflags & IB_BITMAPDIRTY)
+ continue;
+ if(ibuf->index==IMA_NO_INDEX)
+ continue;
+ if(except_frame!=IMA_INDEX_FRAME(ibuf->index)) {
+ BLI_remlink(&ima->ibufs, ibuf);
+
+ if (ibuf->userdata) {
+ MEM_freeN(ibuf->userdata);
+ ibuf->userdata = NULL;
+ }
+ IMB_freeImBuf(ibuf);
+ }
+ }
+}
+
+void BKE_image_all_free_anim_ibufs(int cfra)
+{
+ Image *ima;
+
+ for(ima= G.main->image.first; ima; ima= ima->id.next)
+ if(ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE))
+ BKE_image_free_anim_ibufs(ima, cfra);
+}
+
+
/* *********** READ AND WRITE ************** */
+int BKE_imtype_to_ftype(int imtype)
+{
+ if(imtype==0)
+ return TGA;
+ else if(imtype== R_IRIS)
+ return IMAGIC;
+ else if (imtype==R_RADHDR)
+ return RADHDR;
+ else if (imtype==R_PNG)
+ return PNG;
+ else if (imtype==R_BMP)
+ return BMP;
+ else if (imtype==R_TIFF)
+ return TIF;
+ else if (imtype==R_OPENEXR || imtype==R_MULTILAYER)
+ return OPENEXR;
+ else if (imtype==R_CINEON)
+ return CINEON;
+ else if (imtype==R_DPX)
+ return DPX;
+ else if (imtype==R_TARGA)
+ return TGA;
+ else if(imtype==R_RAWTGA)
+ return RAWTGA;
+ else if(imtype==R_HAMX)
+ return AN_hamx;
+ else
+ return JPG|90;
+}
+
+int BKE_ftype_to_imtype(int ftype)
+{
+ if(ftype==0)
+ return TGA;
+ else if(ftype == IMAGIC)
+ return R_IRIS;
+ else if (ftype & RADHDR)
+ return R_RADHDR;
+ else if (ftype & PNG)
+ return R_PNG;
+ else if (ftype & BMP)
+ return R_BMP;
+ else if (ftype & TIF)
+ return R_TIFF;
+ else if (ftype & OPENEXR)
+ return R_OPENEXR;
+ else if (ftype & CINEON)
+ return R_CINEON;
+ else if (ftype & DPX)
+ return R_DPX;
+ else if (ftype & TGA)
+ return R_TARGA;
+ else if(ftype & RAWTGA)
+ return R_RAWTGA;
+ else if(ftype == AN_hamx)
+ return R_HAMX;
+ else
+ return R_JPEG90;
+}
+
+
int BKE_imtype_is_movie(int imtype)
{
switch(imtype) {
@@ -395,7 +721,7 @@ void BKE_add_image_extension(char *string, int imtype)
extension= ".tif";
}
#ifdef WITH_OPENEXR
- else if(imtype==R_OPENEXR) {
+ else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) {
if(!BLI_testextensie(string, ".exr"))
extension= ".exr";
}
@@ -437,7 +763,7 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
ibuf->ftype= TIF;
}
#ifdef WITH_OPENEXR
- else if (imtype==R_OPENEXR) {
+ else if (imtype==R_OPENEXR || imtype==R_MULTILAYER) {
ibuf->ftype= OPENEXR;
if(subimtype & R_OPENEXR_HALF)
ibuf->ftype |= OPENEXR_HALF;
@@ -488,7 +814,7 @@ void BKE_makepicstring(char *string, char *base, int frame, int imtype)
if (string==NULL) return;
- BLI_strncpy(string, base, FILE_MAXDIR + FILE_MAXFILE - 10); /* weak assumption */
+ BLI_strncpy(string, base, FILE_MAX - 10); /* weak assumption */
BLI_convertstringcode(string, G.sce, frame);
len= strlen(string);
@@ -506,43 +832,7 @@ void BKE_makepicstring(char *string, char *base, int frame, int imtype)
}
-/* ******** IMAGE WRAPPING INIT ************* */
-
-/* used by sequencer, texture */
-void converttopremul(struct ImBuf *ibuf)
-{
- int x, y, val;
- char *cp;
-
- if(ibuf==0) return;
- if(ibuf->depth==24) { /* put alpha at 255 */
-
- cp= (char *)(ibuf->rect);
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- cp[3]= 255;
- }
- }
- return;
- }
-
- cp= (char *)(ibuf->rect);
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- if(cp[3]==0) {
- cp[0]= cp[1]= cp[2]= 0;
- }
- else if(cp[3]!=255) {
- val= cp[3];
- cp[0]= (cp[0]*val)>>8;
- cp[1]= (cp[1]*val)>>8;
- cp[2]= (cp[2]*val)>>8;
- }
- }
- }
-}
-
-/* used by sequencer, texture */
+/* used by sequencer too */
struct anim *openanim(char *name, int flags)
{
struct anim *anim;
@@ -562,198 +852,656 @@ struct anim *openanim(char *name, int flags)
return(anim);
}
+/* ************************* New Image API *************** */
+
+
+/* Notes about Image storage
+- packedfile
+ -> written in .blend
+- filename
+ -> written in .blend
+- movie
+ -> comes from packedfile or filename
+- renderresult
+ -> comes from packedfile or filename
+- listbase
+ -> ibufs from exrhandle
+- flipbook array
+ -> ibufs come from movie, temporary renderresult or sequence
+- ibuf
+ -> comes from packedfile or filename or generated
-/*
-load_image handles reading the image from disk or from the packedfile.
*/
-void load_image(Image * ima, int flags, char *relabase, int framenum)
-{
- char name[FILE_MAXDIR + FILE_MAXFILE];
- if(ima->id.lib) relabase= ima->id.lib->filename;
+/* forces existance of 1 Image for renderout or nodes, returns Image */
+/* name is only for default, when making new one */
+Image *BKE_image_verify_viewer(int type, const char *name)
+{
+ Image *ima;
- if (ima->ibuf == NULL) {
-
- // is there a PackedFile with this image ?;
- if (ima->packedfile) {
- ima->ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, flags);
- } else {
- strcpy(name, ima->name);
- BLI_convertstringcode(name, relabase, framenum);
+ for(ima=G.main->image.first; ima; ima= ima->id.next)
+ if(ima->source==IMA_SRC_VIEWER)
+ if(ima->type==type)
+ break;
+
+ if(ima==NULL)
+ ima= image_alloc(name, IMA_SRC_VIEWER, type);
+
+ /* happens on reload, imagewindow cannot be image user when hidden*/
+ if(ima->id.us==0)
+ id_us_plus(&ima->id);
- ima->ibuf = IMB_loadiffname(name , flags);
- }
- // check if the image is a font image...
- // printf("Checking for font\n");
+ return ima;
+}
- if (ima->ibuf) {
- detectBitmapFont(ima->ibuf);
- /* preview is NULL when it has never been used as an icon before */
- if(G.background==0 && ima->preview==NULL)
- BKE_icon_changed(BKE_icon_getid(&ima->id));
+void BKE_image_assign_ibuf(Image *ima, ImBuf *ibuf)
+{
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+}
+void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
+{
+ if(ima==NULL)
+ return;
+
+ switch(signal) {
+ case IMA_SIGNAL_FREE:
+ image_free_buffers(ima);
+ if(iuser)
+ iuser->ok= 1;
+ break;
+ case IMA_SIGNAL_SRC_CHANGE:
+ if(ima->type==IMA_TYPE_MULTILAYER)
+ image_free_buffers(ima);
+ else if(ima->source==IMA_SRC_GENERATED) {
+ if(ima->gen_x==0 || ima->gen_y==0) {
+ ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+ if(ibuf) {
+ ima->gen_x= ibuf->x;
+ ima->gen_y= ibuf->y;
+ }
+ }
+ }
+ ima->ok= 1;
+ if(iuser)
+ iuser->ok= 1;
+ break;
+
+ case IMA_SIGNAL_RELOAD:
+ /* try to repack file */
+ if(ima->packedfile) {
+ PackedFile *pf;
+ pf = newPackedFile(ima->name);
+ if (pf) {
+ freePackedFile(ima->packedfile);
+ ima->packedfile = pf;
+ image_free_buffers(ima);
+ } else {
+ printf("ERROR: Image not available. Keeping packed image\n");
+ }
}
+ else
+ image_free_buffers(ima);
+
+ if(iuser)
+ iuser->ok= 1;
+
+ break;
+ case IMA_SIGNAL_USER_NEW_IMAGE:
+ if(iuser) {
+ iuser->ok= 1;
+ if(ima->source==IMA_SRC_FILE || ima->source==IMA_SRC_SEQUENCE) {
+ if(ima->type==IMA_TYPE_MULTILAYER) {
+ iuser->multi_index= 0;
+ iuser->layer= iuser->pass= 0;
+ }
+ }
+ }
+ break;
}
}
-
-static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
+/* if layer or pass changes, we need an index for the imbufs list */
+/* note it is called for rendered results, but it doesnt use the index! */
+/* and because rendered results use fake layer/passes, don't correct for wrong indices here */
+RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
{
- struct ImBuf * tbuf1, * tbuf2;
+ RenderLayer *rl;
+ RenderPass *rpass= NULL;
- if (ibuf == 0) return;
- if (ibuf->flags & IB_fields) return;
- ibuf->flags |= IB_fields;
+ if(rr==NULL)
+ return NULL;
- if (ibuf->rect) {
- /* make copies */
- tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
- tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
+ if(iuser) {
+ short index= 0, rl_index= 0, rp_index;
- ibuf->x *= 2;
+ for(rl= rr->layers.first; rl; rl= rl->next, rl_index++) {
+ rp_index= 0;
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next, index++, rp_index++)
+ if(iuser->layer==rl_index && iuser->pass==rp_index)
+ break;
+ if(rpass)
+ break;
+ }
- IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
- IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+ if(rpass)
+ iuser->multi_index= index;
+ else
+ iuser->multi_index= 0;
+ }
+ if(rpass==NULL) {
+ rl= rr->layers.first;
+ if(rl)
+ rpass= rl->passes.first;
+ }
+
+ return rpass;
+}
+
+RenderResult *BKE_image_get_renderresult(Image *ima)
+{
+ if(ima->rr)
+ return ima->rr;
+ if(ima->type==IMA_TYPE_R_RESULT)
+ return RE_GetResult(RE_GetRender(G.scene->id.name));
+ return NULL;
+}
+
+/* after imbuf load, openexr type can return with a exrhandle open */
+/* in that case we have to build a render-result */
+static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
+{
+
+ ima->rr= RE_MultilayerConvert(ibuf->userdata, ibuf->x, ibuf->y);
+ IMB_exr_close(ibuf->userdata);
+ ibuf->userdata= NULL;
+ if(ima->rr)
+ ima->rr->framenr= framenr;
+}
+
+/* common stuff to do with images after loading */
+static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
+{
+
+
+ /* preview is NULL when it has never been used as an icon before */
+ if(G.background==0 && ima->preview==NULL)
+ BKE_icon_changed(BKE_icon_getid(&ima->id));
+
+ /* stringcodes also in ibuf, ibuf->name is used to retrieve original (buttons) */
+ BLI_strncpy(ibuf->name, ima->name, FILE_MAX);
+
+ /* fields */
+ if (ima->flag & IMA_FIELDS) {
+ if(ima->flag & IMA_STD_FIELD) de_interlace_st(ibuf);
+ else de_interlace_ng(ibuf);
+ }
+ /* timer */
+ ima->lastused = clock() / CLOCKS_PER_SEC;
+
+ ima->ok= IMA_OK_LOADED;
+
+}
+
+static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
+{
+ struct ImBuf *ibuf;
+ unsigned short numlen;
+ char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
+
+ ima->lastframe= frame;
+
+ BLI_stringdec(ima->name, head, tail, &numlen);
+ BLI_stringenc(ima->name, head, tail, numlen, frame);
+ BLI_strncpy(name, ima->name, sizeof(name));
+
+ if(ima->id.lib)
+ BLI_convertstringcode(name, ima->id.lib->filename, frame);
+ else
+ BLI_convertstringcode(name, G.sce, frame);
+
+ /* read ibuf */
+ ibuf = IMB_loadiffname(name, IB_rect|IB_multilayer);
+ printf("loaded %s\n", name);
+
+ if (ibuf) {
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ if (ibuf->ftype==OPENEXR && ibuf->userdata) {
+ image_create_multilayer(ima, ibuf, frame);
+ ima->type= IMA_TYPE_MULTILAYER;
+ IMB_freeImBuf(ibuf);
+ ibuf= NULL;
+ }
+ else {
+ image_assign_ibuf(ima, ibuf, 0, frame);
+ image_initialize_after_load(ima, ibuf);
+ }
+ }
+ else
+ ima->ok= 0;
+
+ if(iuser)
+ iuser->ok= ima->ok;
+
+ return ibuf;
+}
+
+static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int frame)
+{
+ struct ImBuf *ibuf= NULL;
+
+ /* either we load from RenderResult, or we have to load a new one */
+
+ /* check for new RenderResult */
+ if(ima->rr==NULL || frame!=ima->rr->framenr) {
+ /* copy to survive not found multilayer image */
+ RenderResult *oldrr= ima->rr;
+
+ ima->rr= NULL;
+ ibuf = image_load_sequence_file(ima, iuser, frame);
- ibuf->x /= 2;
- IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y);
- IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y);
+ if(ibuf) { /* actually an error */
+ ima->type= IMA_TYPE_IMAGE;
+ printf("error, multi is normal image\n");
+ }
+ // printf("loaded new result %p\n", ima->rr);
+ /* free result if new one found */
+ if(ima->rr) {
+ // if(oldrr) printf("freed previous result %p\n", oldrr);
+ if(oldrr) RE_FreeRenderResult(oldrr);
+ }
+ else
+ ima->rr= oldrr;
+
+ }
+ if(ima->rr) {
+ RenderPass *rpass= BKE_image_multilayer_index(ima->rr, iuser);
- IMB_freeImBuf(tbuf1);
- IMB_freeImBuf(tbuf2);
+ if(rpass) {
+ // printf("load from pass %s\n", rpass->name);
+ /* since we free render results, we copy the rect */
+ ibuf= IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0, 0);
+ ibuf->rect_float= MEM_dupallocN(rpass->rect);
+ ibuf->flags |= IB_rectfloat;
+ ibuf->mall= IB_rectfloat;
+ ibuf->channels= rpass->channels;
+
+ image_assign_ibuf(ima, ibuf, iuser->multi_index, frame);
+ image_initialize_after_load(ima, ibuf);
+
+ }
+ // else printf("pass not found\n");
}
- ibuf->y /= 2;
+ else
+ ima->ok= 0;
+
+ if(iuser)
+ iuser->ok= ima->ok;
+
+ return ibuf;
}
-static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */
+
+static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
{
- struct ImBuf * tbuf1, * tbuf2;
+ struct ImBuf *ibuf= NULL;
- if (ibuf == 0) return;
- if (ibuf->flags & IB_fields) return;
- ibuf->flags |= IB_fields;
+ ima->lastframe= frame;
- if (ibuf->rect) {
- /* make copies */
- tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
- tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
+ if(ima->anim==NULL) {
+ char str[FILE_MAX];
- ibuf->x *= 2;
+ BLI_strncpy(str, ima->name, FILE_MAX);
+ if(ima->id.lib)
+ BLI_convertstringcode(str, ima->id.lib->filename, 0);
+ else
+ BLI_convertstringcode(str, G.sce, 0);
- IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
- IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+ ima->anim = openanim(str, IB_cmap | IB_rect);
- ibuf->x /= 2;
- IMB_rectcpy(ibuf, tbuf2, 0, 0, 0, 0, tbuf2->x, tbuf2->y);
- IMB_rectcpy(ibuf, tbuf1, 0, tbuf2->y, 0, 0, tbuf1->x, tbuf1->y);
+ /* let's initialize this user */
+ if(ima->anim && iuser && iuser->frames==0)
+ iuser->frames= IMB_anim_get_duration(ima->anim);
+ }
+
+ if(ima->anim) {
+ int dur = IMB_anim_get_duration(ima->anim);
+ int fra= frame-1;
- IMB_freeImBuf(tbuf1);
- IMB_freeImBuf(tbuf2);
+ if(fra<0) fra = 0;
+ if(fra>(dur-1)) fra= dur-1;
+ ibuf = IMB_anim_absolute(ima->anim, fra);
+
+ if(ibuf) {
+ image_assign_ibuf(ima, ibuf, 0, frame);
+ image_initialize_after_load(ima, ibuf);
+ }
+ else
+ ima->ok= 0;
}
- ibuf->y /= 2;
+ else
+ ima->ok= 0;
+
+ if(iuser)
+ iuser->ok= ima->ok;
+
+ return ibuf;
}
-void image_de_interlace(Image *ima, int odd)
+/* cfra used for # code, Image can only have this # for all its users */
+static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
{
- if(odd)
- de_interlace_st(ima->ibuf);
+ struct ImBuf *ibuf;
+ char str[FILE_MAX];
+
+ /* always ensure clean ima */
+ image_free_buffers(ima);
+
+ /* is there a PackedFile with this image ? */
+ if (ima->packedfile) {
+ ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, IB_rect|IB_multilayer);
+ }
+ else {
+
+ /* get the right string */
+ BLI_strncpy(str, ima->name, sizeof(str));
+ if(ima->id.lib)
+ BLI_convertstringcode(str, ima->id.lib->filename, cfra);
+ else
+ BLI_convertstringcode(str, G.sce, cfra);
+
+ /* read ibuf */
+ ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer);
+ }
+
+ if (ibuf) {
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ if (ibuf->ftype==OPENEXR && ibuf->userdata) {
+ image_create_multilayer(ima, ibuf, cfra);
+ ima->type= IMA_TYPE_MULTILAYER;
+ IMB_freeImBuf(ibuf);
+ ibuf= NULL;
+ }
+ else {
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ image_initialize_after_load(ima, ibuf);
+
+ /* check if the image is a font image... */
+ detectBitmapFont(ibuf);
+
+ /* make packed file for autopack */
+ if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK))
+ ima->packedfile = newPackedFile(str);
+ }
+ }
else
- de_interlace_ng(ima->ibuf);
+ ima->ok= 0;
+
+ if(iuser)
+ iuser->ok= ima->ok;
+
+ return ibuf;
}
-void ima_ibuf_is_nul(Tex *tex, Image *ima)
+static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
{
- void (*de_interlacefunc)(struct ImBuf *ibuf);
- unsigned int a;
- int fra, dur;
- char str[FILE_MAXDIR+FILE_MAXFILE], *cp;
+ ImBuf *ibuf= NULL;
- if(ima==0) return;
+ if(ima->rr==NULL) {
+ ibuf = image_load_image_file(ima, iuser, 0);
+ if(ibuf) { /* actually an error */
+ ima->type= IMA_TYPE_IMAGE;
+ return ibuf;
+ }
+ }
+ if(ima->rr) {
+ RenderPass *rpass= BKE_image_multilayer_index(ima->rr, iuser);
+
+ if(rpass) {
+ ibuf= IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0, 0);
+
+ image_assign_ibuf(ima, ibuf, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
+ image_initialize_after_load(ima, ibuf);
+
+ ibuf->rect_float= rpass->rect;
+ ibuf->flags |= IB_rectfloat;
+ ibuf->channels= rpass->channels;
+ }
+ }
- strcpy(str, ima->name);
- if(ima->id.lib)
- BLI_convertstringcode(str, ima->id.lib->filename, G.scene->r.cfra);
- else
- BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+ if(ibuf==NULL)
+ ima->ok= 0;
+ if(iuser)
+ iuser->ok= ima->ok;
- if(tex->imaflag & TEX_STD_FIELD) de_interlacefunc= de_interlace_st;
- else de_interlacefunc= de_interlace_ng;
+ return ibuf;
+}
+
+
+/* showing RGBA result itself (from compo/sequence) or
+ like exr, using layers etc */
+static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
+{
+ RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name));
- if(tex->imaflag & TEX_ANIM5) {
+ if(rr && iuser) {
+ RenderResult rres;
+ float *rectf;
+ unsigned int *rect;
+ int channels= 4, layer= iuser->layer;
- if(ima->anim==NULL) ima->anim = openanim(str, IB_cmap | IB_rect);
- if (ima->anim) {
- dur = IMB_anim_get_duration(ima->anim);
-
- fra= ima->lastframe-1;
-
- if(fra<0) fra = 0;
- if(fra>(dur-1)) fra= dur-1;
- ima->ibuf = IMB_anim_absolute(ima->anim, fra);
-
- /* patch for textbutton with name ima (B_NAMEIMA) */
- if(ima->ibuf) {
- strcpy(ima->ibuf->name, ima->name);
- if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf);
+ /* this gives active layer, composite or seqence result */
+ RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+ rect= rres.rect32;
+ rectf= rres.rectf;
+
+ /* get compo/seq result by default */
+ if(rr->rectf && layer==0);
+ else if(rr->layers.first) {
+ RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer-(rr->rectf?1:0));
+ if(rl) {
+ /* there's no combined pass, is in renderlayer itself */
+ if(iuser->pass==0) {
+ rectf= rl->rectf;
+ }
+ else {
+ RenderPass *rpass= BLI_findlink(&rl->passes, iuser->pass-1);
+ if(rpass) {
+ channels= rpass->channels;
+ rectf= rpass->rect;
+ }
+ }
}
}
- } else {
- // create a packedfile for this image when autopack is on
- // for performance (IMB_loadiffname uses mmap) we don't do this by default
- if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK)) {
- ima->packedfile = newPackedFile(str);
+ if(rectf || rect) {
+ ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+
+ /* make ibuf if needed, and initialize it */
+ if(ibuf==NULL) {
+ ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, 0, 0);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ }
+ ibuf->x= rr->rectx;
+ ibuf->y= rr->recty;
+
+ if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */
+ imb_freerectImBuf(ibuf);
+ if(rect)
+ ibuf->rect= rect;
+
+ ibuf->rect_float= rectf;
+ ibuf->flags |= IB_rectfloat;
+ ibuf->channels= channels;
+
+ ima->ok= IMA_OK_LOADED;
+ return ibuf;
}
-
- load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
-
- if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf);
}
- if(ima->ibuf) {
+ return NULL;
+}
+
+/* Checks optional ImageUser and verifies/creates ImBuf. */
+/* returns ibuf */
+ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
+{
+ ImBuf *ibuf= NULL;
+
+ /* quick reject tests */
+ if(ima==NULL)
+ return NULL;
+ if(iuser) {
+ if(iuser->ok==0)
+ return NULL;
+ }
+ else if(ima->ok==0)
+ return NULL;
+
+ BLI_lock_thread(LOCK_CUSTOM1);
+
+ /* handle image source and types */
+ if(ima->source==IMA_SRC_MOVIE) {
+ /* source is from single file, use flipbook to store ibuf */
+ int frame= iuser?iuser->framenr:ima->lastframe;
- /* stringcodes also in ibuf. ibuf->name is used as 'undo' (buttons.c) */
- strcpy(ima->ibuf->name, ima->name);
+ ibuf= image_get_ibuf(ima, 0, frame);
+ if(ibuf==NULL)
+ ibuf= image_load_movie_file(ima, iuser, frame);
+ }
+ else if(ima->source==IMA_SRC_SEQUENCE) {
- if(ima->ibuf->cmap) {
+ if(ima->type==IMA_TYPE_IMAGE) {
+ /* regular files, ibufs in flipbook, allows saving */
+ int frame= iuser?iuser->framenr:ima->lastframe;
- if(tex->imaflag & TEX_ANIM5) {
-
- if(tex->imaflag & TEX_MORKPATCH) {
- /**** PATCH TO SET COLOR 2 RIGHT (neogeo..) */
- if(ima->ibuf->maxcol > 4) {
- cp= (char *)(ima->ibuf->cmap+2);
- cp[0]= 0x80;
- }
- }
-
- IMB_applycmap(ima->ibuf);
- IMB_convert_rgba_to_abgr(ima->ibuf);
-
- }
+ ibuf= image_get_ibuf(ima, 0, frame);
+ if(ibuf==NULL)
+ ibuf= image_load_sequence_file(ima, iuser, frame);
+ else
+ BLI_strncpy(ima->name, ibuf->name, sizeof(ima->name));
+ }
+ /* no else; on load the ima type can change */
+ if(ima->type==IMA_TYPE_MULTILAYER) {
+ /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
+ int frame= iuser?iuser->framenr:ima->lastframe;
+ int index= iuser?iuser->multi_index:IMA_NO_INDEX;
- converttopremul(ima->ibuf);
+ ibuf= image_get_ibuf(ima, index, frame);
+ if(G.rt) printf("seq multi fra %d id %d ibuf %p %s\n", frame, index, ibuf, ima->id.name);
+ if(ibuf==NULL)
+ ibuf= image_load_sequence_multilayer(ima, iuser, frame);
+ else
+ BLI_strncpy(ima->name, ibuf->name, sizeof(ima->name));
+ }
+
+ }
+ else if(ima->source==IMA_SRC_FILE) {
+
+ if(ima->type==IMA_TYPE_IMAGE) {
+ ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+ if(ibuf==NULL)
+ ibuf= image_load_image_file(ima, iuser, G.scene->r.cfra); /* cfra only for '#', this global is OK */
}
+ /* no else; on load the ima type can change */
+ if(ima->type==IMA_TYPE_MULTILAYER) {
+ /* keeps render result, stores ibufs in listbase, allows saving */
+ ibuf= image_get_ibuf(ima, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
+ if(ibuf==NULL)
+ ibuf= image_get_ibuf_multilayer(ima, iuser);
+ }
+
+ }
+ else if(ima->source == IMA_SRC_GENERATED) {
+ /* generated is: ibuf is allocated dynamically */
+ ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
- if(tex->imaflag & TEX_ANTISCALE) {
- IMB_clever_double(ima->ibuf);
- IMB_antialias(ima->ibuf);
+ if(ibuf==NULL) {
+ if(ima->type==IMA_TYPE_VERSE) {
+ /* todo */
+ }
+ else { /* always fall back to IMA_TYPE_UV_TEST */
+ /* UV testgrid or black or solid etc */
+ if(ima->gen_x==0) ima->gen_x= 256;
+ if(ima->gen_y==0) ima->gen_y= 256;
+ ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_type);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ }
}
- else if(tex->imaflag & TEX_ANTIALI) IMB_antialias(ima->ibuf);
}
-
- if(ima->ibuf)
- ima->lastused = clock() / CLOCKS_PER_SEC;
- else
- ima->ok= 0;
-
- for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
- if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
- ima->mipmap[a]= 0;
+ else if(ima->source == IMA_SRC_VIEWER) {
+ if(ima->type==IMA_TYPE_R_RESULT) {
+ /* always verify entirely */
+ ibuf= image_get_render_result(ima, iuser);
+ }
+ else if(ima->type==IMA_TYPE_COMPOSITE) {
+ int frame= iuser?iuser->framenr:0;
+
+ /* Composite Viewer, all handled in compositor */
+ ibuf= image_get_ibuf(ima, 0, frame);
+ if(ibuf==NULL) {
+ /* fake ibuf, will be filled in compositor */
+ ibuf= IMB_allocImBuf(256, 256, 32, 0, 0);
+ image_assign_ibuf(ima, ibuf, 0, frame);
+ }
+ }
}
+ if(G.rendering==0)
+ tag_image_time(ima);
+
+ BLI_unlock_thread(LOCK_CUSTOM1);
+
+ return ibuf;
}
+void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
+{
+ int imanr, len;
+
+ /* here (+fie_ima/2-1) makes sure that division happens correctly */
+ len= (iuser->fie_ima*iuser->frames)/2;
+
+ if(len==0) {
+ iuser->framenr= 0;
+ }
+ else {
+ cfra= cfra - iuser->sfra+1;
+
+ /* cyclic */
+ if(iuser->cycl) {
+ cfra= ( (cfra) % len );
+ if(cfra < 0) cfra+= len;
+ if(cfra==0) cfra= len;
+ }
+
+ if(cfra<1) cfra= 1;
+ else if(cfra>len) cfra= len;
+
+ /* convert current frame to current field */
+ cfra= 2*(cfra);
+ if(fieldnr) cfra++;
+
+ /* transform to images space */
+ imanr= (cfra+iuser->fie_ima-2)/iuser->fie_ima;
+ if(imanr>iuser->frames) imanr= iuser->frames;
+ imanr+= iuser->offset;
+
+ if(iuser->cycl) {
+ imanr= ( (imanr) % len );
+ while(imanr < 0) imanr+= len;
+ if(imanr==0) imanr= len;
+ }
+
+ /* allows image users to handle redraws */
+ if(iuser->flag & IMA_ANIM_ALWAYS)
+ if(imanr!=iuser->framenr)
+ iuser->flag |= IMA_ANIM_REFRESHED;
+
+ iuser->framenr= imanr;
+ if(iuser->ok==0) iuser->ok= 1;
+ }
+}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index b5680f98940..ba19ba5d8b2 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -569,7 +569,9 @@ static void get_flags_for_id(ID *id, char *buf)
sprintf(buf, "%c%c%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
}
-static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr)
+#define IDPUP_NO_VIEWER 1
+
+static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int hideflag)
{
int i, nids= BLI_countlist(lb);
@@ -588,6 +590,10 @@ static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, shor
if (U.uiflag & USER_HIDE_DOT && id->name[2]=='.')
continue;
+ if (hideflag & IDPUP_NO_VIEWER)
+ if (GS(id->name)==ID_IM)
+ if ( ((Image *)id)->source==IMA_SRC_VIEWER )
+ continue;
get_flags_for_id(id, buf);
@@ -681,12 +687,35 @@ void IDnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb,
BLI_dynstr_append(pupds, "|");
}
- IDnames_to_dyn_pupstring(pupds, lb, link, nr);
+ IDnames_to_dyn_pupstring(pupds, lb, link, nr, 0);
*str= BLI_dynstr_get_cstring(pupds);
BLI_dynstr_free(pupds);
}
+/* skips viewer images */
+void IMAnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr)
+{
+ DynStr *pupds= BLI_dynstr_new();
+
+ if (title) {
+ BLI_dynstr_append(pupds, title);
+ BLI_dynstr_append(pupds, "%t|");
+ }
+
+ if (extraops) {
+ BLI_dynstr_append(pupds, extraops);
+ if (BLI_dynstr_get_len(pupds))
+ BLI_dynstr_append(pupds, "|");
+ }
+
+ IDnames_to_dyn_pupstring(pupds, lb, link, nr, IDPUP_NO_VIEWER);
+
+ *str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+}
+
+
// only used by headerbuttons.c
void IPOnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr, int blocktype)
{
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index bb6439d09fb..d10ff6c6d33 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -31,6 +31,7 @@
#include <string.h>
#include "DNA_ID.h"
+#include "DNA_image_types.h"
#include "DNA_node_types.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
@@ -641,7 +642,7 @@ static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **n
{
bNode *node;
bNodeSocket *tsock;
- int index;
+ int index= 0;
for(node= ntree->nodes.first; node; node= node->next) {
for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++)
@@ -807,6 +808,13 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
nbd->samples= 32;
nbd->fac= 1.0f;
}
+ else if(ELEM3(type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+ ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
+ node->storage= iuser;
+ iuser->sfra= 1;
+ iuser->fie_ima= 2;
+ iuser->ok= 1;
+ }
else if(type==CMP_NODE_HUE_SAT) {
NodeHueSat *nhs= MEM_callocN(sizeof(NodeHueSat), "node hue sat");
node->storage= nhs;
@@ -1488,10 +1496,10 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
free_compbuf(sock->ns.data);
sock->ns.data= NULL;
- if(node->preview && node->preview->rect) {
- MEM_freeN(node->preview->rect);
- node->preview->rect= NULL;
- }
+ //if(node->preview && node->preview->rect) {
+ // MEM_freeN(node->preview->rect);
+ // node->preview->rect= NULL;
+ //}
}
}
@@ -1967,6 +1975,14 @@ static void *exec_composite_node(void *node_v)
return 0;
}
+/* should become a type? these are nodes without input, only giving values */
+static int node_only_value(bNode *node)
+{
+ if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
+ return 1;
+ return 0;
+}
+
/* return total of executable nodes, for timecursor */
/* only compositor uses it */
static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
@@ -1991,10 +2007,13 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
node_get_stack(node, thd->stack, nsin, nsout);
/* test the outputs */
- for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
- if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
- node->need_exec= 1;
- break;
+ /* skip value-only nodes (should be in type!) */
+ if(!node_only_value(node)) {
+ for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+ if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
+ node->need_exec= 1;
+ break;
+ }
}
}
@@ -2008,7 +2027,7 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
bNodeLink *link= sock->link;
/* this is the test for a cyclic case */
if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
- if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) {
+ if(sock->link->fromnode->need_exec) {
node->need_exec= 1;
break;
}
@@ -2030,15 +2049,31 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
}
}
totnode++;
- // printf("node needs exec %s\n", node->name);
+ /* printf("node needs exec %s\n", node->name); */
/* tag for getExecutableNode() */
node->exec= 0;
}
- else
+ else {
/* tag for getExecutableNode() */
node->exec= NODE_READY|NODE_FINISHED;
+
+ }
}
+
+ /* last step: set the stack values for only-value nodes */
+ /* just does all now, compared to a full buffer exec this is nothing */
+ if(totnode) {
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->need_exec==0 && node_only_value(node)) {
+ if(node->typeinfo->execfunc) {
+ node_get_stack(node, thd->stack, nsin, nsout);
+ node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
+ }
+ }
+ }
+ }
+
return totnode;
}
@@ -2187,8 +2222,6 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
ntreeEndExecTree(ntree);
- free_unused_animimages();
-
}
diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c
index b35bfba6b3e..9030b072b9d 100644
--- a/source/blender/blenkernel/intern/node_composite.c
+++ b/source/blender/blenkernel/intern/node_composite.c
@@ -600,10 +600,27 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
/* stack order input sockets: col, alpha, z */
if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
+ RenderData *rd= data;
Image *ima= (Image *)node->id;
+ ImBuf *ibuf;
CompBuf *cbuf, *tbuf;
int rectx, recty;
+
+ BKE_image_user_calc_imanr(node->storage, rd->cfra, 0);
+ /* always returns for viewer image, but we check nevertheless */
+ ibuf= BKE_image_get_ibuf(ima, node->storage);
+ if(ibuf==NULL) {
+ printf("node_composit_exec_viewer error\n");
+ return;
+ }
+
+ /* free all in ibuf */
+ imb_freerectImBuf(ibuf);
+ imb_freerectfloatImBuf(ibuf);
+ IMB_freezbuffloatImBuf(ibuf);
+
+ /* get size */
tbuf= in[0]->data?in[0]->data:(in[1]->data?in[1]->data:in[2]->data);
if(tbuf==NULL) {
rectx= 320; recty= 256;
@@ -613,31 +630,16 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
recty= tbuf->y;
}
- if(ima->ibuf==NULL)
- ima->ibuf= IMB_allocImBuf(rectx, recty, 32, 0, 0);
-
- /* cleanup of composit image */
- if(ima->ibuf->rect) {
- MEM_freeN(ima->ibuf->rect);
- ima->ibuf->rect= NULL;
- ima->ibuf->mall &= ~IB_rect;
- }
- if(ima->ibuf->zbuf_float) {
- MEM_freeN(ima->ibuf->zbuf_float);
- ima->ibuf->zbuf_float= NULL;
- ima->ibuf->mall &= ~IB_zbuffloat;
- }
- if(ima->ibuf->rect_float)
- MEM_freeN(ima->ibuf->rect_float);
-
- ima->ibuf->x= rectx;
- ima->ibuf->y= recty;
- ima->ibuf->mall |= IB_rectfloat;
- ima->ibuf->rect_float= MEM_mallocN(4*rectx*recty*sizeof(float), "viewer rect");
+ /* make ibuf, and connect to ima */
+ ibuf->x= rectx;
+ ibuf->y= recty;
+ imb_addrectfloatImBuf(ibuf);
+ ima->ok= IMA_OK_LOADED;
+
/* now we combine the input with ibuf */
cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); /* no alloc*/
- cbuf->rect= ima->ibuf->rect_float;
+ cbuf->rect= ibuf->rect_float;
/* when no alpha, we can simply copy */
if(in[1]->data==NULL) {
@@ -646,10 +648,11 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
else
composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL);
+ /* zbuf option */
if(in[2]->data) {
CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 1);
- ima->ibuf->zbuf_float= zbuf->rect;
- ima->ibuf->mall |= IB_zbuffloat;
+ ibuf->zbuf_float= zbuf->rect;
+ ibuf->mall |= IB_zbuffloat;
composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL);
@@ -674,7 +677,7 @@ static bNodeType cmp_node_viewer= {
/* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW,
/* input sock */ cmp_node_viewer_in,
/* output sock */ NULL,
- /* storage */ "",
+ /* storage */ "ImageUser",
/* execfunc */ node_composit_exec_viewer
};
@@ -706,37 +709,38 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack *
if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
Image *ima= (Image *)node->id;
+ RenderData *rd= data;
+ ImBuf *ibuf;
CompBuf *cbuf, *buf1, *buf2, *mask;
int x, y;
buf1= typecheck_compbuf(in[0]->data, CB_RGBA);
buf2= typecheck_compbuf(in[1]->data, CB_RGBA);
- if(ima->ibuf==NULL)
- ima->ibuf= IMB_allocImBuf(buf1->x, buf1->y, 32, 0, 0);
+ BKE_image_user_calc_imanr(node->storage, rd->cfra, 0);
- /* cleanup of viewer image */
- if(ima->ibuf->rect) {
- MEM_freeN(ima->ibuf->rect);
- ima->ibuf->rect= NULL;
- ima->ibuf->mall &= ~IB_rect;
- }
- if(ima->ibuf->zbuf_float) {
- MEM_freeN(ima->ibuf->zbuf_float);
- ima->ibuf->zbuf_float= NULL;
- ima->ibuf->mall &= ~IB_zbuffloat;
+ /* always returns for viewer image, but we check nevertheless */
+ ibuf= BKE_image_get_ibuf(ima, node->storage);
+ if(ibuf==NULL) {
+ printf("node_composit_exec_viewer error\n");
+ return;
}
- if(ima->ibuf->rect_float)
- MEM_freeN(ima->ibuf->rect_float);
- ima->ibuf->x= buf1->x;
- ima->ibuf->y= buf1->y;
- ima->ibuf->mall |= IB_rectfloat;
- ima->ibuf->rect_float= MEM_mallocN(4*buf1->x*buf1->y*sizeof(float), "viewer rect");
+ /* free all in ibuf */
+ imb_freerectImBuf(ibuf);
+ imb_freerectfloatImBuf(ibuf);
+ IMB_freezbuffloatImBuf(ibuf);
+
+ /* make ibuf, and connect to ima */
+ ibuf->x= buf1->x;
+ ibuf->y= buf1->y;
+ imb_addrectfloatImBuf(ibuf);
+ ima->ok= IMA_OK_LOADED;
+
/* output buf */
cbuf= alloc_compbuf(buf1->x, buf1->y, CB_RGBA, 0); /* no alloc*/
- cbuf->rect= ima->ibuf->rect_float;
+ cbuf->rect= ibuf->rect_float;
/* mask buf */
mask= alloc_compbuf(buf1->x, buf1->y, CB_VAL, 1);
@@ -766,7 +770,7 @@ static bNodeType cmp_node_splitviewer= {
/* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW,
/* input sock */ cmp_node_splitviewer_in,
/* output sock */ NULL,
- /* storage */ "",
+ /* storage */ "ImageUser",
/* execfunc */ node_composit_exec_splitviewer
};
@@ -818,6 +822,8 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
outbuf->malloc= 0;
free_compbuf(outbuf);
+ /* signal for imageviewer to refresh (it converts to byte rects...) */
+ BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
return;
}
}
@@ -900,140 +906,69 @@ static bNodeType cmp_node_output_file= {
};
-/* **************** IMAGE ******************** */
-static bNodeSocketType cmp_node_image_out[]= {
+/* **************** IMAGE (and RenderResult, multilayer image) ******************** */
+
+/* output socket defines */
+#define RRES_OUT_IMAGE 0
+#define RRES_OUT_ALPHA 1
+#define RRES_OUT_Z 2
+#define RRES_OUT_NORMAL 3
+#define RRES_OUT_UV 4
+#define RRES_OUT_VEC 5
+#define RRES_OUT_RGBA 6
+#define RRES_OUT_DIFF 7
+#define RRES_OUT_SPEC 8
+#define RRES_OUT_SHADOW 9
+#define RRES_OUT_AO 10
+#define RRES_OUT_REFLECT 11
+#define RRES_OUT_REFRACT 12
+#define RRES_OUT_RADIO 13
+#define RRES_OUT_INDEXOB 14
+
+static bNodeSocketType cmp_node_rlayers_out[]= {
{ SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "Reflect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, "Radio", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
-static int calcimanr(int cfra, NodeImageAnim *nia)
-{
-
- if(nia->frames==0) return nia->nr;
-
- cfra= cfra - nia->sfra;
-
- /* cyclic */
- if(nia->cyclic)
- cfra= (cfra % nia->frames);
- else if(cfra>=nia->frames)
- cfra= nia->frames-1;
- else if(cfra<0)
- cfra= 0;
-
- cfra+= nia->nr;
-
- if(cfra<1) cfra= 1;
-
- return cfra;
-}
-
-static void animated_image(bNode *node, int cfra)
+/* note: this function is used for multilayer too, to ensure uniform
+ handling with BKE_image_get_ibuf() */
+static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
{
- Image *ima;
- NodeImageAnim *nia;
- int imanr;
-
- ima= (Image *)node->id;
- nia= node->storage;
-
- if(nia && nia->frames && ima && ima->name) { /* frames anim or movie */
-
- imanr= calcimanr(cfra, nia);
-
- if(nia->movie) {
- char str[FILE_MAXDIR+FILE_MAXFILE];
-
- strcpy(str, ima->name);
- if(ima->id.lib)
- BLI_convertstringcode(str, ima->id.lib->filename, cfra);
- else
- BLI_convertstringcode(str, G.sce, cfra);
-
- if(ima->anim==NULL)
- ima->anim = openanim(str, IB_cmap | IB_rect);
-
- if (ima->anim) {
- int dur = IMB_anim_get_duration(ima->anim);
-
- if(imanr < 0) imanr = 0;
- if(imanr > (dur-1)) imanr= dur-1;
-
- BLI_lock_thread(LOCK_CUSTOM1);
- if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
- ima->ibuf = IMB_anim_absolute(ima->anim, imanr);
- BLI_unlock_thread(LOCK_CUSTOM1);
-
- /* patch for textbutton with name ima (B_NAMEIMA) */
- if(ima->ibuf) {
- strcpy(ima->ibuf->name, ima->name);
- ima->ok= 1;
- }
- }
- }
- else {
-
- if(imanr!=ima->lastframe) {
- unsigned short numlen;
- char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE];
-
- strcpy(name, ima->name);
-
- ima->lastframe= imanr;
-
- BLI_stringdec(name, head, tail, &numlen);
- BLI_stringenc(name, head, tail, numlen, imanr);
-
- ima= add_image(name);
-
- if(ima) {
- ima->flag |= IMA_FROMANIM;
- if(node->id) node->id->us--;
- node->id= (ID *)ima;
-
- ima->ok= 1;
- }
- }
- }
- }
-}
-
-static CompBuf *node_composit_get_image(bNode *node, RenderData *rd)
-{
- Image *ima;
+ ImBuf *ibuf;
CompBuf *stackbuf;
+ int type;
- /* animated image? */
- if(node->storage)
- animated_image(node, rd->cfra);
+ ibuf= BKE_image_get_ibuf(ima, iuser);
+ if(ibuf==NULL)
+ return NULL;
- ima= (Image *)node->id;
+ if(ibuf->rect_float==NULL)
+ IMB_float_from_rect(ibuf);
- /* test if image is OK */
- if(ima->ok==0) return NULL;
-
- if(ima->ibuf==NULL) {
- BLI_lock_thread(LOCK_CUSTOM1);
- load_image(ima, IB_rect, G.sce, rd->cfra); /* G.sce is current .blend path */
- BLI_unlock_thread(LOCK_CUSTOM1);
- if(ima->ibuf==NULL) {
- ima->ok= 0;
- return NULL;
- }
- }
- if(ima->ibuf->rect_float==NULL)
- IMB_float_from_rect(ima->ibuf);
+ type= ibuf->channels;
if(rd->scemode & R_COMP_CROP) {
- stackbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->rect_float, ima->ibuf->x, ima->ibuf->y, CB_RGBA);
+ stackbuf= get_cropped_compbuf(&rd->disprect, ibuf->rect_float, ibuf->x, ibuf->y, type);
}
else {
/* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
- stackbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_RGBA, 0);
- stackbuf->rect= ima->ibuf->rect_float;
+ stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, 0);
+ stackbuf->rect= ibuf->rect_float;
}
return stackbuf;
@@ -1041,39 +976,119 @@ static CompBuf *node_composit_get_image(bNode *node, RenderData *rd)
static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
{
- Image *ima= (Image *)node->id;
+ ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage);
CompBuf *zbuf= NULL;
- if(ima->ibuf && ima->ibuf->zbuf_float) {
+ if(ibuf && ibuf->zbuf_float) {
if(rd->scemode & R_COMP_CROP) {
- zbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->zbuf_float, ima->ibuf->x, ima->ibuf->y, CB_VAL);
+ zbuf= get_cropped_compbuf(&rd->disprect, ibuf->zbuf_float, ibuf->x, ibuf->y, CB_VAL);
}
else {
- zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0);
- zbuf->rect= ima->ibuf->zbuf_float;
+ zbuf= alloc_compbuf(ibuf->x, ibuf->y, CB_VAL, 0);
+ zbuf->rect= ibuf->zbuf_float;
}
}
return zbuf;
}
+/* check if layer is available, returns pass buffer */
+static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passtype)
+{
+ RenderPass *rpass;
+ short index;
+
+ for(index=0, rpass= rl->passes.first; rpass; rpass= rpass->next, index++)
+ if(rpass->passtype==passtype)
+ break;
+
+ if(rpass) {
+ CompBuf *cbuf;
+
+ iuser->pass= index;
+ BKE_image_multilayer_index(ima->rr, iuser);
+ cbuf= node_composit_get_image(rd, ima, iuser);
+
+ return cbuf;
+ }
+ return NULL;
+}
+
+void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, Image *ima, ImageUser *iuser)
+{
+ if(out[RRES_OUT_Z]->hasoutput)
+ out[RRES_OUT_Z]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_Z);
+ if(out[RRES_OUT_VEC]->hasoutput)
+ out[RRES_OUT_VEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_VECTOR);
+ if(out[RRES_OUT_NORMAL]->hasoutput)
+ out[RRES_OUT_NORMAL]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_NORMAL);
+ if(out[RRES_OUT_UV]->hasoutput)
+ out[RRES_OUT_UV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_UV);
+
+ if(out[RRES_OUT_RGBA]->hasoutput)
+ out[RRES_OUT_RGBA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RGBA);
+ if(out[RRES_OUT_DIFF]->hasoutput)
+ out[RRES_OUT_DIFF]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE);
+ if(out[RRES_OUT_SPEC]->hasoutput)
+ out[RRES_OUT_SPEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SPEC);
+ if(out[RRES_OUT_SHADOW]->hasoutput)
+ out[RRES_OUT_SHADOW]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SHADOW);
+ if(out[RRES_OUT_AO]->hasoutput)
+ out[RRES_OUT_AO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_AO);
+ if(out[RRES_OUT_REFLECT]->hasoutput)
+ out[RRES_OUT_REFLECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFLECT);
+ if(out[RRES_OUT_REFRACT]->hasoutput)
+ out[RRES_OUT_REFRACT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFRACT);
+ if(out[RRES_OUT_RADIO]->hasoutput)
+ out[RRES_OUT_RADIO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RADIO);
+ if(out[RRES_OUT_INDEXOB]->hasoutput)
+ out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB);
+
+}
+
+
static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
/* image assigned to output */
/* stack order input sockets: col, alpha */
if(node->id) {
- CompBuf *stackbuf= node_composit_get_image(node, data);
+ RenderData *rd= data;
+ Image *ima= (Image *)node->id;
+ ImageUser *iuser= (ImageUser *)node->storage;
+ CompBuf *stackbuf= NULL;
- /* put ibuf on stack */
- out[0]->data= stackbuf;
+ /* first set the right frame number in iuser */
+ BKE_image_user_calc_imanr(iuser, rd->cfra, 0);
+
+ /* force a load, we assume iuser index will be set OK anyway */
+ if(ima->type==IMA_TYPE_MULTILAYER)
+ BKE_image_get_ibuf(ima, iuser);
+ if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
+ RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
+
+ if(rl) {
+ out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED);
+
+ /* go over all layers */
+ outputs_multilayer_get(rd, rl, out, ima, iuser);
+ }
+ }
+ else {
+ stackbuf= node_composit_get_image(rd, ima, iuser);
+
+ /* put image on stack */
+ out[0]->data= stackbuf;
+
+ if(out[2]->hasoutput)
+ out[2]->data= node_composit_get_zimage(node, rd);
+ }
+
+ /* alpha and preview for both types */
if(stackbuf) {
if(out[1]->hasoutput)
out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
-
- if(out[2]->hasoutput)
- out[2]->data= node_composit_get_zimage(node, data);
-
+
generate_preview(node, stackbuf);
}
}
@@ -1087,51 +1102,14 @@ static bNodeType cmp_node_image= {
/* width+range */ 120, 80, 300,
/* class+opts */ NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
/* input sock */ NULL,
- /* output sock */ cmp_node_image_out,
- /* storage */ "NodeImageAnim",
+ /* output sock */ cmp_node_rlayers_out,
+ /* storage */ "ImageUser",
/* execfunc */ node_composit_exec_image
};
/* **************** RENDER RESULT ******************** */
-/* output socket defines */
-#define RRES_OUT_IMAGE 0
-#define RRES_OUT_ALPHA 1
-#define RRES_OUT_Z 2
-#define RRES_OUT_NORMAL 3
-#define RRES_OUT_UV 4
-#define RRES_OUT_VEC 5
-#define RRES_OUT_RGBA 6
-#define RRES_OUT_DIFF 7
-#define RRES_OUT_SPEC 8
-#define RRES_OUT_SHADOW 9
-#define RRES_OUT_AO 10
-#define RRES_OUT_REFLECT 11
-#define RRES_OUT_REFRACT 12
-#define RRES_OUT_RADIO 13
-#define RRES_OUT_INDEXOB 14
-
-static bNodeSocketType cmp_node_rlayers_out[]= {
- { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 0, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "Reflect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, "Radio", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VALUE, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { -1, 0, "" }
-};
-
-
static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode)
{
float *fp= RE_RenderLayerGetPass(rl, passcode);
@@ -1143,9 +1121,9 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in
buftype= CB_VAL;
else if(passcode==SCE_PASS_VECTOR)
buftype= CB_VEC4;
- else if(passcode==SCE_PASS_RGBA)
+ else if(ELEM(passcode, SCE_PASS_COMBINED, SCE_PASS_RGBA))
buftype= CB_RGBA;
-
+
if(rd->scemode & R_COMP_CROP)
buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype);
else {
@@ -1157,6 +1135,38 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in
return NULL;
}
+void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out, int rectx, int recty)
+{
+ if(out[RRES_OUT_Z]->hasoutput)
+ out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_Z);
+ if(out[RRES_OUT_VEC]->hasoutput)
+ out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_VECTOR);
+ if(out[RRES_OUT_NORMAL]->hasoutput)
+ out[RRES_OUT_NORMAL]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_NORMAL);
+ if(out[RRES_OUT_UV]->hasoutput)
+ out[RRES_OUT_UV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_UV);
+
+ if(out[RRES_OUT_RGBA]->hasoutput)
+ out[RRES_OUT_RGBA]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RGBA);
+ if(out[RRES_OUT_DIFF]->hasoutput)
+ out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE);
+ if(out[RRES_OUT_SPEC]->hasoutput)
+ out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SPEC);
+ if(out[RRES_OUT_SHADOW]->hasoutput)
+ out[RRES_OUT_SHADOW]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SHADOW);
+ if(out[RRES_OUT_AO]->hasoutput)
+ out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_AO);
+ if(out[RRES_OUT_REFLECT]->hasoutput)
+ out[RRES_OUT_REFLECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFLECT);
+ if(out[RRES_OUT_REFRACT]->hasoutput)
+ out[RRES_OUT_REFRACT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFRACT);
+ if(out[RRES_OUT_RADIO]->hasoutput)
+ out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RADIO);
+ if(out[RRES_OUT_INDEXOB]->hasoutput)
+ out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
+
+}
+
static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
@@ -1191,33 +1201,8 @@ static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in,
if(out[RRES_OUT_ALPHA]->hasoutput)
out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
- if(out[RRES_OUT_Z]->hasoutput)
- out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_Z);
- if(out[RRES_OUT_VEC]->hasoutput)
- out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_VECTOR);
- if(out[RRES_OUT_NORMAL]->hasoutput)
- out[RRES_OUT_NORMAL]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_NORMAL);
- if(out[RRES_OUT_UV]->hasoutput)
- out[RRES_OUT_UV]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_UV);
-
- if(out[RRES_OUT_RGBA]->hasoutput)
- out[RRES_OUT_RGBA]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RGBA);
- if(out[RRES_OUT_DIFF]->hasoutput)
- out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_DIFFUSE);
- if(out[RRES_OUT_SPEC]->hasoutput)
- out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SPEC);
- if(out[RRES_OUT_SHADOW]->hasoutput)
- out[RRES_OUT_SHADOW]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SHADOW);
- if(out[RRES_OUT_AO]->hasoutput)
- out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_AO);
- if(out[RRES_OUT_REFLECT]->hasoutput)
- out[RRES_OUT_REFLECT]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_REFLECT);
- if(out[RRES_OUT_REFRACT]->hasoutput)
- out[RRES_OUT_REFRACT]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_REFRACT);
- if(out[RRES_OUT_RADIO]->hasoutput)
- out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RADIO);
- if(out[RRES_OUT_INDEXOB]->hasoutput)
- out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_INDEXOB);
+
+ node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty);
generate_preview(node, stackbuf);
}
@@ -3415,10 +3400,6 @@ static void node_composit_exec_dilateerode(void *data, bNode *node, bNodeStack *
CompBuf *stackbuf= dupalloc_compbuf(cbuf);
short i;
- /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
- stackbuf->xof= cbuf->xof;
- stackbuf->yof= cbuf->yof;
-
if (node->custom2 > 0) { // positive, dilate
for (i = 0; i < node->custom2; i++)
morpho_dilate(stackbuf);
@@ -3427,6 +3408,9 @@ static void node_composit_exec_dilateerode(void *data, bNode *node, bNodeStack *
morpho_erode(stackbuf);
}
+ if(cbuf!=in[0]->data)
+ free_compbuf(cbuf);
+
out[0]->data= stackbuf;
}
}
@@ -4673,6 +4657,43 @@ bNodeType *node_all_composit[]= {
/* ******************* parse ************ */
+/* clumsy checking... should do dynamic outputs once */
+static void force_hidden_passes(bNode *node, int passflag)
+{
+ bNodeSocket *sock;
+
+ for(sock= node->outputs.first; sock; sock= sock->next)
+ sock->flag &= ~SOCK_UNAVAIL;
+
+ sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
+ if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
+ if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
+ if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
+ if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
+ if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
+ if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
+ if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
+ if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
+ if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
+ if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
+ if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
+ if(!(passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
+ if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
+
+}
+
/* based on rules, force sockets hidden always */
void ntreeCompositForceHidden(bNodeTree *ntree)
{
@@ -4684,38 +4705,26 @@ void ntreeCompositForceHidden(bNodeTree *ntree)
if( node->type==CMP_NODE_R_LAYERS) {
Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
- if(srl) {
- bNodeSocket *sock;
- for(sock= node->outputs.first; sock; sock= sock->next)
- sock->flag &= ~SOCK_UNAVAIL;
-
- sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
- if(!(srl->passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
- if(!(srl->passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
- if(!(srl->passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
- if(!(srl->passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
- if(!(srl->passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
- if(!(srl->passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
- if(!(srl->passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
- if(!(srl->passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
- if(!(srl->passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
- if(!(srl->passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
- if(!(srl->passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
- if(!(srl->passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
- if(!(srl->passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
+ if(srl)
+ force_hidden_passes(node, srl->passflag);
+ }
+ else if( node->type==CMP_NODE_IMAGE) {
+ Image *ima= (Image *)node->id;
+ if(ima) {
+ if(ima->rr) {
+ ImageUser *iuser= node->storage;
+ RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
+ if(rl)
+ force_hidden_passes(node, rl->passflag);
+ else
+ force_hidden_passes(node, 0);
+ }
+ else if(ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */
+ force_hidden_passes(node, 0);
+ }
}
+ else
+ force_hidden_passes(node, 0);
}
}
@@ -4743,8 +4752,8 @@ void ntreeCompositTagAnimated(bNodeTree *ntree)
for(node= ntree->nodes.first; node; node= node->next) {
if(node->type==CMP_NODE_IMAGE) {
- /* no actual test yet... */
- if(node->storage)
+ Image *ima= (Image *)node->id;
+ if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
NodeTagChanged(ntree, node);
}
else if(node->type==CMP_NODE_TIME)
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 49ad8d2ac67..0cdfda3be5d 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -402,7 +402,7 @@ there was an error or when the user desides to cancel the operation.
*/
-char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
+char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
{
char menu[6 * (FILE_MAXDIR + FILE_MAXFILE + 100)];
char line[FILE_MAXDIR + FILE_MAXFILE + 100];
@@ -413,7 +413,7 @@ char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
if (pf != NULL) {
if (how == PF_ASK) {
- strcpy(menu, "UnPack file%t");
+ sprintf(menu, "UnPack file%%t|Remove Pack %%x%d", PF_REMOVE);
if (strcmp(abs_name, local_name)) {
switch (checkPackedFile(local_name, pf)) {
@@ -460,6 +460,9 @@ char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
case -1:
case PF_KEEP:
break;
+ case PF_REMOVE:
+ temp= abs_name;
+ break;
case PF_USE_LOCAL:
// if file exists use it
if (BLI_exists(local_name)) {
@@ -596,10 +599,10 @@ int unpackImage(Image * ima, int how)
if (newname != NULL) {
ret_value = RET_OK;
freePackedFile(ima->packedfile);
- ima->packedfile = 0;
+ ima->packedfile = NULL;
strcpy(ima->name, newname);
MEM_freeN(newname);
- free_image_buffers(ima);
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
}
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index c656f5cdeb6..40488cf8644 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -68,6 +68,7 @@
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_ipo.h"
+#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 62ac911bea7..341397cba1b 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -455,13 +455,17 @@ void default_tex(Tex *tex)
pit = tex->plugin;
if (pit) {
- varstr= pit->varstr;
- if(varstr) {
- for(a=0; a<pit->vars; a++, varstr++) {
- pit->data[a] = varstr->def;
- }
+ varstr= pit->varstr;
+ if(varstr) {
+ for(a=0; a<pit->vars; a++, varstr++) {
+ pit->data[a] = varstr->def;
}
+ }
}
+
+ tex->iuser.fie_ima= 2;
+ tex->iuser.ok= 1;
+ tex->iuser.frames= 100;
}
/* ------------------------------------------------------------------------- */
@@ -776,7 +780,7 @@ EnvMap *BKE_copy_envmap(EnvMap *env)
envn= MEM_dupallocN(env);
envn->ok= 0;
- for(a=0; a<6; a++) envn->cube[a]= 0;
+ for(a=0; a<6; a++) envn->cube[a]= NULL;
if(envn->ima) id_us_plus((ID *)envn->ima);
return envn;
@@ -786,20 +790,12 @@ EnvMap *BKE_copy_envmap(EnvMap *env)
void BKE_free_envmapdata(EnvMap *env)
{
- Image *ima;
- unsigned int a, part;
+ unsigned int part;
for(part=0; part<6; part++) {
- ima= env->cube[part];
- if(ima) {
- if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
-
- for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
- if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
- }
- MEM_freeN(ima);
- env->cube[part]= 0;
- }
+ if(env->cube[part])
+ IMB_freeImBuf(env->cube[part]);
+ env->cube[part]= NULL;
}
env->ok= 0;
}
diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h
index 1a35cad3a03..58bd3fd6bf6 100644
--- a/source/blender/blenlib/BLI_blenlib.h
+++ b/source/blender/blenlib/BLI_blenlib.h
@@ -96,7 +96,7 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
void BLI_make_exist(char *dir);
void BLI_make_existing_file(char *name);
void BLI_split_dirfile(const char *string, char *dir, char *file);
-int BLI_testextensie(char *str, char *ext);
+int BLI_testextensie(const char *str, const char *ext);
void addlisttolist(ListBase *list1, ListBase *list2);
void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);
void * BLI_findlink(struct ListBase *listbase, int number);
@@ -193,7 +193,7 @@ char* BLI_strdupn(char *str, int len);
* the size of dst)
* @retval Returns dst
*/
-char* BLI_strncpy(char *dst, char *src, int maxncpy);
+char* BLI_strncpy(char *dst, const char *src, int maxncpy);
/**
* Compare two strings
diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c
index fbbc42115d5..e52c573eec7 100644
--- a/source/blender/blenlib/intern/gsqueue.c
+++ b/source/blender/blenlib/intern/gsqueue.c
@@ -81,7 +81,14 @@ void BLI_gsqueue_pop(GSQueue *gq, void *item_r)
}
void BLI_gsqueue_push(GSQueue *gq, void *item)
{
- GSQueueElem *elem= MEM_mallocN(sizeof(*elem)+gq->elem_size, "gqueue_push");
+ GSQueueElem *elem;
+
+ /* compare: prevent events added double in row */
+ if (!BLI_gsqueue_is_empty(gq)) {
+ if(0==memcmp(item, &gq->head[1], gq->elem_size))
+ return;
+ }
+ elem= MEM_mallocN(sizeof(*elem)+gq->elem_size, "gqueue_push");
memcpy(&elem[1], item, gq->elem_size);
elem->next= NULL;
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index 9fd5b40878e..29e15068f15 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -638,7 +638,7 @@ char *BLI_strdup(char *str) {
return BLI_strdupn(str, strlen(str));
}
-char *BLI_strncpy(char *dst, char *src, int maxncpy) {
+char *BLI_strncpy(char *dst, const char *src, int maxncpy) {
int srclen= strlen(src);
int cpylen= (srclen>(maxncpy-1))?(maxncpy-1):srclen;
@@ -1117,7 +1117,7 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
BLI_clean(string);
}
-int BLI_testextensie(char *str, char *ext)
+int BLI_testextensie(const char *str, const char *ext)
{
short a, b;
int retval;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 342f3232d22..48eb6ae8e55 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -120,7 +120,7 @@
#include "BKE_effect.h" // for give_parteff
#include "BKE_global.h" // for G
#include "BKE_group.h"
-#include "BKE_property.h" // for get_property
+#include "BKE_image.h"
#include "BKE_lattice.h"
#include "BKE_library.h" // for wich_libbase
#include "BKE_main.h" // for Main
@@ -128,6 +128,7 @@
#include "BKE_modifier.h"
#include "BKE_node.h" // for tree type defines
#include "BKE_object.h"
+#include "BKE_property.h" // for get_property
#include "BKE_sca.h" // for init_actuator
#include "BKE_scene.h"
#include "BKE_softbody.h" // sbNew()
@@ -1108,8 +1109,9 @@ void blo_make_image_pointer_map(FileData *fd)
fd->imamap= oldnewmap_new();
for(;ima; ima= ima->id.next) {
- if(ima->ibuf)
- oldnewmap_insert(fd->imamap, ima->ibuf, ima->ibuf, 0);
+ Link *ibuf= ima->ibufs.first;
+ for(; ibuf; ibuf= ibuf->next)
+ oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
}
for(; sce; sce= sce->id.next) {
if(sce->nodetree) {
@@ -1136,11 +1138,15 @@ void blo_end_image_pointer_map(FileData *fd)
}
for(;ima; ima= ima->id.next) {
- if(ima->ibuf) {
- ima->ibuf= newimaadr(fd, ima->ibuf);
- /* this mirrors direct_link_image */
- if(ima->ibuf==NULL)
+ Link *ibuf, *next;
+
+ /* this mirrors direct_link_image */
+ for(ibuf= ima->ibufs.first; ibuf; ibuf= next) {
+ next= ibuf->next;
+ if(NULL==newimaadr(fd, ibuf)) { /* so was restored */
+ BLI_remlink(&ima->ibufs, ibuf);
ima->bindcode= 0;
+ }
}
}
for(; sce; sce= sce->id.next) {
@@ -1213,11 +1219,11 @@ static void link_list(FileData *fd, ListBase *lb) /* only direct data */
{
Link *ln, *prev;
- if(lb->first==0) return;
+ if(lb->first==NULL) return;
lb->first= newdataadr(fd, lb->first);
ln= lb->first;
- prev= 0;
+ prev= NULL;
while(ln) {
ln->next= newdataadr(fd, ln->next);
ln->prev= prev;
@@ -1480,9 +1486,12 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
/* could be handlerized at some point */
if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
direct_link_curvemapping(fd, node->storage);
- else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_TIME || node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB))
- direct_link_curvemapping(fd, node->storage);
-
+ else if(ntree->type==NTREE_COMPOSIT) {
+ if( ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB))
+ direct_link_curvemapping(fd, node->storage);
+ else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+ ((ImageUser *)node->storage)->ok= 1;
+ }
}
link_list(fd, &node->inputs);
link_list(fd, &node->outputs);
@@ -2167,16 +2176,38 @@ static void lib_link_image(FileData *fd, Main *main)
}
}
+static void link_ibuf_list(FileData *fd, ListBase *lb)
+{
+ Link *ln, *prev;
+
+ if(lb->first==NULL) return;
+
+ lb->first= newimaadr(fd, lb->first);
+ ln= lb->first;
+ prev= NULL;
+ while(ln) {
+ ln->next= newimaadr(fd, ln->next);
+ ln->prev= prev;
+ prev= ln;
+ ln= ln->next;
+ }
+ lb->last= prev;
+}
+
static void direct_link_image(FileData *fd, Image *ima)
{
/* for undo system, pointers could be restored */
- ima->ibuf= newimaadr(fd, ima->ibuf);
- /* if restored, we keep the binded opengl index */
- if(ima->ibuf==NULL)
+ if(fd->imamap)
+ link_ibuf_list(fd, &ima->ibufs);
+ else
+ ima->ibufs.first= ima->ibufs.last= NULL;
+
+ /* if not restored, we keep the binded opengl index */
+ if(ima->ibufs.first==NULL)
ima->bindcode= 0;
- memset(ima->mipmap, 0, sizeof(ima->mipmap));
ima->anim= NULL;
+ ima->rr= NULL;
ima->repbind= NULL;
ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
@@ -2319,10 +2350,11 @@ static void direct_link_texture(FileData *fd, Tex *tex)
tex->coba= newdataadr(fd, tex->coba);
tex->env= newdataadr(fd, tex->env);
if(tex->env) {
- tex->env->ima= 0;
+ tex->env->ima= NULL;
memset(tex->env->cube, 0, 6*sizeof(void *));
tex->env->ok= 0;
}
+ tex->iuser.ok= 1;
}
@@ -3304,10 +3336,8 @@ static void lib_link_screen_sequence_ipos(Main *main)
bScreen *sc;
ScrArea *sa;
- sc= main->screen.first;
- while(sc) {
- sa= sc->areabase.first;
- while(sa) {
+ for(sc= main->screen.first; sc; sc= sc->id.next) {
+ for(sa= sc->areabase.first; sa; sa= sa->next) {
SpaceLink *sl;
for (sl= sa->spacedata.first; sl; sl= sl->next) {
if(sl->spacetype == SPACE_IPO) {
@@ -3317,9 +3347,7 @@ static void lib_link_screen_sequence_ipos(Main *main)
}
}
}
- sa= sa->next;
}
- sc= sc->id.next;
}
}
@@ -3332,8 +3360,7 @@ static void lib_link_screen(FileData *fd, Main *main)
bScreen *sc;
ScrArea *sa;
- sc= main->screen.first;
- while(sc) {
+ for(sc= main->screen.first; sc; sc= sc->id.next) {
if(sc->id.flag & LIB_NEEDLINK) {
sc->id.us= 1;
sc->scene= newlibadr(fd, sc->id.lib, sc->scene);
@@ -3356,8 +3383,6 @@ static void lib_link_screen(FileData *fd, Main *main)
if(v3d->bgpic) {
v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima);
- v3d->bgpic->tex= newlibadr_us(fd, sc->id.lib, v3d->bgpic->tex);
- v3d->bgpic->rect= NULL;
}
if(v3d->localvd) {
v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
@@ -3384,9 +3409,11 @@ static void lib_link_screen(FileData *fd, Main *main)
else if(sl->spacetype==SPACE_FILE) {
SpaceFile *sfile= (SpaceFile *)sl;
- sfile->filelist= 0;
- sfile->libfiledata= 0;
- sfile->returnfunc= 0;
+ sfile->filelist= NULL;
+ sfile->libfiledata= NULL;
+ sfile->returnfunc= NULL;
+ sfile->menup= NULL;
+ sfile->pupmenu= NULL;
}
else if(sl->spacetype==SPACE_IMASEL) {
check_imasel_copy((SpaceImaSel *)sl);
@@ -3446,7 +3473,6 @@ static void lib_link_screen(FileData *fd, Main *main)
}
sc->id.flag -= LIB_NEEDLINK;
}
- sc= sc->id.next;
}
}
@@ -3484,8 +3510,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
bScreen *sc;
ScrArea *sa;
- sc= newmain->screen.first;
- while(sc) {
+ for(sc= newmain->screen.first; sc; sc= sc->id.next) {
sc->scene= curscene;
@@ -3514,9 +3539,6 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
if(v3d->bgpic) {
v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima, 1);
- v3d->bgpic->tex= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->tex, 1);
- if(v3d->bgpic->rect) MEM_freeN(v3d->bgpic->rect);
- v3d->bgpic->rect= NULL;
}
if(v3d->localvd) {
Base *base;
@@ -3624,10 +3646,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
}
sa= sa->next;
}
-
- sc= sc->id.next;
}
-
}
static void direct_link_screen(FileData *fd, bScreen *sc)
@@ -3693,6 +3712,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
if (sl->spacetype==SPACE_VIEW3D) {
View3D *v3d= (View3D*) sl;
v3d->bgpic= newdataadr(fd, v3d->bgpic);
+ if(v3d->bgpic)
+ v3d->bgpic->iuser.ok= 1;
v3d->localvd= newdataadr(fd, v3d->localvd);
v3d->afterdraw.first= v3d->afterdraw.last= NULL;
v3d->clipbb= newdataadr(fd, v3d->clipbb);
@@ -3723,7 +3744,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sima->cumap= newdataadr(fd, sima->cumap);
if(sima->cumap)
direct_link_curvemapping(fd, sima->cumap);
- sima->info_str= NULL;
+ sima->info_str= sima->info_spare= NULL;
+ sima->spare= NULL;
+ sima->iuser.ok= 1;
}
else if(sl->spacetype==SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl;
@@ -4049,10 +4072,6 @@ static void link_global(FileData *fd, BlendFileData *bfd, FileGlobal *fg)
bfd->displaymode= fg->displaymode;
bfd->globalf= fg->globalf;
- bfd->main->subversionfile= fg->subversion;
- bfd->main->minversionfile= fg->minversion;
- bfd->main->minsubversionfile= fg->minsubversion;
-
bfd->curscreen= newlibadr(fd, 0, fg->curscreen);
bfd->curscene= newlibadr(fd, 0, fg->curscene);
// this happens in files older than 2.35
@@ -4240,6 +4259,40 @@ static void customdata_version_242(Mesh *me)
mesh_update_customdata_pointers(me);
}
+/* struct NodeImageAnim moved to ImageUser, and we make it default available */
+static void do_version_ntree_242_2(bNodeTree *ntree)
+{
+ bNode *node;
+
+ if(ntree->type==NTREE_COMPOSIT) {
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+ /* only image had storage */
+ if(node->storage) {
+ NodeImageAnim *nia= node->storage;
+ ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "ima user node");
+
+ iuser->frames= nia->frames;
+ iuser->sfra= nia->sfra;
+ iuser->offset= nia->nr-1;
+ iuser->cycl= nia->cyclic;
+ iuser->fie_ima= 2;
+ iuser->ok= 1;
+
+ node->storage= iuser;
+ MEM_freeN(nia);
+ }
+ else {
+ ImageUser *iuser= node->storage= MEM_callocN(sizeof(ImageUser), "node image user");
+ iuser->sfra= 1;
+ iuser->fie_ima= 2;
+ iuser->ok= 1;
+ }
+ }
+ }
+ }
+}
+
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -4258,10 +4311,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
- if(tex->imaflag & TEX_ANIM5) {
- tex->imaflag |= TEX_MORKPATCH;
- tex->imaflag |= TEX_ANTIALI;
- }
}
tex= tex->id.next;
}
@@ -6169,7 +6218,71 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sort_shape_fix(main);
/* now, subversion control! */
- if(main->subversionfile < 1) {
+ if(main->subversionfile < 3) {
+ bScreen *sc;
+ Image *ima;
+ Tex *tex;
+ Scene *sce;
+ bNodeTree *ntree;
+
+ /* Image refactor initialize */
+ for(ima= main->image.first; ima; ima= ima->id.next) {
+ ima->source= IMA_SRC_FILE;
+ ima->type= IMA_TYPE_IMAGE;
+
+ ima->gen_x= 256; ima->gen_y= 256;
+ ima->gen_type= 1;
+
+ if(0==strncmp(ima->id.name+2, "Viewer Node", sizeof(ima->id.name+2))) {
+ ima->source= IMA_SRC_VIEWER;
+ ima->type= IMA_TYPE_COMPOSITE;
+ }
+ if(0==strncmp(ima->id.name+2, "Render Result", sizeof(ima->id.name+2))) {
+ ima->source= IMA_SRC_VIEWER;
+ ima->type= IMA_TYPE_R_RESULT;
+ }
+
+ }
+ for(tex= main->tex.first; tex; tex= tex->id.next) {
+ if(tex->type==TEX_IMAGE && tex->ima) {
+ ima= newlibadr(fd, lib, tex->ima);
+ if(tex->imaflag & TEX_ANIM5_)
+ ima->source= IMA_SRC_MOVIE;
+ if(tex->imaflag & TEX_FIELDS_)
+ ima->flag |= IMA_FIELDS;
+ if(tex->imaflag & TEX_STD_FIELD_)
+ ima->flag |= IMA_STD_FIELD;
+ if(tex->imaflag & TEX_ANTIALI_)
+ ima->flag |= IMA_ANTIALI;
+ }
+ tex->iuser.frames= tex->frames;
+ tex->iuser.fie_ima= tex->fie_ima;
+ tex->iuser.offset= tex->offset;
+ tex->iuser.sfra= tex->sfra;
+ tex->iuser.cycl= (tex->imaflag & TEX_ANIMCYCLIC_)!=0;
+ }
+ for(sce= main->scene.first; sce; sce= sce->id.next) {
+ if(sce->nodetree)
+ do_version_ntree_242_2(sce->nodetree);
+ }
+ for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
+ do_version_ntree_242_2(ntree);
+
+ for(sc= main->screen.first; sc; sc= sc->id.next) {
+ ScrArea *sa;
+ for(sa= sc->areabase.first; sa; sa= sa->next) {
+ SpaceLink *sl;
+ for (sl= sa->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_IMAGE)
+ ((SpaceImage *)sl)->iuser.fie_ima= 2;
+ else if(sl->spacetype==SPACE_VIEW3D) {
+ View3D *v3d= (View3D *)sl;
+ if(v3d->bgpic)
+ v3d->bgpic->iuser.fie_ima= 2;
+ }
+ }
+ }
+ }
}
}
@@ -6252,6 +6365,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
case REND:
if (bhead->code==GLOB) {
fg= read_struct(fd, bhead, "Global");
+ /* set right away */
+ bfd->main->subversionfile= fg->subversion;
+ bfd->main->minversionfile= fg->minversion;
+ bfd->main->minsubversionfile= fg->minsubversion;
}
bhead = blo_nextbhead(fd, bhead);
break;
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 02b3557c094..60177f2c996 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -315,6 +315,7 @@ void IMB_antialias(struct ImBuf * ibuf);
void IMB_filter(struct ImBuf *ibuf);
void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
void IMB_filter_extend(struct ImBuf *ibuf);
+void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
/**
*
@@ -537,6 +538,7 @@ void imb_freerectImBuf(struct ImBuf * ibuf);
short imb_addrectfloatImBuf(struct ImBuf * ibuf);
void imb_freerectfloatImBuf(struct ImBuf * ibuf);
+void imb_freemipmapImBuf(struct ImBuf * ibuf);
#ifdef WITH_QUICKTIME
/**
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 586dedc54e8..f5487bb9ac0 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -56,6 +56,8 @@
struct _AviMovie;
struct Mdec;
+#define IB_MIPMAP_LEVELS 10
+
/**
* \brief The basic imbuf type
* \ingroup imbuf
@@ -70,36 +72,41 @@ struct Mdec;
*
* Also, that iff.h needs to be in the final release "plugins/include" dir, too!
*/
-typedef struct ImBuf{
- short x, y; /**< width and Height of our image buffer */
- short skipx; /**< Width in ints to get to the next scanline */
+typedef struct ImBuf {
+ struct ImBuf *next, *prev; /**< allow lists of ImBufs, for caches or flipbooks */
+ short x, y; /**< width and Height of our image buffer */
+ short skipx; /**< Width in ints to get to the next scanline */
unsigned char depth; /**< Active amount of bits/bitplanes */
unsigned char cbits; /**< Amount of active bits in cmap */
unsigned short mincol; /**< smallest color in colormap */
unsigned short maxcol; /**< Largest color in colormap */
- int type; /**< 0=abgr, 1=bitplanes */
- int ftype; /**< File type we are going to save as */
+ int type; /**< 0=abgr, 1=bitplanes */
+ int ftype; /**< File type we are going to save as */
unsigned int *cmap; /**< Color map data. */
unsigned int *rect; /**< pixel values stored here */
unsigned int **planes; /**< bitplanes */
- int flags; /**< Controls which components should exist. */
- int mall; /**< what is malloced internal, and can be freed */
+ int flags; /**< Controls which components should exist. */
+ int mall; /**< what is malloced internal, and can be freed */
short xorig, yorig; /**< Cordinates of first pixel of an image used in some formats (example: targa) */
char name[1023]; /**< The file name assocated with this image */
char namenull; /**< Unused don't want to remove it thought messes things up */
- int userflags; /**< Used to set imbuf to Dirty and other stuff */
- int *zbuf; /**< z buffer data, original zbuffer */
- float *zbuf_float; /**< z buffer data, camera coordinates */
+ int userflags; /**< Used to set imbuf to Dirty and other stuff */
+ int *zbuf; /**< z buffer data, original zbuffer */
+ float *zbuf_float; /**< z buffer data, camera coordinates */
void *userdata;
unsigned char *encodedbuffer; /**< Compressed image only used with png currently */
unsigned int encodedsize; /**< Size of data written to encodedbuffer */
unsigned int encodedbuffersize; /**< Size of encodedbuffer */
float *rect_float; /**< floating point Rect equivilant */
+ int channels; /**< amount of channels in rect_float (0 = 4 channel default) */
float dither; /**< random dither value, for conversion from float -> byte rect */
struct MEM_CacheLimiterHandle_s * c_handle; /**< handle for cache limiter */
- int refcounter; /**< Refcounter for multiple users */
+ int refcounter; /**< Refcounter for multiple users */
+ int index; /**< reference index for ImBuf lists */
+
+ struct ImBuf *mipmap[IB_MIPMAP_LEVELS]; /**< MipMap levels, a series of halved images */
} ImBuf;
/* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */
@@ -138,8 +145,9 @@ typedef enum {
#define IB_zbuf (1 << 13)
#define IB_mem (1 << 14)
-#define IB_rectfloat (1 << 15)
-#define IB_zbuffloat (1 << 16)
+#define IB_rectfloat (1 << 15)
+#define IB_zbuffloat (1 << 16)
+#define IB_multilayer (1 << 17)
/*
* The bit flag is stored in the ImBuf.ftype variable.
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 30e97328e7c..003d377389b 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -62,6 +62,17 @@ void imb_freeplanesImBuf(struct ImBuf * ibuf)
ibuf->mall &= ~IB_planes;
}
+void imb_freemipmapImBuf(struct ImBuf * ibuf)
+{
+ int a;
+
+ for(a=0; a<IB_MIPMAP_LEVELS; a++) {
+ if(ibuf->mipmap[a]) IMB_freeImBuf(ibuf->mipmap[a]);
+ ibuf->mipmap[a]= NULL;
+ }
+}
+
+/* any free rect frees mipmaps to be sure, creation is in render on first request */
void imb_freerectfloatImBuf(struct ImBuf * ibuf)
{
if (ibuf==NULL) return;
@@ -73,10 +84,13 @@ void imb_freerectfloatImBuf(struct ImBuf * ibuf)
}
}
+ imb_freemipmapImBuf(ibuf);
+
ibuf->rect_float= NULL;
ibuf->mall &= ~IB_rectfloat;
}
+/* any free rect frees mipmaps to be sure, creation is in render on first request */
void imb_freerectImBuf(struct ImBuf * ibuf)
{
if (ibuf==NULL) return;
@@ -87,6 +101,8 @@ void imb_freerectImBuf(struct ImBuf * ibuf)
}
}
+ imb_freemipmapImBuf(ibuf);
+
ibuf->rect= NULL;
ibuf->mall &= ~IB_rect;
}
@@ -363,7 +379,8 @@ struct ImBuf *IMB_allocImBuf(short x, short y, uchar d, unsigned int flags, ucha
ibuf->y= y;
ibuf->depth= d;
ibuf->ftype= TGA;
-
+ ibuf->channels= 4; /* float option, is set to other values when buffers get assigned */
+
if (flags & IB_rect){
if (imb_addrectImBuf(ibuf)==FALSE){
IMB_freeImBuf(ibuf);
@@ -407,7 +424,7 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
{
struct ImBuf *ibuf2, tbuf;
int flags = 0;
- int x, y;
+ int a, x, y;
if (ibuf1 == NULL) return NULL;
@@ -452,6 +469,8 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
tbuf.encodedbuffer = ibuf2->encodedbuffer;
tbuf.zbuf= NULL;
tbuf.zbuf_float= NULL;
+ for(a=0; a<IB_MIPMAP_LEVELS; a++)
+ tbuf.mipmap[a]= NULL;
// set malloc flag
tbuf.mall = ibuf2->mall;
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index c0018d0b336..a4fab4a3572 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -181,7 +181,7 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
/* quick method to convert floatbuf to byte */
float *tof = ibuf->rect_float;
float dither= ibuf->dither;
- int i;
+ int i, channels= ibuf->channels;
unsigned char *to = (unsigned char *) ibuf->rect;
if(tof==NULL) return;
@@ -190,14 +190,26 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
to = (unsigned char *) ibuf->rect;
}
- if(dither==0.0f) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = FTOCHAR(tof[0]);
- to[1] = FTOCHAR(tof[1]);
- to[2] = FTOCHAR(tof[2]);
- to[3] = FTOCHAR(tof[3]);
- to += 4;
- tof += 4;
+ if(dither==0.0f || channels!=4) {
+ if(channels==1) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
+ to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
+ }
+ else if(channels==3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
+ to[0] = FTOCHAR(tof[0]);
+ to[1] = FTOCHAR(tof[1]);
+ to[2] = FTOCHAR(tof[2]);
+ to[3] = 255;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
+ to[0] = FTOCHAR(tof[0]);
+ to[1] = FTOCHAR(tof[1]);
+ to[2] = FTOCHAR(tof[2]);
+ to[3] = FTOCHAR(tof[3]);
+ }
}
}
else {
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 343211eb6b0..fd9dac1af2b 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -302,3 +302,28 @@ void IMB_filter_extend(struct ImBuf *ibuf)
}
}
+void IMB_makemipmap(ImBuf *ibuf, int use_filter)
+{
+ ImBuf *hbuf= ibuf;
+ int minsize, curmap=0;
+
+ minsize= ibuf->x<ibuf->y?ibuf->x:ibuf->y;
+
+ while(minsize>10 && curmap<IB_MIPMAP_LEVELS) {
+ if(use_filter) {
+ ImBuf *nbuf= IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect, 0);
+ IMB_filterN(nbuf, hbuf);
+ ibuf->mipmap[curmap]= IMB_onehalf(nbuf);
+ IMB_freeImBuf(nbuf);
+ }
+ else {
+ ibuf->mipmap[curmap]= IMB_onehalf(hbuf);
+ }
+ hbuf= ibuf->mipmap[curmap];
+
+ curmap++;
+ minsize= hbuf->x<hbuf->y?hbuf->x:hbuf->y;
+ }
+}
+
+
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 3027f9508cf..25ca958afdb 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -343,37 +343,69 @@ short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags)
}
}
-/* ********************* Tile file support ************************************ */
+/* ********************* Nicer API, MultiLayer and with Tile file support ************************************ */
+
+/* naming rules:
+ - parse name from right to left
+ - last character is channel ID, 1 char like 'A' 'R' 'G' 'B' 'X' 'Y' 'Z' 'W' 'U' 'V'
+ - separated with a dot; the Pass name (like "Depth", "Color", "Diffuse" or "Combined")
+ - separated with a dot: the Layer name (like "Lamp1" or "Walls" or "Characters")
+*/
+
+static ListBase exrhandles= {NULL, NULL};
typedef struct ExrHandle {
+ struct ExrHandle *next, *prev;
+
InputFile *ifile;
TiledOutputFile *tofile;
OutputFile *ofile;
int tilex, tiley;
int width, height;
- ListBase channels;
+
+ ListBase channels; /* flattened out, ExrChannel */
+ ListBase layers; /* hierarchical, pointing in end to ExrChannel */
} ExrHandle;
-#define CHANMAXNAME 64
+/* flattened out channel */
typedef struct ExrChannel {
struct ExrChannel *next, *prev;
- char name[2*CHANMAXNAME + 1];
- int xstride, ystride;
- float *rect;
+
+ char name[EXR_TOT_MAXNAME+1]; /* full name of layer+pass */
+ int xstride, ystride; /* step to next pixel, to next scanline */
+ float *rect; /* first pointer to write in */
+ char chan_id; /* quick lookup of channel char */
} ExrChannel;
-/* not threaded! write one tiled file at a time */
+
+/* hierarchical; layers -> passes -> channels[] */
+typedef struct ExrPass {
+ struct ExrPass *next, *prev;
+ char name[EXR_PASS_MAXNAME];
+ int totchan;
+ float *rect;
+ struct ExrChannel *chan[EXR_PASS_MAXCHAN];
+ char chan_id[EXR_PASS_MAXCHAN];
+} ExrPass;
+
+typedef struct ExrLayer {
+ struct ExrLayer *next, *prev;
+ char name[EXR_LAY_MAXNAME+1];
+ ListBase passes;
+} ExrLayer;
+
+/* ********************** */
+
void *IMB_exr_get_handle(void)
{
- static ExrHandle data;
-
- memset(&data, sizeof(ExrHandle), 0);
-
- return &data;
+ ExrHandle *data= (ExrHandle *)MEM_callocN(sizeof(ExrHandle), "exr handle");
+ BLI_addtail(&exrhandles, data);
+ return data;
}
-/* still clumsy name handling, layers/channels can be ordered as list in list later */
-void IMB_exr_add_channel(void *handle, const char *layname, const char *channame)
+/* adds flattened ExrChannels */
+/* xstride, ystride and rect can be done in set_channel too, for tile writing */
+void IMB_exr_add_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect)
{
ExrHandle *data= (ExrHandle *)handle;
ExrChannel *echan;
@@ -381,14 +413,19 @@ void IMB_exr_add_channel(void *handle, const char *layname, const char *channame
echan= (ExrChannel *)MEM_callocN(sizeof(ExrChannel), "exr tile channel");
if(layname) {
- char lay[CHANMAXNAME], chan[CHANMAXNAME];
- strncpy(lay, layname, CHANMAXNAME-1);
- strncpy(chan, channame, CHANMAXNAME-1);
+ char lay[EXR_LAY_MAXNAME+1], pass[EXR_PASS_MAXNAME+1];
+ BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
+ BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
- sprintf(echan->name, "%s.%s", lay, chan);
+ sprintf(echan->name, "%s.%s", lay, pass);
}
else
- strncpy(echan->name, channame, 2*CHANMAXNAME);
+ BLI_strncpy(echan->name, passname, EXR_TOT_MAXNAME-1);
+
+ echan->xstride= xstride;
+ echan->ystride= ystride;
+ echan->rect= rect;
+
// printf("added channel %s\n", echan->name);
BLI_addtail(&data->channels, echan);
}
@@ -405,7 +442,9 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height)
for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
header.channels().insert (echan->name, Channel (FLOAT));
- header.insert ("comments", StringAttribute ("Blender MultiChannel"));
+ header.compression() = RLE_COMPRESSION;
+
+ header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43"));
data->ofile = new OutputFile(filename, header);
}
@@ -426,13 +465,14 @@ void IMB_exrtile_begin_write(void *handle, char *filename, int width, int height
header.setTileDescription (TileDescription (tilex, tiley, ONE_LEVEL));
header.lineOrder() = RANDOM_Y,
- header.compression() = NO_COMPRESSION;
+ header.compression() = RLE_COMPRESSION;
- header.insert ("comments", StringAttribute ("Blender MultiChannel"));
+ header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43"));
data->tofile = new TiledOutputFile(filename, header);
}
+/* read from file */
int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
{
ExrHandle *data= (ExrHandle *)handle;
@@ -447,7 +487,7 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
const ChannelList &channels = data->ifile->header().channels();
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
- IMB_exr_add_channel(data, NULL, i.name());
+ IMB_exr_add_channel(data, NULL, i.name(), 0, 0, NULL);
return 1;
}
@@ -456,21 +496,21 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
}
/* still clumsy name handling, layers/channels can be ordered as list in list later */
-void IMB_exr_set_channel(void *handle, char *layname, char *channame, int xstride, int ystride, float *rect)
+void IMB_exr_set_channel(void *handle, char *layname, char *passname, int xstride, int ystride, float *rect)
{
ExrHandle *data= (ExrHandle *)handle;
ExrChannel *echan;
- char name[2*CHANMAXNAME + 1];
+ char name[EXR_TOT_MAXNAME + 1];
if(layname) {
- char lay[CHANMAXNAME], chan[CHANMAXNAME];
- strncpy(lay, layname, CHANMAXNAME-1);
- strncpy(chan, channame, CHANMAXNAME-1);
+ char lay[EXR_LAY_MAXNAME+1], pass[EXR_PASS_MAXNAME+1];
+ BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
+ BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
- sprintf(name, "%s.%s", lay, chan);
+ sprintf(name, "%s.%s", lay, pass);
}
else
- strncpy(name, channame, 2*CHANMAXNAME);
+ BLI_strncpy(name, passname, EXR_TOT_MAXNAME-1);
for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
@@ -540,11 +580,38 @@ void IMB_exr_read_channels(void *handle)
data->ifile->readPixels (0, data->height-1);
}
+void IMB_exr_multilayer_convert(void *handle, void *base,
+ void * (*addlayer)(void *base, char *str),
+ void (*addpass)(void *base, void *lay, char *str,
+ float *rect, int totchan, char *chan_id))
+{
+ ExrHandle *data= (ExrHandle *)handle;
+ ExrLayer *lay;
+ ExrPass *pass;
+
+ if(data->layers.first==NULL) {
+ printf("cannot convert multilayer, no layers in handle\n");
+ return;
+ }
+
+ for(lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) {
+ void *laybase= addlayer(base, lay->name);
+ if(laybase) {
+ for(pass= (ExrPass *)lay->passes.first; pass; pass= pass->next) {
+ addpass(base, laybase, pass->name, pass->rect, pass->totchan, pass->chan_id);
+ pass->rect= NULL;
+ }
+ }
+ }
+}
+
void IMB_exr_close(void *handle)
{
ExrHandle *data= (ExrHandle *)handle;
ExrChannel *echan;
+ ExrLayer *lay;
+ ExrPass *pass;
if(data->ifile)
delete data->ifile;
@@ -558,6 +625,191 @@ void IMB_exr_close(void *handle)
data->tofile= NULL;
BLI_freelistN(&data->channels);
+
+ for(lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) {
+ for(pass= (ExrPass *)lay->passes.first; pass; pass= pass->next)
+ if(pass->rect)
+ MEM_freeN(pass->rect);
+ BLI_freelistN(&lay->passes);
+ }
+ BLI_freelistN(&data->layers);
+
+ BLI_remlink(&exrhandles, data);
+ MEM_freeN(data);
+}
+
+/* ********* */
+
+static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *passname)
+{
+ int plen, len= strlen(echan->name);
+
+ if(len < 4) {
+ printf("multilayer read: name too short: %s\n", echan->name);
+ return 0;
+ }
+ if(echan->name[len-2]!='.') {
+ printf("multilayer read: name has no Channel: %s\n", echan->name);
+ return 0;
+ }
+ echan->chan_id= echan->name[len-1];
+
+ len-= 3;
+ while(len>=0) {
+ if(echan->name[len]=='.')
+ break;
+ len--;
+ }
+ BLI_strncpy(passname, echan->name+len+1, EXR_PASS_MAXNAME);
+ plen= strlen(passname);
+ if(plen < 3) {
+ printf("multilayer read: should not happen: %s\n", echan->name);
+ return 0;
+ }
+ passname[plen-2]= 0;
+
+ if(len<1)
+ layname[0]= 0;
+ else {
+ BLI_strncpy(layname, echan->name, EXR_LAY_MAXNAME);
+ layname[len]= 0;
+ }
+ // printf("found lay %s pass %s chan %c\n", layname, passname, echan->chan_id);
+}
+
+static ExrLayer *imb_exr_get_layer(ListBase *lb, char *layname)
+{
+ ExrLayer *lay;
+
+ for(lay= (ExrLayer *)lb->first; lay; lay= lay->next) {
+ if( strcmp(lay->name, layname)==0 )
+ return lay;
+ }
+ lay= (ExrLayer *)MEM_callocN(sizeof(ExrLayer), "exr layer");
+ BLI_addtail(lb, lay);
+ BLI_strncpy(lay->name, layname, EXR_LAY_MAXNAME);
+
+ return lay;
+}
+
+static ExrPass *imb_exr_get_pass(ListBase *lb, char *passname)
+{
+ ExrPass *pass;
+
+ for(pass= (ExrPass *)lb->first; pass; pass= pass->next) {
+ if( strcmp(pass->name, passname)==0 )
+ return pass;
+ }
+
+ pass= (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass");
+
+ if(strcmp(passname, "Combined")==0)
+ BLI_addhead(lb, pass);
+ else
+ BLI_addtail(lb, pass);
+
+ BLI_strncpy(pass->name, passname, EXR_LAY_MAXNAME);
+
+ return pass;
+}
+
+/* creates channels, makes a hierarchy and assigns memory to channels */
+static ExrHandle *imb_exr_begin_read_mem(InputFile *file, int width, int height)
+{
+ ExrLayer *lay;
+ ExrPass *pass;
+ ExrChannel *echan;
+ ExrHandle *data= (ExrHandle *)IMB_exr_get_handle();
+ int a;
+ char layname[EXR_TOT_MAXNAME], passname[EXR_TOT_MAXNAME];
+
+ data->ifile= file;
+ data->width= width;
+ data->height= height;
+
+ const ChannelList &channels = data->ifile->header().channels();
+
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+ IMB_exr_add_channel(data, NULL, i.name(), 0, 0, NULL);
+
+ /* now try to sort out how to assign memory to the channels */
+ /* first build hierarchical layer list */
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) {
+ if( imb_exr_split_channel_name(echan, layname, passname) ) {
+ ExrLayer *lay= imb_exr_get_layer(&data->layers, layname);
+ ExrPass *pass= imb_exr_get_pass(&lay->passes, passname);
+
+ pass->chan[pass->totchan]= echan;
+ pass->totchan++;
+ if(pass->totchan>=EXR_PASS_MAXCHAN)
+ break;
+ }
+ }
+ if(echan) {
+ printf("error, too many channels in one pass: %s\n", echan->name);
+ IMB_exr_close(data);
+ return NULL;
+ }
+
+ /* with some heuristics, try to merge the channels in buffers */
+ for(lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) {
+ for(pass= (ExrPass *)lay->passes.first; pass; pass= pass->next) {
+ if(pass->totchan) {
+ pass->rect= (float *)MEM_mapallocN(width*height*pass->totchan*sizeof(float), "pass rect");
+ if(pass->totchan==1) {
+ echan= pass->chan[0];
+ echan->rect= pass->rect;
+ echan->xstride= 1;
+ echan->ystride= width;
+ pass->chan_id[0]= echan->chan_id;
+ }
+ else {
+ char lookup[256];
+
+ memset(lookup, 0, sizeof(lookup));
+
+ /* we can have RGB(A), XYZ(W), UVA */
+ if(pass->totchan==3 || pass->totchan==4) {
+ if(pass->chan[0]->chan_id=='B' || pass->chan[1]->chan_id=='B' || pass->chan[2]->chan_id=='B') {
+ lookup['R']= 0;
+ lookup['G']= 1;
+ lookup['B']= 2;
+ lookup['A']= 3;
+ }
+ else if(pass->chan[0]->chan_id=='Y' || pass->chan[1]->chan_id=='Y' || pass->chan[2]->chan_id=='Y') {
+ lookup['X']= 0;
+ lookup['Y']= 1;
+ lookup['Z']= 2;
+ lookup['W']= 3;
+ }
+ else {
+ lookup['U']= 0;
+ lookup['V']= 1;
+ lookup['A']= 2;
+ }
+ for(a=0; a<pass->totchan; a++) {
+ echan= pass->chan[a];
+ echan->rect= pass->rect + lookup[echan->chan_id];
+ echan->xstride= pass->totchan;
+ echan->ystride= width*pass->totchan;
+ pass->chan_id[ lookup[echan->chan_id] ]= echan->chan_id;
+ }
+ }
+ else { /* unknown */
+ for(a=0; a<pass->totchan; a++) {
+ echan= pass->chan[a];
+ echan->rect= pass->rect + a;
+ echan->xstride= pass->totchan;
+ echan->ystride= width*pass->totchan;
+ pass->chan_id[a]= echan->chan_id;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return data;
}
@@ -598,9 +850,9 @@ static int exr_has_zbuffer(InputFile *file)
static int exr_is_renderresult(InputFile *file)
{
- const StringAttribute *comments= file->header().findTypedAttribute<StringAttribute>("comments");
+ const StringAttribute *comments= file->header().findTypedAttribute<StringAttribute>("BlenderMultiChannel");
if(comments)
- if(comments->value() == "Blender MultiChannel")
+// if(comments->value() == "Blender MultiChannel")
return 1;
return 0;
}
@@ -615,6 +867,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
try
{
Mem_IStream membuf(mem, size);
+ int is_multi;
file = new InputFile(membuf);
Box2i dw = file->header().dataWindow();
@@ -625,53 +878,70 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
// dw.min.x, dw.min.y, dw.max.x, dw.max.y);
//exr_print_filecontents(file);
- int flipped= exr_is_renderresult(file);
- ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
+ is_multi= exr_is_renderresult(file);
- if (ibuf)
+ /* do not make an ibuf when */
+ if(is_multi && !(flags & IB_test) && !(flags & IB_multilayer))
{
+ printf("Error: can't process EXR multilayer file\n");
+ }
+ else {
+
+ ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
ibuf->ftype = OPENEXR;
if (!(flags & IB_test))
{
- FrameBuffer frameBuffer;
- float *first;
- int xstride = sizeof(float) * 4;
- int ystride = flipped ? xstride*width : - xstride*width;
-
- imb_addrectfloatImBuf(ibuf);
-
- /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */
- first= ibuf->rect_float - 4*(dw.min.x - dw.min.y*width);
- /* but, since we read y-flipped (negative y stride) we move to last scanline */
- if(!flipped) first+= 4*(height-1)*width;
-
- frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride));
- frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride));
- frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride));
- /* 1.0 is fill value */
- frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
-
- if(exr_has_zbuffer(file))
+ if(is_multi) /* only enters with IB_multilayer flag set */
{
- float *firstz;
+ /* constructs channels for reading, allocates memory in channels */
+ ExrHandle *handle= imb_exr_begin_read_mem(file, width, height);
+ if(handle) {
+ IMB_exr_read_channels(handle);
+ ibuf->userdata= handle; /* potential danger, the caller has to check for this! */
+ return ibuf;
+ }
+ }
+ else {
+ FrameBuffer frameBuffer;
+ float *first;
+ int xstride = sizeof(float) * 4;
+ int ystride = - xstride*width;
+
+ imb_addrectfloatImBuf(ibuf);
+
+ /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */
+ first= ibuf->rect_float - 4*(dw.min.x - dw.min.y*width);
+ /* but, since we read y-flipped (negative y stride) we move to last scanline */
+ first+= 4*(height-1)*width;
+
+ frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride));
+ frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride));
+ frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride));
+ /* 1.0 is fill value */
+ frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
+
+ if(exr_has_zbuffer(file))
+ {
+ float *firstz;
+
+ addzbuffloatImBuf(ibuf);
+ firstz= ibuf->zbuf_float - (dw.min.x - dw.min.y*width);
+ firstz+= (height-1)*width;
+ frameBuffer.insert ("Z", Slice (FLOAT, (char *)firstz , sizeof(float), -width*sizeof(float)));
+ }
- addzbuffloatImBuf(ibuf);
- firstz= ibuf->zbuf_float - (dw.min.x - dw.min.y*width);
- if(!flipped) firstz+= (height-1)*width;
- frameBuffer.insert ("Z", Slice (FLOAT, (char *)firstz , sizeof(float), -width*sizeof(float)));
+ file->setFrameBuffer (frameBuffer);
+ file->readPixels (dw.min.y, dw.max.y);
+
+ IMB_rect_from_float(ibuf);
}
-
- file->setFrameBuffer (frameBuffer);
- file->readPixels (dw.min.y, dw.max.y);
-
- IMB_rect_from_float(ibuf);
}
+
+ delete file;
}
- delete file;
-
return(ibuf);
}
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
index ff71aab5f3c..feceb227e4b 100644
--- a/source/blender/imbuf/intern/openexr/openexr_multi.h
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -32,28 +32,41 @@
/* experiment with more advanced exr api */
+/* Note: as for now openexr only supports 32 chars in channel names.
+ This api also supports max 8 channels per pass now. easy to fix! */
+#define EXR_LAY_MAXNAME 19
+#define EXR_PASS_MAXNAME 11
+#define EXR_TOT_MAXNAME 32
+#define EXR_PASS_MAXCHAN 8
+
+
#ifdef WITH_OPENEXR
void * IMB_exr_get_handle (void);
-void IMB_exr_add_channel (void *handle, const char *layname, const char *channame);
+void IMB_exr_add_channel (void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect);
int IMB_exr_begin_read (void *handle, char *filename, int *width, int *height);
void IMB_exr_begin_write (void *handle, char *filename, int width, int height);
void IMB_exrtile_begin_write (void *handle, char *filename, int width, int height, int tilex, int tiley);
-void IMB_exr_set_channel (void *handle, char *layname, char *channame, int xstride, int ystride, float *rect);
+void IMB_exr_set_channel (void *handle, char *layname, char *passname, int xstride, int ystride, float *rect);
void IMB_exr_read_channels (void *handle);
void IMB_exr_write_channels (void *handle);
void IMB_exrtile_write_channels (void *handle, int partx, int party);
+void IMB_exr_multilayer_convert (void *handle, void *base,
+ void * (*addlayer)(void *base, char *str),
+ void (*addpass)(void *base, void *lay, char *str, float *rect, int totchan, char *chan_id));
+
void IMB_exr_close (void *handle);
+
#else
/* ugly... but we only use it on pipeline.c, render module, now */
void * IMB_exr_get_handle (void) {return NULL;}
-void IMB_exr_add_channel (void *handle, const char *layname, const char *channame) {}
+void IMB_exr_add_channel (void *handle, const char *layname, const char *channame, int xstride, int ystride, float *rect) {}
int IMB_exr_begin_read (void *handle, char *filename, int *width, int *height) {return 0;}
void IMB_exr_begin_write (void *handle, char *filename, int width, int height) {}
@@ -65,6 +78,10 @@ void IMB_exr_read_channels (void *handle) {}
void IMB_exr_write_channels (void *handle) {}
void IMB_exrtile_write_channels (void *handle, int partx, int party) {}
+void IMB_exr_multilayer_convert (void *handle, void *base,
+ void * (*addlayer)(void *base, char *str),
+ void (*addpass)(void *base, void *lay, char *str, float *rect, int totchan, char *chan_id)) {}
+
void IMB_exr_close (void *handle) {}
#endif
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 45ef191277b..bfa6200d23b 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -270,7 +270,7 @@ struct ImBuf *IMB_loadiffname(char *naam, int flags) {
ibuf= IMB_loadifffile(file, flags);
- if (ibuf == 0) {
+ if (ibuf == NULL) {
if (read(file, buf, 4) != 4) buf[0] = 0;
if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0)
ibuf = imb_ibJpegImageFromFilename(naam, flags);
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 41183ce91da..429fcb109ea 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -332,6 +332,8 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &width, &height);
if (width == 0 || height == 0) return;
+ if (sbuf && sbuf->channels!=4) return;
+ if (dbuf->channels!=4) return;
do_char = (sbuf && sbuf->rect && dbuf->rect);
do_float = (sbuf && sbuf->rect_float && dbuf->rect_float);
diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h
index f5ae79fcd80..f87e9797cb3 100644
--- a/source/blender/include/BIF_butspace.h
+++ b/source/blender/include/BIF_butspace.h
@@ -42,6 +42,8 @@ struct ID;
extern void do_butspace(unsigned short event);
extern void redraw_test_buttons(struct Object *new);
+extern char *image_type_pup(void);
+
/* buttons_editing.c */
extern void validate_editbonebutton_cb(void *bonev, void *namev);
diff --git a/source/blender/include/BIF_drawimage.h b/source/blender/include/BIF_drawimage.h
index a3b12b7bafd..5c289cfc2a4 100644
--- a/source/blender/include/BIF_drawimage.h
+++ b/source/blender/include/BIF_drawimage.h
@@ -36,6 +36,9 @@
struct ScrArea;
struct SpaceImage;
struct Render;
+struct Image;
+struct ImBuf;
+struct uiBlock;
void do_imagebuts(unsigned short event);
void calc_image_view(struct SpaceImage *sima, char mode);
@@ -51,8 +54,15 @@ void uvco_to_areaco_noclip(float *vec, int *mval);
void what_image(struct SpaceImage *sima);
void image_preview_event(int event);
+void image_info(struct Image *ima, struct ImBuf *ibuf, char *str);
+void imagespace_composite_flipbook(struct ScrArea *sa);
+
void imagewindow_render_callbacks(struct Render *re);
void imagewindow_toggle_render(void);
+void imagewindow_swap_render_rects(void);
+void imagewin_store_spare(void);
+
+void image_editvertex_buts(struct uiBlock *block);
#endif
diff --git a/source/blender/include/BIF_editsima.h b/source/blender/include/BIF_editsima.h
index 46444c88ae3..6a67ebc7009 100644
--- a/source/blender/include/BIF_editsima.h
+++ b/source/blender/include/BIF_editsima.h
@@ -76,7 +76,10 @@ void new_image_sima(void);
void reload_image_sima(void);
void save_image_sima(void);
void save_as_image_sima(void);
+void save_image_sequence_sima(void);
void replace_image_sima(short imageselect);
void open_image_sima(short imageselect);
void pack_image_sima(void);
+/* checks images for forced updates on frame change */
+void BIF_image_update_frame(void);
diff --git a/source/blender/include/BIF_renderwin.h b/source/blender/include/BIF_renderwin.h
index a997efb336d..789c3661db7 100644
--- a/source/blender/include/BIF_renderwin.h
+++ b/source/blender/include/BIF_renderwin.h
@@ -50,6 +50,7 @@ void BIF_renderwin_set_custom_cursor(unsigned char mask[16][2], unsigned char bi
void BIF_redraw_render_rect(void);
void BIF_swap_render_rects(void);
+void BIF_store_spare(void);
void BIF_toggle_render_display(void);
void BIF_init_render_callbacks(struct Render *re, int do_display);
diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h
index 7bf0814b82e..1e84dba39cb 100644
--- a/source/blender/include/BIF_space.h
+++ b/source/blender/include/BIF_space.h
@@ -64,6 +64,7 @@ struct SpaceOops;
#define IMAGE_HANDLER_PAINT 31
#define IMAGE_HANDLER_CURVES 32
#define IMAGE_HANDLER_PREVIEW 33
+#define IMAGE_HANDLER_GAME_PROPERTIES 34
/* action handler codes */
#define ACTION_HANDLER_PROPERTIES 40
diff --git a/source/blender/include/BIF_writeimage.h b/source/blender/include/BIF_writeimage.h
index 002d382be5b..70978a033c2 100644
--- a/source/blender/include/BIF_writeimage.h
+++ b/source/blender/include/BIF_writeimage.h
@@ -37,7 +37,7 @@ struct ImBuf;
struct EnvMap;
void BIF_save_rendered_image(char *name);
-void BIF_save_rendered_image_fs(int zbuf);
+void BIF_save_rendered_image_fs(void);
void BIF_save_envmap(struct EnvMap *env, char *str);
void save_image_filesel_str(char *str);
diff --git a/source/blender/include/BSE_filesel.h b/source/blender/include/BSE_filesel.h
index 29f9c52f79f..6934899062e 100644
--- a/source/blender/include/BSE_filesel.h
+++ b/source/blender/include/BSE_filesel.h
@@ -40,7 +40,6 @@ struct ID;
struct ScrArea;
struct BWinEvent;
-void clear_global_filesel_vars(void);
void filesel_statistics(struct SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen);
void test_flags_file(struct SpaceFile *sfile);
void sort_filelist(struct SpaceFile *sfile);
@@ -49,9 +48,16 @@ void freefilelist(struct SpaceFile *sfile);
void parent(struct SpaceFile *sfile);
void swapselect_file(struct SpaceFile *sfile);
void drawfilespace(struct ScrArea *sa, void *spacedata);
+
void activate_fileselect(int type, char *title, char *file, void (*func)(char *));
+void activate_fileselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *));
+void activate_fileselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+
void activate_imageselect(int type, char *title, char *file, void (*func)(char *));
+
void activate_databrowse(struct ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short));
+void activate_databrowse_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+
void filesel_prevspace(void);
void free_filesel_spec(char *dir);
void winqreadfilespace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
diff --git a/source/blender/include/BSE_node.h b/source/blender/include/BSE_node.h
index 626c9e75cbc..bbe79c1e8ff 100644
--- a/source/blender/include/BSE_node.h
+++ b/source/blender/include/BSE_node.h
@@ -44,6 +44,8 @@ struct bNodeTree;
struct Material;
struct ID;
struct Scene;
+struct Image;
+struct ImageUser;
/* ************* API for editnode.c *********** */
@@ -82,6 +84,12 @@ void node_adduplicate(struct SpaceNode *snode);
void snode_autoconnect(struct SpaceNode *snode, struct bNode *node_to, int flag);
void node_select_linked(struct SpaceNode *snode, int out);
+struct ImageUser *ntree_get_active_iuser(struct bNodeTree *ntree);
+
+void imagepaint_composite_tags(struct bNodeTree *ntree, struct Image *image, struct ImageUser *iuser);
+
+
+
/* ************* drawnode.c *************** */
struct SpaceNode;
struct bNodeLink;
diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h
index fee04ac50a8..aaad17453ef 100644
--- a/source/blender/include/blendef.h
+++ b/source/blender/include/blendef.h
@@ -44,8 +44,7 @@
/* max length material array, 16 because of bits in matfrom */
#define MAXPICKBUF 10000
#define MAXSEQ 32
-/* in Image struct */
-#define MAXMIPMAP 10
+
/* in buttons.c */
#define MAX_EFFECT 20
@@ -326,6 +325,13 @@
#define B_SIMABRUSHCHANGE 377
#define B_SIMABTEXBROWSE 378
#define B_SIMABTEXDELETE 379
+#define B_SIMARELOAD 380
+#define B_SIMANAME 381
+#define B_SIMAMULTI 382
+#define B_TRANS_IMAGE 383
+#define B_SIMA_REPACK 384
+#define B_SIMA_PLAY 385
+#define B_SIMA_RECORD 386
/* BUTS: 400 */
#define B_BUTSHOME 401
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index bd0b2adaa31..75bc8ff6ed3 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -41,6 +41,8 @@ struct ColorBand;
struct uiBlock;
struct rctf;
struct CurveMap;
+struct ImageUser;
+struct RenderResult;
/* buts->scaflag */
#define BUTS_SENS_SEL 1
@@ -115,6 +117,10 @@ extern void radio_panels(void);
extern void do_radiobuts(unsigned short event);
extern void texture_panels(void);
extern void do_texbuts(unsigned short event);
+void uiblock_image_panel(struct uiBlock *block, struct Image **ima_pp, struct ImageUser *iuser,
+ short redraw, short imagechanged);
+void uiblock_layer_pass_buttons(struct uiBlock *block, struct RenderResult *rr,
+ struct ImageUser *iuser, int event, int x, int y, int w);
/* logic */
extern void do_logic_buts(unsigned short event);
@@ -151,18 +157,11 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
/* *********************** */
#define B_VIEWBUTS 1100
-#define B_LOADBGPIC 1001
-#define B_BLENDBGPIC 1002
-#define B_BGPICBROWSE 1003
-#define B_BGPICTEX 1004
-#define B_BGPICCLEAR 1005
-#define B_BGPICTEXCLEAR 1006
-
#define B_OBJECTPANELROT 1007
-#define B_OBJECTPANELMEDIAN 1008
+#define B_OBJECTPANELMEDIAN 1008
#define B_ARMATUREPANEL1 1009
#define B_ARMATUREPANEL2 1010
-#define B_OBJECTPANELPARENT 1011
+#define B_OBJECTPANELPARENT 1011
#define B_OBJECTPANEL 1012
#define B_ARMATUREPANEL3 1013
#define B_OBJECTPANELSCALE 1014
@@ -213,13 +212,12 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_TEXTYPE 1301
#define B_DEFTEXVAR 1302
-#define B_LOADTEXIMA 1303
+
#define B_NAMEIMA 1304
#define B_TEXCHANNEL 1305
#define B_TEXREDR_PRV 1306
-#define B_TEXIMABROWSE 1307
-#define B_IMAPTEST 1308
-#define B_RELOADIMA 1309
+#define B_IMAGECHANGED 1307
+
#define B_LOADPLUGIN 1310
#define B_NAMEPLUGIN 1311
#define B_COLORBAND 1312
@@ -233,20 +231,18 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_LOADTEXIMA1 1320
#define B_TEXPRV 1321
+
#define B_PLUGBUT 1325
/* B_PLUGBUT reserves 24 buttons at least! */
#define B_ENV_MAKE 1350
#define B_ENV_FREE 1351
-#define B_ENV_DELETE 1352
+#define B_ENV_DELETE 1352
#define B_ENV_SAVE 1353
#define B_ENV_OB 1354
-#define B_PACKIMA 1355
-#define B_TEXSETFRAMES 1356
+#define B_ENV_FREE_ALL 1357
-#define B_ENV_FREE_ALL 1357
-#define B_UNLINKIMA 1358
/* **************** animbuts = object buttons ******* */
#define B_ANIMBUTS 1500
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index deabcee590a..d99e19ce456 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -39,6 +39,7 @@
struct PackedFile;
struct anim;
struct ImBuf;
+struct RenderResult;
typedef struct PreviewImage {
unsigned int w;
@@ -46,23 +47,43 @@ typedef struct PreviewImage {
unsigned int * rect;
} PreviewImage;
+/* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
+/* should be used in conjunction with an ID * to Image. */
+typedef struct ImageUser {
+ int framenr; /* movies, sequences: current to display */
+ int frames; /* total amount of frames to use */
+ int offset, sfra; /* offset within movie, start frame in global time */
+ short fie_ima, cycl; /* fields/image in movie, cyclic flag */
+ short flag, ok;
+
+ short multi_index, layer, pass; /* listbase indices, for menu browsing or retrieve buffer */
+ short menunr; /* localized menu entry, for handling browse event */
+} ImageUser;
+
+/* iuser->flag */
+#define IMA_ANIM_ALWAYS 1
+#define IMA_ANIM_REFRESHED 2
+
typedef struct Image {
ID id;
- char name[160];
+ char name[240];
+ ListBase ibufs; /* not written in file */
+
+ /* sources from: */
struct anim *anim;
- struct ImBuf *ibuf;
- struct ImBuf *mipmap[10];
+ struct RenderResult *rr;
short ok, flag;
+ short source, type, pad, pad1;
int lastframe;
/* texture page */
short tpageflag, totbind;
short xrep, yrep;
short twsta, twend;
- unsigned int bindcode;
+ unsigned int bindcode; /* only for current image... */
unsigned int *repbind; /* for repeat of parts of images */
struct PackedFile * packedfile;
@@ -71,25 +92,25 @@ typedef struct Image {
float lastupdate;
int lastused;
short animspeed;
- short reserved1;
- int reserved2;
+
+ short gen_x, gen_y, gen_type; /* for generated images */
+
/*#ifdef WITH_VERSE*/
void *vnode; /* pointer at verse bitmap node */
/*#endif*/
} Image;
-/* in Image struct */
-#define MAXMIPMAP 10
/* **************** IMAGE ********************* */
/* flag */
-#define IMA_HALVE 1
-#define IMA_BW 2
-#define IMA_FROMANIM 4
-#define IMA_USED 8
+#define IMA_FIELDS 1
+#define IMA_STD_FIELD 2
+
#define IMA_REFLECT 16
#define IMA_NOCOLLECT 32
+#define IMA_ANTIALI 64
+
/* tpageflag */
#define IMA_TILES 1
@@ -97,5 +118,7 @@ typedef struct Image {
#define IMA_COLCYCLE 4 /* Depreciated */
#define IMA_MIPMAP_COMPLETE 8 /* all mipmap levels in OpenGL texture set? */
+/* ima->type and ima->source moved to BKE_image.h, for API */
+
#endif
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index efc812af092..5e899dce0f6 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -182,6 +182,7 @@ typedef struct bNodeTree {
/* data structs, for node->storage */
+/* this one has been replaced with ImageUser, keep it for do_versions() */
typedef struct NodeImageAnim {
int frames, sfra, nr;
char cyclic, movie;
diff --git a/source/blender/makesdna/DNA_packedFile_types.h b/source/blender/makesdna/DNA_packedFile_types.h
index 7c4dc58006a..a0fdd892106 100644
--- a/source/blender/makesdna/DNA_packedFile_types.h
+++ b/source/blender/makesdna/DNA_packedFile_types.h
@@ -55,6 +55,7 @@ enum PF_FileStatus
PF_USE_LOCAL,
PF_USE_ORIGINAL,
PF_KEEP,
+ PF_REMOVE,
PF_NOOP,
PF_ASK
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 87ff72f7025..8f3ee4e0e3f 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -593,15 +593,16 @@ typedef struct Scene {
#define R_AVIJPEG 16
#define R_PNG 17
#define R_AVICODEC 18
-#define R_QUICKTIME 19
+#define R_QUICKTIME 19
#define R_BMP 20
#define R_RADHDR 21
#define R_TIFF 22
#define R_OPENEXR 23
#define R_FFMPEG 24
#define R_FRAMESERVER 25
-#define R_CINEON 26
-#define R_DPX 27
+#define R_CINEON 26
+#define R_DPX 27
+#define R_MULTILAYER 28
/* subimtype, flag options for imtype */
#define R_OPENEXR_HALF 1
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 210ecc20119..1f5391d59b1 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -36,7 +36,8 @@
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
-#include "DNA_oops_types.h" /* for TreeStoreElem */
+#include "DNA_oops_types.h" /* for TreeStoreElem */
+#include "DNA_image_types.h" /* ImageUser */
/* Hum ... Not really nice... but needed for spacebuts. */
#include "DNA_view2d_types.h"
@@ -163,31 +164,27 @@ typedef struct SpaceFile {
struct direntry *filelist;
int totfile;
+
char title[24];
char dir[160];
char file[80];
+
short type, ofs, flag, sort;
short maxnamelen, collums;
struct BlendHandle *libfiledata;
- short retval, ipotype;
- short menu, act;
-
- /* changed type for compiling */
- /* void (*returnfunc)(short); ? used with char* ....*/
- /**
- * @attention Called in filesel.c:
- * @attention returnfunc(this->retval) : short
- * @attention returnfunc(name) : char*
- * @attention Other uses are limited to testing against
- * @attention the value. How do we resolve this? Two args?
- * @attention For now, keep the char*, as it seems stable.
- * @attention Be warned that strange behaviour _has_ been spotted!
- */
- void (*returnfunc)(char*);
-
- short *menup;
+ unsigned short retval; /* event */
+ short menu, act, ipotype;
+
+ /* one day we'll add unions to dna */
+ void (*returnfunc)(char *);
+ void (*returnfunc_event)(unsigned short);
+ void (*returnfunc_args)(char *, void *, void *);
+
+ void *arg1, *arg2;
+ short *menup; /* pointer to menu result or ID browsing */
+ char *pupmenu; /* optional menu in header */
} SpaceFile;
typedef struct SpaceOops {
@@ -228,18 +225,21 @@ typedef struct SpaceImage {
View2D v2d;
struct Image *image;
+ struct ImageUser iuser;
+
struct CurveMapping *cumap;
short mode, menunr;
short imanr, curtile;
int flag;
- short pad1, lock;
-
- float zoom, pad2;
+ short imtypenr, lock;
+ short showspare, pad2;
+ float zoom;
- float xof, yof; /* user defined offset, image is centered */
+ float xof, yof; /* user defined offset, image is centered */
+ float centx, centy; /* storage for offset while render drawing */
- float centx, centy; /* storage for offset while render drawing */
- char *info_str; /* info string for render */
+ char *info_str, *info_spare; /* info string for render */
+ struct ImBuf *spare;
} SpaceImage;
typedef struct SpaceNla{
@@ -429,9 +429,11 @@ typedef struct SpaceImaSel {
/* sbuts->flag */
#define SB_PRV_OSA 1
-/* these values need to be hardcoded in blender.h SpaceFile: struct dna does not recognize defines */
+/* these values need to be hardcoded in structs, dna does not recognize defines */
+/* also defined in BKE */
#define FILE_MAXDIR 160
#define FILE_MAXFILE 80
+#define FILE_MAX 240
/* filesel types */
#define FILE_UNIX 8
@@ -589,7 +591,8 @@ typedef struct SpaceImaSel {
#define TIME_ALL_ANIM_WIN 4
#define TIME_ALL_BUTS_WIN 8
#define TIME_WITH_SEQ_AUDIO 16
-#define TIME_SEQ 32
+#define TIME_SEQ 32
+#define TIME_ALL_IMAGE_WIN 64
/* sseq->mainb */
#define SEQ_DRAW_SEQUENCE 0
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 01de2196f8c..eae2a07ec6e 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -35,6 +35,7 @@
#define DNA_TEXTURE_TYPES_H
#include "DNA_ID.h"
+#include "DNA_image_types.h"
struct Ipo;
struct PluginTex;
@@ -43,6 +44,7 @@ struct EnvMap;
struct Object;
struct Tex;
struct Image;
+struct ImBuf;
typedef struct MTex {
@@ -112,7 +114,7 @@ typedef struct ColorBand {
typedef struct EnvMap {
struct Object *object;
struct Image *ima; /* type ENV_LOAD */
- struct Image *cube[6]; /* these images are dynamic, not part of the main struct */
+ struct ImBuf *cube[6]; /* these images are dynamic, not part of the main struct */
float imat[4][4];
float obimat[3][3];
short type, stype;
@@ -152,19 +154,23 @@ typedef struct Tex {
float cropxmin, cropymin, cropxmax, cropymax;
short xrepeat, yrepeat;
short extend;
+
+ /* variables disabled, moved to struct iuser */
short fie_ima;
int len;
- float checkerdist, nabla;
int frames, offset, sfra;
+
+ float checkerdist, nabla;
float norfac;
+ struct ImageUser iuser;
+
struct Ipo *ipo;
struct Image *ima;
struct PluginTex *plugin;
struct ColorBand *coba;
struct EnvMap *env;
- int fradur[4][2];
} Tex;
@@ -234,18 +240,18 @@ typedef struct TexMapping {
#define TEX_INTERPOL 1
#define TEX_USEALPHA 2
#define TEX_MIPMAP 4
-#define TEX_FIELDS 8
#define TEX_IMAROT 16
#define TEX_CALCALPHA 32
-#define TEX_ANIMCYCLIC 64
-#define TEX_ANIM5 128
-#define TEX_ANTIALI 256
-#define TEX_ANTISCALE 512
-#define TEX_STD_FIELD 1024
#define TEX_NORMALMAP 2048
#define TEX_GAUSS_MIP 4096
-#define TEX_MORKPATCH 16384
+/* imaflag unused, only for version check */
+#define TEX_FIELDS_ 8
+#define TEX_ANIMCYCLIC_ 64
+#define TEX_ANIM5_ 128
+#define TEX_ANTIALI_ 256
+#define TEX_ANTISCALE_ 512
+#define TEX_STD_FIELD_ 1024
/* flag */
#define TEX_COLORBAND 1
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 27ccc318067..451c9c231c2 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -54,17 +54,16 @@ struct RetopoViewData;
#endif
#include "DNA_listBase.h"
+#include "DNA_image_types.h"
/* The near/far thing is a Win EXCEPTION. Thus, leave near/far in the
* code, and patch for windows. */
typedef struct BGpic {
struct Image *ima;
- struct ImBuf *ibuf;
- struct Tex *tex;
+ struct ImageUser iuser;
float xof, yof, size, zoom, blend;
short xim, yim;
- unsigned int *rect;
} BGpic;
typedef struct View3D {
diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c
index ae51f85744e..c5e8fb27559 100644
--- a/source/blender/python/api2_2x/Draw.c
+++ b/source/blender/python/api2_2x/Draw.c
@@ -1534,6 +1534,7 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
PyObject *pyObjImage;
BPy_Image *py_img;
Image *image;
+ ImBuf *ibuf;
float originX, originY;
float zoomX = 1.0, zoomY = 1.0;
int clipX = 0, clipY = 0, clipW = -1, clipH = -1;
@@ -1559,14 +1560,15 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
/* fetch a C Image pointer from the passed-in Python object */
py_img = ( BPy_Image * ) pyObjImage;
image = py_img->image;
-
- /* load the image data if necessary */
- if( !image->ibuf ) /* if no image data is available ... */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
- if( !image->ibuf ) /* if failed to load the image */
+ ibuf = BKE_image_get_ibuf( image, NULL );
+
+ if( !ibuf ) /* if failed to load the image */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't load image data in Blender" );
-
+ "couldn't load image data in Blender" );
+ if( !ibuf->rect ) /* no float yet */
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "Image has no byte rect" );
+
/* Update the time tag of the image */
tag_image_time(image);
@@ -1575,12 +1577,12 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
* the clipping is just checked against the bounds of the image.
* if clipW or clipH are less than zero then they include as much of
* the image as they can. */
- clipX = EXPP_ClampInt( clipX, 0, image->ibuf->x );
- clipY = EXPP_ClampInt( clipY, 0, image->ibuf->y );
- if( ( clipW < 0 ) || ( clipW > ( image->ibuf->x - clipW ) ) )
- clipW = image->ibuf->x - clipX;
- if( ( clipH < 0 ) || ( clipH > ( image->ibuf->y - clipH ) ) )
- clipH = image->ibuf->y - clipY;
+ clipX = EXPP_ClampInt( clipX, 0, ibuf->x );
+ clipY = EXPP_ClampInt( clipY, 0, ibuf->y );
+ if( ( clipW < 0 ) || ( clipW > ( ibuf->x - clipW ) ) )
+ clipW = ibuf->x - clipX;
+ if( ( clipH < 0 ) || ( clipH > ( ibuf->y - clipH ) ) )
+ clipH = ibuf->y - clipY;
/* -- we are "Go" to Draw! -- */
@@ -1626,13 +1628,13 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
/* set the width of the image (ROW_LENGTH), and the offset to the
* clip origin within the image in x (SKIP_PIXELS) and
* y (SKIP_ROWS) */
- glPixelStorei( GL_UNPACK_ROW_LENGTH, image->ibuf->x );
+ glPixelStorei( GL_UNPACK_ROW_LENGTH, ibuf->x );
glPixelStorei( GL_UNPACK_SKIP_PIXELS, clipX );
glPixelStorei( GL_UNPACK_SKIP_ROWS, clipY );
/* draw the image */
glDrawPixels( clipW, clipH, GL_RGBA, GL_UNSIGNED_BYTE,
- image->ibuf->rect );
+ ibuf->rect );
/* restore the defaults for some parameters (we could also use a
* glPushClientAttrib() and glPopClientAttrib() pair). */
diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c
index 9d9ac6c6184..75dae874dd7 100644
--- a/source/blender/python/api2_2x/Image.c
+++ b/source/blender/python/api2_2x/Image.c
@@ -232,12 +232,12 @@ static PyObject *M_Image_New( PyObject * self, PyObject * args)
if (width > 5000 || height > 5000 || width < 1 || height < 1)
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"Image width and height must be between 1 and 5000" ) );
- image = new_image(width, height, name, 0);
+ image = BKE_add_image_size(width, height, name, 0);
if( !image )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyObject Image_Type" ) );
- /* reset usage count, since new_image() incremented it */
+ /* reset usage count, since BKE_add_image_size() incremented it */
/* image->id.us--; */
/* Strange, new images have a user count of one???, otherwise it messes up */
@@ -354,14 +354,13 @@ static PyObject *M_Image_Load( PyObject * self, PyObject * args )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyObject Image_Type" ) );
- img_ptr = add_image( fname );
+ img_ptr = BKE_add_image_file( fname );
if( !img_ptr )
return ( EXPP_ReturnPyObjError( PyExc_IOError,
"couldn't load image" ) );
- /*reload the image buffers*/
- free_image_buffers(img_ptr);
- img_ptr->ibuf = IMB_loadiffname(img_ptr->name , 0);
+ /* force a load the image buffers*/
+ BKE_image_get_ibuf(img_ptr, NULL);
image->image = img_ptr;
@@ -380,7 +379,7 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
{
PyObject *attr;
- Image *image = self->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
char *pixel; /* image data */
int index; /* offset into image data */
int x = 0;
@@ -391,20 +390,17 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected 2 integers" );
- if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
+ if( !ibuf || !ibuf->rect ) /* loading didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- if( image->ibuf->type == 1 ) /* bitplane image */
+ if( ibuf->type == 1 ) /* bitplane image */
return EXPP_ReturnPyObjError( PyExc_TypeError,
"unsupported bitplane image format" );
- if( x > ( image->ibuf->x - 1 )
- || y > ( image->ibuf->y - 1 )
- || x < image->ibuf->xorig || y < image->ibuf->yorig )
+ if( x > ( ibuf->x - 1 )
+ || y > ( ibuf->y - 1 )
+ || x < ibuf->xorig || y < ibuf->yorig )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"x or y is out of range" );
@@ -413,9 +409,9 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
so we calc ourselves
*/
- index = ( x + y * image->ibuf->x ) * pixel_size;
+ index = ( x + y * ibuf->x ) * pixel_size;
- pixel = ( char * ) image->ibuf->rect;
+ pixel = ( char * ) ibuf->rect;
attr = Py_BuildValue( "[f,f,f,f]",
( ( float ) pixel[index] ) / 255.0,
( ( float ) pixel[index + 1] ) / 255.0,
@@ -440,7 +436,7 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
{
PyObject *attr;
- Image *image = self->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
char *pixel; /* image data */
int index; /* offset into image data */
int x = 0;
@@ -451,20 +447,17 @@ static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected 2 integers" );
- if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
+ if( !ibuf || !ibuf->rect ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- if( image->ibuf->type == 1 ) /* bitplane image */
+ if( ibuf->type == 1 ) /* bitplane image */
return EXPP_ReturnPyObjError( PyExc_TypeError,
"unsupported bitplane image format" );
- if( x > ( image->ibuf->x - 1 )
- || y > ( image->ibuf->y - 1 )
- || x < image->ibuf->xorig || y < image->ibuf->yorig )
+ if( x > ( ibuf->x - 1 )
+ || y > ( ibuf->y - 1 )
+ || x < ibuf->xorig || y < ibuf->yorig )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"x or y is out of range" );
@@ -473,9 +466,9 @@ static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
so we calc ourselves
*/
- index = ( x + y * image->ibuf->x ) * pixel_size;
+ index = ( x + y * ibuf->x ) * pixel_size;
- pixel = ( char * ) image->ibuf->rect;
+ pixel = ( char * ) ibuf->rect;
attr = Py_BuildValue( "[i,i,i,i]",
pixel[index],
pixel[index + 1],
@@ -493,7 +486,7 @@ static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
{
- Image *image = self->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
char *pixel; /* image data */
int index; /* offset into image data */
int x = 0;
@@ -507,20 +500,17 @@ static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected 2 integers and an array of 4 floats" );
- if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
+ if( !ibuf || !ibuf->rect ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- if( image->ibuf->type == 1 ) /* bitplane image */
+ if( ibuf->type == 1 ) /* bitplane image */
return EXPP_ReturnPyObjError( PyExc_TypeError,
"unsupported bitplane image format" );
- if( x > ( image->ibuf->x - 1 )
- || y > ( image->ibuf->y - 1 )
- || x < image->ibuf->xorig || y < image->ibuf->yorig )
+ if( x > ( ibuf->x - 1 )
+ || y > ( ibuf->y - 1 )
+ || x < ibuf->xorig || y < ibuf->yorig )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"x or y is out of ruange" );
@@ -536,9 +526,9 @@ static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
so we calc ourselves
*/
- index = ( x + y * image->ibuf->x ) * pixel_size;
+ index = ( x + y * ibuf->x ) * pixel_size;
- pixel = ( char * ) image->ibuf->rect;
+ pixel = ( char * ) ibuf->rect;
pixel[index] = ( char ) ( p[0] * 255.0 );
pixel[index + 1] = ( char ) ( p[1] * 255.0 );
@@ -553,7 +543,7 @@ static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
{
- Image *image = self->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
char *pixel; /* image data */
int index; /* offset into image data */
int x = 0;
@@ -567,20 +557,17 @@ static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected 2 integers and an list of 4 ints" );
- if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
+ if( !ibuf || !ibuf->rect ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- if( image->ibuf->type == 1 ) /* bitplane image */
+ if( ibuf->type == 1 ) /* bitplane image */
return EXPP_ReturnPyObjError( PyExc_TypeError,
"unsupported bitplane image format" );
- if( x > ( image->ibuf->x - 1 )
- || y > ( image->ibuf->y - 1 )
- || x < image->ibuf->xorig || y < image->ibuf->yorig )
+ if( x > ( ibuf->x - 1 )
+ || y > ( ibuf->y - 1 )
+ || x < ibuf->xorig || y < ibuf->yorig )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"x or y is out of range" );
@@ -595,9 +582,9 @@ static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
so we calc ourselves
*/
- index = ( x + y * image->ibuf->x ) * pixel_size;
+ index = ( x + y * ibuf->x ) * pixel_size;
- pixel = ( char * ) image->ibuf->rect;
+ pixel = ( char * ) ibuf->rect;
pixel[index] = ( char ) p[0];
pixel[index + 1] = ( char ) p[1];
@@ -612,17 +599,14 @@ static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
static PyObject *Image_getMaxXY( BPy_Image * self )
{
- Image *image = self->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
PyObject *attr;
- if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
+ if( !ibuf || !ibuf->rect ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- attr = Py_BuildValue( "[i,i]", image->ibuf->x, image->ibuf->y );
+ attr = Py_BuildValue( "[i,i]", ibuf->x, ibuf->y );
if( attr )
return attr;
@@ -636,18 +620,15 @@ static PyObject *Image_getMaxXY( BPy_Image * self )
static PyObject *Image_getMinXY( BPy_Image * self )
{
- Image *image = self->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
PyObject *attr;
- if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
+ if( !ibuf || !ibuf->rect ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- attr = Py_BuildValue( "[i,i]", image->ibuf->xorig,
- image->ibuf->yorig );
+ attr = Py_BuildValue( "[i,i]", ibuf->xorig,
+ ibuf->yorig );
if( attr )
return attr;
@@ -713,9 +694,9 @@ static PyObject *Image_makeCurrent( BPy_Image * self )
static PyObject *Image_save( BPy_Image * self )
{
- if( !IMB_saveiff
- ( self->image->ibuf, self->image->name,
- self->image->ibuf->flags ) )
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+
+ if(!ibuf || !IMB_saveiff( ibuf, self->image->name, ibuf->flags ) )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"could not save image" );
@@ -849,18 +830,14 @@ static PyObject *Image_getFilename( BPy_Image * self )
static PyObject *Image_getSize( BPy_Image * self )
{
- PyObject *attr;
- Image *image = self->image;
-
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+ PyObject *attr;
- if( !image->ibuf ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf ) /* didn't work */
+ if( !ibuf ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- attr = Py_BuildValue( "[hh]", image->ibuf->x, image->ibuf->y );
+ attr = Py_BuildValue( "[hh]", ibuf->x, ibuf->y );
if( attr )
return attr;
@@ -871,17 +848,14 @@ static PyObject *Image_getSize( BPy_Image * self )
static PyObject *Image_getDepth( BPy_Image * self )
{
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
PyObject *attr;
- Image *image = self->image;
-
- if( !image->ibuf ) /* if no image data available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
- if( !image->ibuf ) /* didn't work */
+ if( !ibuf ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- attr = Py_BuildValue( "h", image->ibuf->depth );
+ attr = Py_BuildValue( "h", ibuf->depth );
if( attr )
return attr;
@@ -961,8 +935,8 @@ static PyObject *Image_reload( BPy_Image * self )
{
Image *image = self->image;
- free_image_buffers( image ); /* force read again */
- image->ok = 1;
+ BKE_image_signal(image, NULL, IMA_SIGNAL_RELOAD);
+
Py_RETURN_NONE;
}
@@ -982,29 +956,27 @@ static PyObject *Image_glLoad( BPy_Image * self )
unsigned int *bind = &image->bindcode;
if( *bind == 0 ) {
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
- if( !image->ibuf ) /* if no image data is available */
- load_image( image, IB_rect, G.sce, G.scene->r.cfra ); /* loading it */
-
- if( !image->ibuf ) /* didn't work */
+ if( !ibuf ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
glGenTextures( 1, ( GLuint * ) bind );
glBindTexture( GL_TEXTURE_2D, *bind );
- gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, image->ibuf->x,
- image->ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
- image->ibuf->rect );
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, ibuf->x,
+ ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
+ ibuf->rect );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image->ibuf->x,
- image->ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- image->ibuf->rect );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ibuf->x,
+ ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ ibuf->rect );
/* raise the nocollect flag,
image is not available for garbage collection
@@ -1176,7 +1148,7 @@ static PyObject *Image_getAttr( BPy_Image * self, char *name )
else
attr = EXPP_incr_ret_False();
} else if( strcmp( name, "has_data" ) == 0 ) {
- if (self->image->ibuf)
+ if (self->image->ibufs.first)
attr = EXPP_incr_ret_True();
else
attr = EXPP_incr_ret_False();
diff --git a/source/blender/python/api2_2x/Texture.c b/source/blender/python/api2_2x/Texture.c
index 1e2588ea43e..42e8e1ca5f8 100644
--- a/source/blender/python/api2_2x/Texture.c
+++ b/source/blender/python/api2_2x/Texture.c
@@ -208,17 +208,13 @@ static const EXPP_map_pair tex_flag_map[] = {
{NULL, 0}
};
+/* NOTE: flags moved to image... */
static const EXPP_map_pair tex_imageflag_map[] = {
{"InterPol", TEX_INTERPOL},
{"UseAlpha", TEX_USEALPHA},
{"MipMap", TEX_MIPMAP},
- {"Fields", TEX_FIELDS},
{"Rot90", TEX_IMAROT},
{"CalcAlpha", TEX_CALCALPHA},
- {"Cyclic", TEX_ANIMCYCLIC},
- {"Movie", TEX_ANIM5},
- {"StField", TEX_STD_FIELD},
- {"Anti", TEX_ANTIALI},
{"NormalMap", TEX_NORMALMAP},
{NULL, 0}
};
@@ -397,6 +393,10 @@ GETFUNC( getName );
GETFUNC( getType );
GETFUNC( getSType );
GETFUNC( clearIpo );
+GETFUNC( getAnimMontage );
+GETFUNC( getAnimLength );
+SETFUNC( setAnimLength );
+SETFUNC( setAnimMontage );
#endif
GETFUNC( oldgetSType );
@@ -405,8 +405,6 @@ GETFUNC( oldgetType );
GETFUNC(getProperties);
GETFUNC( clearIpo );
GETFUNC( getAnimFrames );
-GETFUNC( getAnimLength );
-GETFUNC( getAnimMontage );
GETFUNC( getAnimOffset );
GETFUNC( getAnimStart );
GETFUNC( getBrightness );
@@ -455,8 +453,6 @@ OLDSETFUNC( setSType );
OLDSETFUNC( setType );
SETFUNC( setAnimFrames );
-SETFUNC( setAnimLength );
-SETFUNC( setAnimMontage );
SETFUNC( setAnimOffset );
SETFUNC( setAnimStart );
SETFUNC( setBrightness );
@@ -552,6 +548,7 @@ static PyGetSetDef BPy_Texture_getseters[] = {
(getter)Texture_getAnimFrames, (setter)Texture_setAnimFrames,
"Number of frames of a movie to use",
NULL},
+#if 0
{"animLength",
(getter)Texture_getAnimLength, (setter)Texture_setAnimLength,
"Number of frames of a movie to use (0 for all)",
@@ -560,6 +557,7 @@ static PyGetSetDef BPy_Texture_getseters[] = {
(getter)Texture_getAnimMontage, (setter)Texture_setAnimMontage,
"Montage mode, start frames and durations",
NULL},
+#endif
{"animOffset",
(getter)Texture_getAnimOffset, (setter)Texture_setAnimOffset,
"Offsets the number of the first movie frame to use",
@@ -729,14 +727,16 @@ static PyGetSetDef BPy_Texture_getseters[] = {
(getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
"Mipmaps enabled ('ImageFlags')",
(void *)TEX_MIPMAP},
- {"fields",
- (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
- "Use of image's fields enabled ('ImageFlags')",
- (void *)TEX_FIELDS},
{"rot90",
(getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
"X/Y flip for rendering enabled ('ImageFlags')",
(void *)TEX_IMAROT},
+#if 0
+ /* disabled, moved to image */
+ {"fields",
+ (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
+ "Use of image's fields enabled ('ImageFlags')",
+ (void *)TEX_FIELDS},
{"cyclic",
(getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
"Looping of animated frames enabled ('ImageFlags')",
@@ -753,6 +753,7 @@ static PyGetSetDef BPy_Texture_getseters[] = {
(getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
"Standard field deinterlacing enabled ('ImageFlags')",
(void *)TEX_STD_FIELD},
+#endif
{"normalMap",
(getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
"Use of image RGB values for normal mapping enabled ('ImageFlags')",
@@ -1174,12 +1175,8 @@ static PyObject *M_Texture_ImageFlagsDict( void )
PyConstant_Insert(d, "INTERPOL", PyInt_FromLong(TEX_INTERPOL));
PyConstant_Insert(d, "USEALPHA", PyInt_FromLong(TEX_USEALPHA));
PyConstant_Insert(d, "MIPMAP", PyInt_FromLong(TEX_MIPMAP));
- PyConstant_Insert(d, "FIELDS", PyInt_FromLong(TEX_FIELDS));
PyConstant_Insert(d, "ROT90", PyInt_FromLong(TEX_IMAROT));
PyConstant_Insert(d, "CALCALPHA", PyInt_FromLong(TEX_CALCALPHA));
- PyConstant_Insert(d, "STFIELD", PyInt_FromLong(TEX_STD_FIELD));
- PyConstant_Insert(d, "MOVIE", PyInt_FromLong(TEX_ANIM5));
- PyConstant_Insert(d, "CYCLIC", PyInt_FromLong(TEX_ANIMCYCLIC));
PyConstant_Insert(d, "NORMALMAP", PyInt_FromLong(TEX_NORMALMAP));
}
return ImageFlags;
@@ -1422,11 +1419,13 @@ static PyObject *Texture_oldgetType( BPy_Texture * self )
static int Texture_setAnimFrames( BPy_Texture * self, PyObject * value )
{
- return EXPP_setIValueClamped ( value, &self->texture->frames,
+ return EXPP_setIValueClamped ( value, &self->texture->iuser.frames,
EXPP_TEX_ANIMFRAME_MIN,
EXPP_TEX_ANIMFRAME_MAX, 'h' );
}
+#if 0
+/* this was stupid to begin with! (ton) */
static int Texture_setAnimLength( BPy_Texture * self, PyObject * value )
{
return EXPP_setIValueClamped ( value, &self->texture->len,
@@ -1434,6 +1433,7 @@ static int Texture_setAnimLength( BPy_Texture * self, PyObject * value )
EXPP_TEX_ANIMLEN_MAX, 'h' );
}
+/* this is too simple to keep supporting? disabled for time being (ton) */
static int Texture_setAnimMontage( BPy_Texture * self, PyObject * value )
{
int fradur[4][2];
@@ -1458,17 +1458,18 @@ static int Texture_setAnimMontage( BPy_Texture * self, PyObject * value )
return 0;
}
+#endif
static int Texture_setAnimOffset( BPy_Texture * self, PyObject * value )
{
- return EXPP_setIValueClamped ( value, &self->texture->offset,
+ return EXPP_setIValueClamped ( value, &self->texture->iuser.offset,
EXPP_TEX_ANIMOFFSET_MIN,
EXPP_TEX_ANIMOFFSET_MAX, 'h' );
}
static int Texture_setAnimStart( BPy_Texture * self, PyObject * value )
{
- return EXPP_setIValueClamped ( value, &self->texture->sfra,
+ return EXPP_setIValueClamped ( value, &self->texture->iuser.sfra,
EXPP_TEX_ANIMSTART_MIN,
EXPP_TEX_ANIMSTART_MAX, 'h' );
}
@@ -1610,13 +1611,8 @@ static int Texture_setImageFlags( BPy_Texture * self, PyObject * value,
int bitmask = TEX_INTERPOL
| TEX_USEALPHA
| TEX_MIPMAP
- | TEX_FIELDS
| TEX_IMAROT
| TEX_CALCALPHA
- | TEX_ANIMCYCLIC
- | TEX_ANIM5
- | TEX_ANTIALI
- | TEX_STD_FIELD
| TEX_NORMALMAP;
if( !PyInt_CheckExact ( value ) ) {
@@ -1631,13 +1627,6 @@ static int Texture_setImageFlags( BPy_Texture * self, PyObject * value,
"invalid bit(s) set in mask" );
}
- /* "mipmap" and "fields" can't be set at the same time */
-
- if( ( param & TEX_MIPMAP ) &&
- ( param & TEX_FIELDS ) )
- return EXPP_ReturnIntError( PyExc_ValueError,
- "image flags MIPMAP and FIELDS cannot be used together" );
-
/* everything is OK; save the new flag setting */
self->texture->imaflag = param;
@@ -2024,6 +2013,8 @@ static PyObject *Texture_getAnimFrames( BPy_Texture *self )
return attr;
}
+#if 0
+/* disabled. this option was too stupid! (ton) */
static PyObject *Texture_getAnimLength( BPy_Texture *self )
{
PyObject *attr = PyInt_FromLong( self->texture->len );
@@ -2055,10 +2046,11 @@ static PyObject *Texture_getAnimMontage( BPy_Texture *self )
return attr;
}
+#endif
static PyObject *Texture_getAnimOffset( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->offset );
+ PyObject *attr = PyInt_FromLong( self->texture->iuser.offset );
if( !attr )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -2069,7 +2061,7 @@ static PyObject *Texture_getAnimOffset( BPy_Texture *self )
static PyObject *Texture_getAnimStart( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->sfra );
+ PyObject *attr = PyInt_FromLong( self->texture->iuser.sfra );
if( !attr )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -2162,7 +2154,7 @@ static PyObject *Texture_getIntExtend( BPy_Texture * self )
static PyObject *Texture_getFieldsPerImage( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->fie_ima );
+ PyObject *attr = PyInt_FromLong( self->texture->iuser.fie_ima );
if( !attr )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index 8ef3c09ab00..2add056b4c8 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -42,6 +42,7 @@ struct View3D; /* keep me up here */
#include "BIF_drawscene.h"
#include "BIF_renderwin.h"
+#include "BIF_writeimage.h"
#include "BLI_blenlib.h"
@@ -108,7 +109,6 @@ enum rend_constants {
#define EXPP_RENDER_ATTR_YF_GIMETHOD 34
#define EXPP_RENDER_ATTR_YF_GIQUALITY 35
-extern void save_rendered_image_cb_real(char *name, int zbuf, int confirm);
/* Render doc strings */
static char M_Render_doc[] = "The Blender Render module";
@@ -420,8 +420,8 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
char *name_str, filepath[FILE_MAXDIR+FILE_MAXFILE];
RenderResult *rr = NULL;
- int zbuff = 0;
-
+ int zbuff;
+
if( !PyArg_ParseTuple( args, "s|i", &name_str, &zbuff ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a filename (string) and optional int" );
@@ -431,7 +431,7 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"full filename too long" );
- if (zbuff !=0 ) zbuff = 1; /*required 1/0 */
+ if (zbuff !=0 ) zbuff = 1; /*required 1/0 */ /* removed! (ton) */
BLI_strncpy( filepath, self->renderContext->pic, sizeof(filepath) );
strcat(filepath, name_str);
@@ -445,7 +445,7 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
BLI_splitdirstring(dir, str);
strcpy(G.ima, dir);
}
- save_rendered_image_cb_real(filepath, zbuff,0);
+ BIF_save_rendered_image(filepath);
}
return EXPP_incr_ret(Py_None);
}
@@ -1902,11 +1902,9 @@ static int RenderData_setBackbufPath( BPy_RenderData *self, PyObject *value )
strcpy( self->renderContext->backbuf, name );
EXPP_allqueue( REDRAWBUTSSCENE, 0 );
- ima = add_image( name );
- if( ima ) {
- free_image_buffers( ima );
- ima->ok = 1;
- }
+ ima = BKE_add_image_file( name );
+ if( ima )
+ BKE_image_signal( ima, NULL, IMA_SIGNAL_RELOAD );
return 0;
}
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 22b623816ab..72f266630c4 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -59,11 +59,14 @@ typedef struct Render Render;
typedef struct RenderPass {
struct RenderPass *next, *prev;
int passtype, channels;
+ char name[16]; /* amount defined in openexr_multi.h */
+ char chan_id[8]; /* amount defined in openexr_multi.h */
float *rect;
} RenderPass;
/* a renderlayer is a full image, but with all passes and samples */
/* size of the rects is defined in RenderResult */
+/* after render, the Combined pass is in rectf, for renderlayers read from files it is a real pass */
typedef struct RenderLayer {
struct RenderLayer *next, *prev;
@@ -75,7 +78,7 @@ typedef struct RenderLayer {
struct Material *mat_override;
struct Group *light_override;
- float *rectf; /* 4 float, standard rgba buffer */
+ float *rectf; /* 4 float, standard rgba buffer (read not above!) */
float *acolrect; /* 4 float, optional transparent buffer, needs storage for display updates */
ListBase passes;
@@ -111,6 +114,9 @@ typedef struct RenderResult {
char exrfile[FILE_MAXDIR];
void *exrhandle;
+ /* for render results in Image, verify validity for sequences */
+ int framenr;
+
} RenderResult;
typedef struct RenderStats {
@@ -134,6 +140,7 @@ void RE_FreeRender (struct Render *re);
void RE_FreeAllRender (void);
/* get results and statistics */
+void RE_FreeRenderResult(struct RenderResult *rr);
struct RenderResult *RE_GetResult(struct Render *re);
void RE_GetResultImage(struct Render *re, struct RenderResult *rr);
struct RenderStats *RE_GetStats(struct Render *re);
@@ -173,6 +180,8 @@ void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame);
void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra);
void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
+void RE_WriteRenderResult(RenderResult *rr, char *filename);
+struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty);
/* ancient stars function... go away! */
void RE_make_stars(struct Render *re, void (*initfunc)(void),
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index 13ab6f7cd67..6c7d12c4c8c 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -51,6 +51,7 @@ struct ShadeInput;
struct TexResult;
struct Tex;
struct Image;
+struct ImBuf;
/* texture.h */
@@ -65,8 +66,8 @@ void render_realtime_texture(struct ShadeInput *shi);
/* imagetexture.h */
-int imagewraposa(struct Tex *tex, struct Image *ima, float *texvec, float *dxt, float *dyt, struct TexResult *texres);
-int imagewrap(struct Tex *tex, struct Image *ima, float *texvec, struct TexResult *texres);
+int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, float *texvec, float *dxt, float *dyt, struct TexResult *texres);
+int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, float *texvec, struct TexResult *texres);
void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float *result);
#endif /* TEXTURE_EXT_H */
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index c6845754a7d..4f7420bacc2 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -2989,7 +2989,7 @@ void RE_Database_Free(Render *re)
if(re->scene)
if(re->scene->r.scemode & R_FREE_IMAGE)
if((re->r.scemode & R_PREVIEWBUTS)==0)
- free_all_imagetextures();
+ BKE_image_free_all_textures();
}
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 1cb7eb98545..782308a65ec 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -66,45 +66,37 @@
/* ------------------------------------------------------------------------- */
-static void envmap_split_ima(EnvMap *env)
+static void envmap_split_ima(EnvMap *env, ImBuf *ibuf)
{
- ImBuf *ibuf;
- Image *ima;
-/* extern rectcpy(); */
int dx, part;
BKE_free_envmapdata(env);
- dx= env->ima->ibuf->y;
+ dx= ibuf->y;
dx/= 2;
- if(3*dx != env->ima->ibuf->x) {
+ if(3*dx != ibuf->x) {
printf("Incorrect envmap size\n");
env->ok= 0;
env->ima->ok= 0;
}
else {
for(part=0; part<6; part++) {
- ibuf= IMB_allocImBuf(dx, dx, 24, IB_rect, 0);
- ima= MEM_callocN(sizeof(Image), "image");
- ima->ibuf= ibuf;
- ima->ok= 1;
- env->cube[part]= ima;
+ env->cube[part]= IMB_allocImBuf(dx, dx, 24, IB_rect, 0);
}
- IMB_rectcpy(env->cube[0]->ibuf, env->ima->ibuf,
+ IMB_rectcpy(env->cube[0], ibuf,
0, 0, 0, 0, dx, dx);
- IMB_rectcpy(env->cube[1]->ibuf, env->ima->ibuf,
+ IMB_rectcpy(env->cube[1], ibuf,
0, 0, dx, 0, dx, dx);
- IMB_rectcpy(env->cube[2]->ibuf, env->ima->ibuf,
+ IMB_rectcpy(env->cube[2], ibuf,
0, 0, 2*dx, 0, dx, dx);
- IMB_rectcpy(env->cube[3]->ibuf, env->ima->ibuf,
+ IMB_rectcpy(env->cube[3], ibuf,
0, 0, 0, dx, dx, dx);
- IMB_rectcpy(env->cube[4]->ibuf, env->ima->ibuf,
+ IMB_rectcpy(env->cube[4], ibuf,
0, 0, dx, dx, dx, dx);
- IMB_rectcpy(env->cube[5]->ibuf, env->ima->ibuf,
+ IMB_rectcpy(env->cube[5], ibuf,
0, 0, 2*dx, dx, dx, dx);
env->ok= ENV_OSA;
}
- printf("split\n");
}
/* ------------------------------------------------------------------------- */
@@ -372,7 +364,6 @@ static void render_envmap(Render *re, EnvMap *env)
/* only the cubemap and planar map is implemented */
Render *envre;
ImBuf *ibuf;
- Image *ima;
float orthmat[4][4];
float oldviewinv[4][4], mat[4][4], tmat[4][4];
short part;
@@ -431,11 +422,7 @@ static void render_envmap(Render *re, EnvMap *env)
IMB_rect_from_float(ibuf);
ibuf->rect_float= NULL;
- ima= MEM_callocN(sizeof(Image), "image");
-
- ima->ibuf= ibuf;
- ima->ok= 1;
- env->cube[part]= ima;
+ env->cube[part]= ibuf;
}
if(re->test_break()) break;
@@ -629,13 +616,10 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
extern Render R; /* only in this call */
/* texvec should be the already reflected normal */
EnvMap *env;
- Image *ima;
+ ImBuf *ibuf;
float fac, vec[3], sco[3], dxts[3], dyts[3];
int face, face1;
- if((R.r.mode & R_ENVMAP)==0)
- return 0;
-
env= tex->env;
if(env==NULL || (env->stype!=ENV_LOAD && env->object==NULL)) {
texres->tin= 0.0;
@@ -644,13 +628,9 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
if(env->stype==ENV_LOAD) {
env->ima= tex->ima;
if(env->ima && env->ima->ok) {
- if(env->ima->ibuf==NULL) {
- printf("load ibuf\n");
- BLI_lock_thread(LOCK_CUSTOM1);
- if(env->ima->ibuf==NULL) ima_ibuf_is_nul(tex, env->ima);
- if(env->ima->ok && env->ok==0)
- envmap_split_ima(env);
- BLI_unlock_thread(LOCK_CUSTOM1);
+ if(env->cube[0]==NULL) {
+ ImBuf *ibuf= BKE_image_get_ibuf(env->ima, NULL);
+ envmap_split_ima(env, ibuf);
}
}
}
@@ -667,7 +647,7 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
else MTC_Mat4Mul3Vecfl(R.viewinv, vec);
face= envcube_isect(env, vec, sco);
- ima= env->cube[face];
+ ibuf= env->cube[face];
if(osatex) {
if(env->object) {
@@ -679,7 +659,7 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
MTC_Mat4Mul3Vecfl(R.viewinv, dyt);
}
set_dxtdyt(dxts, dyts, dxt, dyt, face);
- imagewraposa(tex, ima, sco, dxts, dyts, texres);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres);
/* edges? */
@@ -693,9 +673,9 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
VecSubf(vec, vec, dxt);
if(face!=face1) {
- ima= env->cube[face1];
+ ibuf= env->cube[face1];
set_dxtdyt(dxts, dyts, dxt, dyt, face1);
- imagewraposa(tex, ima, sco, dxts, dyts, &texr1);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1);
}
else texr1.tr= texr1.tg= texr1.tb= texr1.ta= 0.0;
@@ -706,9 +686,9 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
VecSubf(vec, vec, dyt);
if(face!=face1) {
- ima= env->cube[face1];
+ ibuf= env->cube[face1];
set_dxtdyt(dxts, dyts, dxt, dyt, face1);
- imagewraposa(tex, ima, sco, dxts, dyts, &texr2);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2);
}
else texr2.tr= texr2.tg= texr2.tb= texr2.ta= 0.0;
@@ -724,7 +704,7 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
}
}
else {
- imagewrap(tex, ima, sco, texres);
+ imagewrap(tex, NULL, ibuf, sco, texres);
}
return 1;
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index a876a09e0b7..39af0893f81 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -69,14 +69,26 @@ extern struct Render R;
/* *********** IMAGEWRAPPING ****************** */
+
/* x and y have to be checked for image size */
static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y)
{
int ofs = y * ibuf->x + x;
if(ibuf->rect_float) {
- float *fp= ibuf->rect_float + 4*ofs;
- QUATCOPY(col, fp);
+ if(ibuf->channels==4) {
+ float *fp= ibuf->rect_float + 4*ofs;
+ QUATCOPY(col, fp);
+ }
+ else if(ibuf->channels==3) {
+ float *fp= ibuf->rect_float + 3*ofs;
+ VECCOPY(col, fp);
+ col[3]= 1.0f;
+ }
+ else {
+ float *fp= ibuf->rect_float + ofs;
+ col[0]= col[1]= col[2]= col[3]= *fp;
+ }
}
else {
char *rect = (char *)( ibuf->rect+ ofs);
@@ -88,156 +100,151 @@ static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y)
}
}
-int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres)
+int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texres)
{
- struct ImBuf *ibuf;
float fx, fy, val1, val2, val3;
- int x, y;
-
- texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0;
+ int x, y, retval;
- if(ima==NULL || ima->ok== 0) {
- if(texres->nor) return 3;
- else return 1;
- }
+ texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
- if(ima->ibuf==NULL) {
+ /* we need to set retval OK, otherwise texture code generates normals itself... */
+ retval= texres->nor?3:1;
+
+ /* quick tests */
+ if(ibuf==NULL && ima==NULL)
+ return retval;
+ if(ima) {
+
/* hack for icon render */
- if(R.r.scemode &R_NO_IMAGE_LOAD)
- return 0;
- if(ima->ibuf==NULL) {
- BLI_lock_thread(LOCK_CUSTOM1);
- if(ima->ibuf==NULL) ima_ibuf_is_nul(tex, ima);
- BLI_unlock_thread(LOCK_CUSTOM1);
- }
+ if(ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
+ return retval;
+
+ ibuf= BKE_image_get_ibuf(ima, &tex->iuser);
}
+ if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
+ return retval;
+
+ /* setup mapping */
+ if(tex->imaflag & TEX_IMAROT) {
+ fy= texvec[0];
+ fx= texvec[1];
+ }
+ else {
+ fx= texvec[0];
+ fy= texvec[1];
+ }
+
+ if(tex->extend == TEX_CHECKER) {
+ int xs, ys;
+
+ xs= (int)floor(fx);
+ ys= (int)floor(fy);
+ fx-= xs;
+ fy-= ys;
- if (ima->ok) {
- ibuf = ima->ibuf;
-
- if(tex->imaflag & TEX_IMAROT) {
- fy= texvec[0];
- fx= texvec[1];
+ if( (tex->flag & TEX_CHECKER_ODD)==0) {
+ if((xs+ys) & 1);else return retval;
}
- else {
- fx= texvec[0];
- fy= texvec[1];
+ if( (tex->flag & TEX_CHECKER_EVEN)==0) {
+ if((xs+ys) & 1) return retval;
}
-
- if(tex->extend == TEX_CHECKER) {
- int xs, ys;
-
- xs= (int)floor(fx);
- ys= (int)floor(fy);
- fx-= xs;
- fy-= ys;
-
- if( (tex->flag & TEX_CHECKER_ODD)==0) {
- if((xs+ys) & 1);else return 0;
- }
- if( (tex->flag & TEX_CHECKER_EVEN)==0) {
- if((xs+ys) & 1) return 0;
- }
- /* scale around center, (0.5, 0.5) */
- if(tex->checkerdist<1.0) {
- fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5;
- fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5;
- }
+ /* scale around center, (0.5, 0.5) */
+ if(tex->checkerdist<1.0) {
+ fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5;
+ fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5;
}
+ }
- x = (int)(fx*ibuf->x);
- y = (int)(fy*ibuf->y);
+ x = (int)(fx*ibuf->x);
+ y = (int)(fy*ibuf->y);
- if(tex->extend == TEX_CLIPCUBE) {
- if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0 || texvec[2]>1.0) {
- return 0;
- }
+ if(tex->extend == TEX_CLIPCUBE) {
+ if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0 || texvec[2]>1.0) {
+ return retval;
}
- else if( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
- if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
- return 0;
- }
+ }
+ else if( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
+ if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
+ return retval;
}
- else {
- if(tex->extend==TEX_EXTEND) {
- if(x>=ibuf->x) x = ibuf->x-1;
- else if(x<0) x= 0;
- }
- else {
- x= x % ibuf->x;
- if(x<0) x+= ibuf->x;
- }
- if(tex->extend==TEX_EXTEND) {
- if(y>=ibuf->y) y = ibuf->y-1;
- else if(y<0) y= 0;
- }
- else {
- y= y % ibuf->y;
- if(y<0) y+= ibuf->y;
- }
+ }
+ else {
+ if(tex->extend==TEX_EXTEND) {
+ if(x>=ibuf->x) x = ibuf->x-1;
+ else if(x<0) x= 0;
}
-
- /* warning, no return before setting back! */
- if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
- ibuf->rect+= (ibuf->x*ibuf->y);
+ else {
+ x= x % ibuf->x;
+ if(x<0) x+= ibuf->x;
}
-
- ibuf_get_color(&texres->tr, ibuf, x, y);
-
- if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
- ibuf->rect-= (ibuf->x*ibuf->y);
+ if(tex->extend==TEX_EXTEND) {
+ if(y>=ibuf->y) y = ibuf->y-1;
+ else if(y<0) y= 0;
}
-
- if(tex->imaflag & TEX_USEALPHA) {
- if(tex->imaflag & TEX_CALCALPHA);
- else texres->talpha= 1;
+ else {
+ y= y % ibuf->y;
+ if(y<0) y+= ibuf->y;
}
-
- if(texres->nor) {
- if(tex->imaflag & TEX_NORMALMAP) {
- // qdn: normal from color
- texres->nor[0] = 2.f*(texres->tr - 0.5f);
- texres->nor[1] = 2.f*(0.5f - texres->tg);
- texres->nor[2] = 2.f*(texres->tb - 0.5f);
- }
- else {
- /* bump: take three samples */
- val1= texres->tr+texres->tg+texres->tb;
+ }
+
+ /* warning, no return before setting back! */
+ if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
+ ibuf->rect+= (ibuf->x*ibuf->y);
+ }
- if(x<ibuf->x-1) {
- float col[4];
- ibuf_get_color(col, ibuf, x+1, y);
- val2= (col[0]+col[1]+col[2]);
- }
- else val2= val1;
+ ibuf_get_color(&texres->tr, ibuf, x, y);
+
+ if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
+ ibuf->rect-= (ibuf->x*ibuf->y);
+ }
- if(y<ibuf->y-1) {
- float col[4];
- ibuf_get_color(col, ibuf, x, y+1);
- val3= (col[0]+col[1]+col[2]);
- }
- else val3= val1;
+ if(tex->imaflag & TEX_USEALPHA) {
+ if(tex->imaflag & TEX_CALCALPHA);
+ else texres->talpha= 1;
+ }
+
+ if(texres->nor) {
+ if(tex->imaflag & TEX_NORMALMAP) {
+ // qdn: normal from color
+ texres->nor[0] = 2.f*(texres->tr - 0.5f);
+ texres->nor[1] = 2.f*(0.5f - texres->tg);
+ texres->nor[2] = 2.f*(texres->tb - 0.5f);
+ }
+ else {
+ /* bump: take three samples */
+ val1= texres->tr+texres->tg+texres->tb;
- /* do not mix up x and y here! */
- texres->nor[0]= (val1-val2);
- texres->nor[1]= (val1-val3);
+ if(x<ibuf->x-1) {
+ float col[4];
+ ibuf_get_color(col, ibuf, x+1, y);
+ val2= (col[0]+col[1]+col[2]);
}
- }
+ else val2= val1;
- BRICONTRGB;
+ if(y<ibuf->y-1) {
+ float col[4];
+ ibuf_get_color(col, ibuf, x, y+1);
+ val3= (col[0]+col[1]+col[2]);
+ }
+ else val3= val1;
- if(texres->talpha) texres->tin= texres->ta;
- else if(tex->imaflag & TEX_CALCALPHA) {
- texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb);
+ /* do not mix up x and y here! */
+ texres->nor[0]= (val1-val2);
+ texres->nor[1]= (val1-val3);
}
- else texres->ta= texres->tin= 1.0;
-
- if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
+ }
+ BRICONTRGB;
+
+ if(texres->talpha) texres->tin= texres->ta;
+ else if(tex->imaflag & TEX_CALCALPHA) {
+ texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb);
}
+ else texres->ta= texres->tin= 1.0;
+
+ if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
- if(texres->nor) return 3;
- else return 1;
+ return retval;
}
static void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2)
@@ -567,50 +574,27 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
}
}
-static void makemipmap(Tex *tex, Image *ima)
-{
- struct ImBuf *ibuf, *nbuf;
- int minsize, curmap=0;
-
- ibuf= ima->ibuf;
- minsize= MIN2(ibuf->x, ibuf->y);
-
- while(minsize>10 && curmap<BLI_ARRAY_NELEMS(ima->mipmap)) {
- if(tex->imaflag & TEX_GAUSS_MIP) {
- nbuf= IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect, 0);
- IMB_filterN(nbuf, ibuf);
- ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(nbuf);
- IMB_freeImBuf(nbuf);
- }
- else {
- ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(ibuf);
- }
- ibuf= ima->mipmap[curmap];
-
- curmap++;
- minsize= MIN2(ibuf->x, ibuf->y);
- }
-}
-
void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *result)
{
TexResult texres;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
- if(ima==NULL || ima->ok== 0 || ima->ibuf==NULL) {
+ if(ibuf==NULL) {
+ result[0]= result[1]= result[2]= result[3]= 0.0f;
return;
}
- if( (R.flag & R_SEC_FIELD) && (ima->ibuf->flags & IB_fields) )
- ima->ibuf->rect+= (ima->ibuf->x*ima->ibuf->y);
+ if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
+ ibuf->rect+= (ibuf->x*ibuf->y);
- boxsample(ima->ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1);
+ boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1);
result[0]= texres.tr;
result[1]= texres.tg;
result[2]= texres.tb;
result[3]= texres.ta;
- if( (R.flag & R_SEC_FIELD) && (ima->ibuf->flags & IB_fields) )
- ima->ibuf->rect-= (ima->ibuf->x*ima->ibuf->y);
+ if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
+ ibuf->rect-= (ibuf->x*ibuf->y);
}
void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result)
@@ -630,354 +614,349 @@ void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *res
-int imagewraposa(Tex *tex, Image *ima, float *texvec, float *dxt, float *dyt, TexResult *texres)
+int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, float *dyt, TexResult *texres)
{
TexResult texr;
- ImBuf *ibuf, *previbuf;
float fx, fy, minx, maxx, miny, maxy, dx, dy;
float maxd, pixsize, val1, val2, val3;
int curmap, retval, imaprepeat, imapextend;
- texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0;
+ texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
/* we need to set retval OK, otherwise texture code generates normals itself... */
retval= texres->nor?3:1;
- if(ima==NULL || ima->ok== 0) {
+ /* quick tests */
+ if(ibuf==NULL && ima==NULL)
return retval;
+ if(ima) {
+
+ /* hack for icon render */
+ if(ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
+ return retval;
+
+ ibuf= BKE_image_get_ibuf(ima, &tex->iuser);
}
+ if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
+ return retval;
- if(ima->ibuf==NULL) {
- BLI_lock_thread(LOCK_CUSTOM1);
- if(ima->ibuf==NULL) ima_ibuf_is_nul(tex, ima);
- BLI_unlock_thread(LOCK_CUSTOM1);
+ /* mipmap test */
+ if(tex->imaflag & TEX_MIPMAP) {
+ if(ibuf->flags & IB_fields);
+ else if(ibuf->mipmap[0]==NULL) {
+ BLI_lock_thread(LOCK_CUSTOM1);
+
+ if(ibuf->mipmap[0]==NULL)
+ IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
+
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ }
+ }
+
+ if(tex->imaflag & TEX_USEALPHA) {
+ if(tex->imaflag & TEX_CALCALPHA);
+ else texres->talpha= 1;
}
- if (ima->ok) {
+ texr.talpha= texres->talpha;
- if(tex->imaflag & TEX_MIPMAP) {
- if(ima->mipmap[0]==NULL) {
- if(ima->mipmap[0]==NULL) {
- BLI_lock_thread(LOCK_CUSTOM1);
- if(ima->mipmap[0]==NULL) makemipmap(tex, ima);
- BLI_unlock_thread(LOCK_CUSTOM1);
- }
- }
- }
+ if(tex->imaflag & TEX_IMAROT) {
+ fy= texvec[0];
+ fx= texvec[1];
+ }
+ else {
+ fx= texvec[0];
+ fy= texvec[1];
+ }
- ibuf = ima->ibuf;
-
- if(tex->imaflag & TEX_USEALPHA) {
- if(tex->imaflag & TEX_CALCALPHA);
- else texres->talpha= 1;
- }
-
- texr.talpha= texres->talpha;
-
- if(tex->imaflag & TEX_IMAROT) {
- fy= texvec[0];
- fx= texvec[1];
- }
- else {
- fx= texvec[0];
- fy= texvec[1];
- }
-
- if(ibuf->flags & IB_fields) {
- if(R.r.mode & R_FIELDS) { /* field render */
- if(R.flag & R_SEC_FIELD) { /* correction for 2nd field */
- /* fac1= 0.5/( (float)ibuf->y ); */
- /* fy-= fac1; */
- }
- else { /* first field */
- fy+= 0.5f/( (float)ibuf->y );
- }
+ if(ibuf->flags & IB_fields) {
+ if(R.r.mode & R_FIELDS) { /* field render */
+ if(R.flag & R_SEC_FIELD) { /* correction for 2nd field */
+ /* fac1= 0.5/( (float)ibuf->y ); */
+ /* fy-= fac1; */
+ }
+ else { /* first field */
+ fy+= 0.5f/( (float)ibuf->y );
}
}
-
- /* pixel coordinates */
+ }
+
+ /* pixel coordinates */
- minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] );
- maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] );
- miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] );
- maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] );
+ minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] );
+ maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] );
+ miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] );
+ maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] );
- /* tex_sharper has been removed */
- minx= tex->filtersize*(maxx-minx)/2.0f;
- miny= tex->filtersize*(maxy-miny)/2.0f;
-
- if(tex->filtersize!=1.0f) {
- dxt[0]*= tex->filtersize;
- dxt[1]*= tex->filtersize;
- dyt[0]*= tex->filtersize;
- dyt[1]*= tex->filtersize;
- }
+ /* tex_sharper has been removed */
+ minx= tex->filtersize*(maxx-minx)/2.0f;
+ miny= tex->filtersize*(maxy-miny)/2.0f;
+
+ if(tex->filtersize!=1.0f) {
+ dxt[0]*= tex->filtersize;
+ dxt[1]*= tex->filtersize;
+ dyt[0]*= tex->filtersize;
+ dyt[1]*= tex->filtersize;
+ }
- if(tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
-
- if(minx>0.25) minx= 0.25;
- else if(minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */
- if(miny>0.25) miny= 0.25;
- else if(miny<0.00001f) miny= 0.00001f;
+ if(tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
+
+ if(minx>0.25) minx= 0.25;
+ else if(minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */
+ if(miny>0.25) miny= 0.25;
+ else if(miny<0.00001f) miny= 0.00001f;
-
- /* repeat and clip */
- imaprepeat= (tex->extend==TEX_REPEAT);
- imapextend= (tex->extend==TEX_EXTEND);
+
+ /* repeat and clip */
+ imaprepeat= (tex->extend==TEX_REPEAT);
+ imapextend= (tex->extend==TEX_EXTEND);
- if(tex->extend == TEX_CHECKER) {
- int xs, ys, xs1, ys1, xs2, ys2, boundary;
-
- xs= (int)floor(fx);
- ys= (int)floor(fy);
+ if(tex->extend == TEX_CHECKER) {
+ int xs, ys, xs1, ys1, xs2, ys2, boundary;
+
+ xs= (int)floor(fx);
+ ys= (int)floor(fy);
+
+ // both checkers available, no boundary exceptions, checkerdist will eat aliasing
+ if( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
+ fx-= xs;
+ fy-= ys;
+ }
+ else {
- // both checkers available, no boundary exceptions, checkerdist will eat aliasing
- if( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
+ xs1= (int)floor(fx-minx);
+ ys1= (int)floor(fy-miny);
+ xs2= (int)floor(fx+minx);
+ ys2= (int)floor(fy+miny);
+ boundary= (xs1!=xs2) || (ys1!=ys2);
+
+ if(boundary==0) {
+ if( (tex->flag & TEX_CHECKER_ODD)==0) {
+ if((xs+ys) & 1);
+ else return retval;
+ }
+ if( (tex->flag & TEX_CHECKER_EVEN)==0) {
+ if((xs+ys) & 1) return retval;
+ }
fx-= xs;
fy-= ys;
}
else {
-
- xs1= (int)floor(fx-minx);
- ys1= (int)floor(fy-miny);
- xs2= (int)floor(fx+minx);
- ys2= (int)floor(fy+miny);
- boundary= (xs1!=xs2) || (ys1!=ys2);
-
- if(boundary==0) {
- if( (tex->flag & TEX_CHECKER_ODD)==0) {
- if((xs+ys) & 1);
- else return retval;
- }
- if( (tex->flag & TEX_CHECKER_EVEN)==0) {
- if((xs+ys) & 1) return retval;
- }
- fx-= xs;
- fy-= ys;
+ if(tex->flag & TEX_CHECKER_ODD) {
+ if((xs1+ys) & 1) fx-= xs2;
+ else fx-= xs1;
+
+ if((ys1+xs) & 1) fy-= ys2;
+ else fy-= ys1;
}
- else {
- if(tex->flag & TEX_CHECKER_ODD) {
- if((xs1+ys) & 1) fx-= xs2;
- else fx-= xs1;
-
- if((ys1+xs) & 1) fy-= ys2;
- else fy-= ys1;
- }
- if(tex->flag & TEX_CHECKER_EVEN) {
- if((xs1+ys) & 1) fx-= xs1;
- else fx-= xs2;
-
- if((ys1+xs) & 1) fy-= ys1;
- else fy-= ys2;
- }
+ if(tex->flag & TEX_CHECKER_EVEN) {
+ if((xs1+ys) & 1) fx-= xs1;
+ else fx-= xs2;
+
+ if((ys1+xs) & 1) fy-= ys1;
+ else fy-= ys2;
}
}
+ }
- /* scale around center, (0.5, 0.5) */
- if(tex->checkerdist<1.0) {
- fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5;
- fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5;
- minx/= (1.0-tex->checkerdist);
- miny/= (1.0-tex->checkerdist);
- }
+ /* scale around center, (0.5, 0.5) */
+ if(tex->checkerdist<1.0) {
+ fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5;
+ fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5;
+ minx/= (1.0-tex->checkerdist);
+ miny/= (1.0-tex->checkerdist);
}
+ }
- if(tex->extend == TEX_CLIPCUBE) {
- if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0 || texvec[2]<-1.0 || texvec[2]>1.0) {
- return retval;
- }
+ if(tex->extend == TEX_CLIPCUBE) {
+ if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0 || texvec[2]<-1.0 || texvec[2]>1.0) {
+ return retval;
}
- else if(tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
- if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0) {
- return retval;
- }
+ }
+ else if(tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
+ if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0) {
+ return retval;
+ }
+ }
+ else {
+ if(tex->extend==TEX_EXTEND) {
+ if(fx>1.0) fx = 1.0;
+ else if(fx<0.0) fx= 0.0;
}
else {
- if(tex->extend==TEX_EXTEND) {
- if(fx>1.0) fx = 1.0;
- else if(fx<0.0) fx= 0.0;
- }
- else {
- if(fx>1.0) fx -= (int)(fx);
- else if(fx<0.0) fx+= 1-(int)(fx);
- }
-
- if(tex->extend==TEX_EXTEND) {
- if(fy>1.0) fy = 1.0;
- else if(fy<0.0) fy= 0.0;
- }
- else {
- if(fy>1.0) fy -= (int)(fy);
- else if(fy<0.0) fy+= 1-(int)(fy);
- }
+ if(fx>1.0) fx -= (int)(fx);
+ else if(fx<0.0) fx+= 1-(int)(fx);
}
-
- /* warning no return! */
- if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
- ibuf->rect+= (ibuf->x*ibuf->y);
+
+ if(tex->extend==TEX_EXTEND) {
+ if(fy>1.0) fy = 1.0;
+ else if(fy<0.0) fy= 0.0;
}
+ else {
+ if(fy>1.0) fy -= (int)(fy);
+ else if(fy<0.0) fy+= 1-(int)(fy);
+ }
+ }
- /* choice: */
- if(tex->imaflag & TEX_MIPMAP) {
- float bumpscale;
-
- dx= minx;
- dy= miny;
- maxd= MAX2(dx, dy);
- if(maxd>0.5) maxd= 0.5;
+ /* warning no return! */
+ if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
+ ibuf->rect+= (ibuf->x*ibuf->y);
+ }
- pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y);
-
- bumpscale= pixsize/maxd;
- if(bumpscale>1.0f) bumpscale= 1.0f;
- else bumpscale*=bumpscale;
-
- curmap= 0;
- previbuf= ibuf;
- while(curmap<BLI_ARRAY_NELEMS(ima->mipmap) && ima->mipmap[curmap]) {
- if(maxd < pixsize) break;
- previbuf= ibuf;
- ibuf= ima->mipmap[curmap];
- pixsize= 1.0f / (float)MIN2(ibuf->x, ibuf->y); /* this used to be 1.0 */
- curmap++;
- }
+ /* choice: */
+ if(tex->imaflag & TEX_MIPMAP) {
+ ImBuf *previbuf, *curibuf;
+ float bumpscale;
+
+ dx= minx;
+ dy= miny;
+ maxd= MAX2(dx, dy);
+ if(maxd>0.5) maxd= 0.5;
- if(previbuf!=ibuf || (tex->imaflag & TEX_INTERPOL)) {
- /* sample at least 1 pixel */
- if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x;
- if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y;
- }
+ pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y);
+
+ bumpscale= pixsize/maxd;
+ if(bumpscale>1.0f) bumpscale= 1.0f;
+ else bumpscale*=bumpscale;
+
+ curmap= 0;
+ previbuf= curibuf= ibuf;
+ while(curmap<IB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
+ if(maxd < pixsize) break;
+ previbuf= curibuf;
+ curibuf= ibuf->mipmap[curmap];
+ pixsize= 1.0f / (float)MIN2(curibuf->x, curibuf->y);
+ curmap++;
+ }
+
+ if(previbuf!=curibuf || (tex->imaflag & TEX_INTERPOL)) {
+ /* sample at least 1 pixel */
+ if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
+ if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
+ }
+
+ if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
+ /* a bit extra filter */
+ //minx*= 1.35f;
+ //miny*= 1.35f;
- if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
- /* a bit extra filter */
- //minx*= 1.35f;
- //miny*= 1.35f;
+ boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
+ val1= texres->tr+texres->tg+texres->tb;
+ boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
+ val2= texr.tr + texr.tg + texr.tb;
+ boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
+ val3= texr.tr + texr.tg + texr.tb;
+
+ /* don't switch x or y! */
+ texres->nor[0]= (val1-val2);
+ texres->nor[1]= (val1-val3);
+
+ if(previbuf!=curibuf) { /* interpolate */
- boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
- val1= texres->tr+texres->tg+texres->tb;
- boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
- val2= texr.tr + texr.tg + texr.tb;
- boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
- val3= texr.tr + texr.tg + texr.tb;
-
- /* don't switch x or y! */
- texres->nor[0]= (val1-val2);
- texres->nor[1]= (val1-val3);
+ boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
- if(previbuf!=ibuf) { /* interpolate */
-
- boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
-
- /* calc rgb */
- dx= 2.0f*(pixsize-maxd)/pixsize;
- if(dx>=1.0f) {
- texres->ta= texr.ta; texres->tb= texr.tb;
- texres->tg= texr.tg; texres->tr= texr.tr;
- }
- else {
- dy= 1.0f-dx;
- texres->tb= dy*texres->tb+ dx*texr.tb;
- texres->tg= dy*texres->tg+ dx*texr.tg;
- texres->tr= dy*texres->tr+ dx*texr.tr;
- texres->ta= dy*texres->ta+ dx*texr.ta;
- }
-
- val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
- boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
- val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
- boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
- val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
-
- texres->nor[0]= (val1-val2); /* vals have been interpolated above! */
- texres->nor[1]= (val1-val3);
-
- if(dx<1.0f) {
- dy= 1.0f-dx;
- texres->tb= dy*texres->tb+ dx*texr.tb;
- texres->tg= dy*texres->tg+ dx*texr.tg;
- texres->tr= dy*texres->tr+ dx*texr.tr;
- texres->ta= dy*texres->ta+ dx*texr.ta;
- }
+ /* calc rgb */
+ dx= 2.0f*(pixsize-maxd)/pixsize;
+ if(dx>=1.0f) {
+ texres->ta= texr.ta; texres->tb= texr.tb;
+ texres->tg= texr.tg; texres->tr= texr.tr;
}
- texres->nor[0]*= bumpscale;
- texres->nor[1]*= bumpscale;
- }
- else {
- maxx= fx+minx;
- minx= fx-minx;
- maxy= fy+miny;
- miny= fy-miny;
-
- boxsample(ibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
-
- if(previbuf!=ibuf) { /* interpolate */
- boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
-
- fx= 2.0f*(pixsize-maxd)/pixsize;
-
- if(fx>=1.0) {
- texres->ta= texr.ta; texres->tb= texr.tb;
- texres->tg= texr.tg; texres->tr= texr.tr;
- } else {
- fy= 1.0f-fx;
- texres->tb= fy*texres->tb+ fx*texr.tb;
- texres->tg= fy*texres->tg+ fx*texr.tg;
- texres->tr= fy*texres->tr+ fx*texr.tr;
- texres->ta= fy*texres->ta+ fx*texr.ta;
- }
+ else {
+ dy= 1.0f-dx;
+ texres->tb= dy*texres->tb+ dx*texr.tb;
+ texres->tg= dy*texres->tg+ dx*texr.tg;
+ texres->tr= dy*texres->tr+ dx*texr.tr;
+ texres->ta= dy*texres->ta+ dx*texr.ta;
+ }
+
+ val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
+ boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
+ val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
+ boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
+ val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
+
+ texres->nor[0]= (val1-val2); /* vals have been interpolated above! */
+ texres->nor[1]= (val1-val3);
+
+ if(dx<1.0f) {
+ dy= 1.0f-dx;
+ texres->tb= dy*texres->tb+ dx*texr.tb;
+ texres->tg= dy*texres->tg+ dx*texr.tg;
+ texres->tr= dy*texres->tr+ dx*texr.tr;
+ texres->ta= dy*texres->ta+ dx*texr.ta;
}
}
+ texres->nor[0]*= bumpscale;
+ texres->nor[1]*= bumpscale;
}
else {
- if((tex->imaflag & TEX_INTERPOL)) {
- /* sample 1 pixel minimum */
- if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x;
- if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y;
- }
+ maxx= fx+minx;
+ minx= fx-minx;
+ maxy= fy+miny;
+ miny= fy-miny;
+
+ boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
- if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
+ if(previbuf!=curibuf) { /* interpolate */
+ boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
- /* a bit extra filter */
- //minx*= 1.35f;
- //miny*= 1.35f;
+ fx= 2.0f*(pixsize-maxd)/pixsize;
- boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
- val1= texres->tr+texres->tg+texres->tb;
- boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
- val2= texr.tr + texr.tg + texr.tb;
- boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
- val3= texr.tr + texr.tg + texr.tb;
- /* don't switch x or y! */
- texres->nor[0]= (val1-val2);
- texres->nor[1]= (val1-val3);
- }
- else {
- boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
+ if(fx>=1.0) {
+ texres->ta= texr.ta; texres->tb= texr.tb;
+ texres->tg= texr.tg; texres->tr= texr.tr;
+ } else {
+ fy= 1.0f-fx;
+ texres->tb= fy*texres->tb+ fx*texr.tb;
+ texres->tg= fy*texres->tg+ fx*texr.tg;
+ texres->tr= fy*texres->tr+ fx*texr.tr;
+ texres->ta= fy*texres->ta+ fx*texr.ta;
+ }
}
}
-
- BRICONTRGB;
-
- if(tex->imaflag & TEX_CALCALPHA) {
- texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
+ }
+ else {
+ if((tex->imaflag & TEX_INTERPOL)) {
+ /* sample 1 pixel minimum */
+ if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
+ if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
}
- else texres->tin= texres->ta;
- if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
-
- if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
- ibuf->rect-= (ibuf->x*ibuf->y);
+ if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
+
+ boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
+ val1= texres->tr+texres->tg+texres->tb;
+ boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
+ val2= texr.tr + texr.tg + texr.tb;
+ boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
+ val3= texr.tr + texr.tg + texr.tb;
+ /* don't switch x or y! */
+ texres->nor[0]= (val1-val2);
+ texres->nor[1]= (val1-val3);
}
-
- if(texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
- // qdn: normal from color
- texres->nor[0] = 2.f*(texres->tr - 0.5f);
- texres->nor[1] = 2.f*(0.5f - texres->tg);
- texres->nor[2] = 2.f*(texres->tb - 0.5f);
+ else {
+ boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
}
}
- else {
- texres->tin= 0.0f;
+
+ BRICONTRGB;
+
+ if(tex->imaflag & TEX_CALCALPHA) {
+ texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
+ }
+ else texres->tin= texres->ta;
+
+ if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
+
+ if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
+ ibuf->rect-= (ibuf->x*ibuf->y);
+ }
+
+ if(texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
+ // qdn: normal from color
+ texres->nor[0] = 2.f*(texres->tr - 0.5f);
+ texres->nor[1] = 2.f*(0.5f - texres->tg);
+ texres->nor[2] = 2.f*(texres->tb - 0.5f);
}
return retval;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 3ce3b93f3a4..e62d66a354d 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -40,6 +40,7 @@
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -162,7 +163,7 @@ static void stats_background(RenderStats *rs)
}
}
-static void free_render_result(RenderResult *res)
+void RE_FreeRenderResult(RenderResult *res)
{
if(res==NULL) return;
@@ -197,7 +198,7 @@ static void free_render_result(RenderResult *res)
static void push_render_result(Render *re)
{
/* officially pushed result should be NULL... error can happen with do_seq */
- free_render_result(re->pushedresult);
+ RE_FreeRenderResult(re->pushedresult);
re->pushedresult= re->result;
re->result= NULL;
@@ -236,89 +237,157 @@ static void pop_render_result(Render *re)
}
}
- free_render_result(re->pushedresult);
+ RE_FreeRenderResult(re->pushedresult);
re->pushedresult= NULL;
}
}
-
+/* NOTE: OpenEXR only supports 32 chars for layer+pass names
+ In blender we now use max 10 chars for pass, max 20 for layer */
static char *get_pass_name(int passtype, int channel)
{
if(passtype == SCE_PASS_COMBINED) {
+ if(channel==-1) return "Combined";
if(channel==0) return "Combined.R";
- else if(channel==1) return "Combined.G";
- else if(channel==2) return "Combined.B";
- else return "Combined.A";
+ if(channel==1) return "Combined.G";
+ if(channel==2) return "Combined.B";
+ return "Combined.A";
+ }
+ if(passtype == SCE_PASS_Z) {
+ if(channel==-1) return "Depth";
+ return "Depth.Z";
}
- if(passtype == SCE_PASS_Z)
- return "Z";
if(passtype == SCE_PASS_VECTOR) {
+ if(channel==-1) return "Vector";
if(channel==0) return "Vector.X";
- else if(channel==1) return "Vector.Y";
- else if(channel==2) return "Vector.Z";
- else return "Vector.W";
+ if(channel==1) return "Vector.Y";
+ if(channel==2) return "Vector.Z";
+ return "Vector.W";
}
if(passtype == SCE_PASS_NORMAL) {
+ if(channel==-1) return "Normal";
if(channel==0) return "Normal.X";
- else if(channel==1) return "Normal.Y";
- else return "Normal.Z";
+ if(channel==1) return "Normal.Y";
+ return "Normal.Z";
}
if(passtype == SCE_PASS_UV) {
- if(channel==0) return "Tex.U";
- else return "Tex.V";
+ if(channel==-1) return "UV";
+ if(channel==0) return "UV.U";
+ if(channel==1) return "UV.V";
+ return "UV.A";
}
if(passtype == SCE_PASS_RGBA) {
+ if(channel==-1) return "Color";
if(channel==0) return "Color.R";
- else if(channel==1) return "Color.G";
- else if(channel==2) return "Color.B";
- else return "Color.A";
+ if(channel==1) return "Color.G";
+ if(channel==2) return "Color.B";
+ return "Color.A";
}
if(passtype == SCE_PASS_DIFFUSE) {
+ if(channel==-1) return "Diffuse";
if(channel==0) return "Diffuse.R";
- else if(channel==1) return "Diffuse.G";
- else return "Diffuse.B";
+ if(channel==1) return "Diffuse.G";
+ return "Diffuse.B";
}
if(passtype == SCE_PASS_SPEC) {
+ if(channel==-1) return "Spec";
if(channel==0) return "Spec.R";
- else if(channel==1) return "Spec.G";
- else return "Spec.B";
+ if(channel==1) return "Spec.G";
+ return "Spec.B";
}
if(passtype == SCE_PASS_SHADOW) {
+ if(channel==-1) return "Shadow";
if(channel==0) return "Shadow.R";
- else if(channel==1) return "Shadow.G";
- else return "Shadow.B";
+ if(channel==1) return "Shadow.G";
+ return "Shadow.B";
}
if(passtype == SCE_PASS_AO) {
+ if(channel==-1) return "AO";
if(channel==0) return "AO.R";
- else if(channel==1) return "AO.G";
- else return "AO.B";
+ if(channel==1) return "AO.G";
+ return "AO.B";
}
if(passtype == SCE_PASS_REFLECT) {
+ if(channel==-1) return "Reflect";
if(channel==0) return "Reflect.R";
- else if(channel==1) return "Reflect.G";
- else return "Reflect.B";
+ if(channel==1) return "Reflect.G";
+ return "Reflect.B";
}
if(passtype == SCE_PASS_REFRACT) {
+ if(channel==-1) return "Refract";
if(channel==0) return "Refract.R";
- else if(channel==1) return "Refract.G";
- else return "Refract.B";
+ if(channel==1) return "Refract.G";
+ return "Refract.B";
}
if(passtype == SCE_PASS_RADIO) {
+ if(channel==-1) return "Radio";
if(channel==0) return "Radio.R";
- else if(channel==1) return "Radio.G";
- else return "Radio.B";
+ if(channel==1) return "Radio.G";
+ return "Radio.B";
+ }
+ if(passtype == SCE_PASS_INDEXOB) {
+ if(channel==-1) return "IndexOB";
+ return "IndexOB.X";
}
- if(passtype == SCE_PASS_INDEXOB)
- return "IndexOB";
return "Unknown";
}
+static int passtype_from_name(char *str)
+{
+
+ if(strcmp(str, "Combined")==0)
+ return SCE_PASS_COMBINED;
+
+ if(strcmp(str, "Depth")==0)
+ return SCE_PASS_Z;
+
+ if(strcmp(str, "Vector")==0)
+ return SCE_PASS_VECTOR;
+
+ if(strcmp(str, "Normal")==0)
+ return SCE_PASS_NORMAL;
+
+ if(strcmp(str, "UV")==0)
+ return SCE_PASS_UV;
+
+ if(strcmp(str, "Color")==0)
+ return SCE_PASS_RGBA;
+
+ if(strcmp(str, "Diffuse")==0)
+ return SCE_PASS_DIFFUSE;
+
+ if(strcmp(str, "Spec")==0)
+ return SCE_PASS_SPEC;
+
+ if(strcmp(str, "Shadow")==0)
+ return SCE_PASS_SHADOW;
+
+ if(strcmp(str, "AO")==0)
+ return SCE_PASS_AO;
+
+ if(strcmp(str, "Reflect")==0)
+ return SCE_PASS_REFLECT;
+
+ if(strcmp(str, "Refract")==0)
+ return SCE_PASS_REFRACT;
+
+ if(strcmp(str, "Radio")==0)
+ return SCE_PASS_RADIO;
+
+ if(strcmp(str, "IndexOB")==0)
+ return SCE_PASS_INDEXOB;
+
+ return 0;
+}
+
+
+
static void render_unique_exr_name(Render *re, char *str)
{
- char di[FILE_MAXDIR+FILE_MAXFILE], name[FILE_MAXFILE], fi[FILE_MAXFILE];
+ char di[FILE_MAX], name[FILE_MAXFILE], fi[FILE_MAXFILE];
- BLI_strncpy(di, G.sce, FILE_MAXDIR+FILE_MAXFILE);
+ BLI_strncpy(di, G.sce, FILE_MAX);
BLI_splitdirstring(di, fi);
sprintf(name, "%s_%s.exr", fi, re->scene->id.name+2);
if(G.background)
@@ -341,7 +410,7 @@ static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channel
if(rr->exrhandle) {
int a;
for(a=0; a<channels; a++)
- IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a));
+ IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
}
else {
if(passtype==SCE_PASS_VECTOR) {
@@ -435,10 +504,10 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
rl->mat_override= srl->mat_override;
if(rr->exrhandle) {
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R");
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G");
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B");
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A");
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
}
else
rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
@@ -608,20 +677,142 @@ static void save_render_result_tile(Render *re, RenderPart *pa)
}
+/* for passes read from files, these have names stored */
+static char *make_pass_name(RenderPass *rpass, int chan)
+{
+ static char name[16];
+ int len;
+
+ BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
+ len= strlen(name);
+ name[len]= '.';
+ name[len+1]= rpass->chan_id[chan];
+ name[len+2]= 0;
+
+ return name;
+}
+
+/* filename already made absolute */
+/* called from within UI, saves both rendered result as a file-read result */
+void RE_WriteRenderResult(RenderResult *rr, char *filename)
+{
+ RenderLayer *rl;
+ RenderPass *rpass;
+ void *exrhandle= IMB_exr_get_handle();
+
+ /* composite result */
+ if(rr->rectf) {
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf);
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1);
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2);
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3);
+ }
+
+ /* add layers/passes and assign channels */
+ for(rl= rr->layers.first; rl; rl= rl->next) {
+
+ /* combined */
+ if(rl->rectf) {
+ int a, xstride= 4;
+ for(a=0; a<xstride; a++)
+ IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
+ xstride, xstride*rr->rectx, rl->rectf+a);
+ }
+
+ /* passes are allocated in sync */
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ int a, xstride= rpass->channels;
+ for(a=0; a<xstride; a++) {
+ if(rpass->passtype)
+ IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
+ xstride, xstride*rr->rectx, rpass->rect+a);
+ else
+ IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
+ xstride, xstride*rr->rectx, rpass->rect+a);
+ }
+ }
+ }
+
+ IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty);
+
+ IMB_exr_write_channels(exrhandle);
+ IMB_exr_close(exrhandle);
+}
+
+/* callbacks for RE_MultilayerConvert */
+static void *ml_addlayer_cb(void *base, char *str)
+{
+ RenderResult *rr= base;
+ RenderLayer *rl;
+
+ rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
+ BLI_addtail(&rr->layers, rl);
+
+ BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
+ return rl;
+}
+static void ml_addpass_cb(void *base, void *lay, char *str, float *rect, int totchan, char *chan_id)
+{
+ RenderLayer *rl= lay;
+ RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass");
+ int a;
+
+ BLI_addtail(&rl->passes, rpass);
+ rpass->channels= totchan;
+
+ rpass->passtype= passtype_from_name(str);
+ if(rpass->passtype==0) printf("unknown pass %s\n", str);
+ rl->passflag |= rpass->passtype;
+
+ BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME);
+ /* channel id chars */
+ for(a=0; a<totchan; a++)
+ rpass->chan_id[a]= chan_id[a];
+
+ rpass->rect= rect;
+}
+
+/* from imbuf, if a handle was returned we convert this to render result */
+RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty)
+{
+ RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");
+
+ rr->rectx= rectx;
+ rr->recty= recty;
+
+ IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
+
+ return rr;
+}
+
+/* called in end of render, to add names to passes... for UI only */
+static void renderresult_add_names(RenderResult *rr)
+{
+ RenderLayer *rl;
+ RenderPass *rpass;
+
+ for(rl= rr->layers.first; rl; rl= rl->next)
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next)
+ strcpy(rpass->name, get_pass_name(rpass->passtype, -1));
+}
+
+
+/* only for temp buffer files, makes exact copy of render result */
static void read_render_result(Render *re)
{
RenderLayer *rl;
RenderPass *rpass;
void *exrhandle= IMB_exr_get_handle();
int rectx, recty;
- char str[FILE_MAXDIR+FILE_MAXFILE];
+ char str[FILE_MAX];
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
render_unique_exr_name(re, str);
if(IMB_exr_begin_read(exrhandle, str, &rectx, &recty)==0) {
- printf("cannot read render result\n");
+ IMB_exr_close(exrhandle);
+ printf("cannot read: %s\n", str);
return;
}
@@ -649,6 +840,7 @@ static void read_render_result(Render *re)
}
IMB_exr_read_channels(exrhandle);
+ renderresult_add_names(re->result);
}
IMB_exr_close(exrhandle);
@@ -787,8 +979,8 @@ void RE_FreeRender(Render *re)
free_renderdata_tables(re);
free_sample_tables(re);
- free_render_result(re->result);
- free_render_result(re->pushedresult);
+ RE_FreeRenderResult(re->result);
+ RE_FreeRenderResult(re->pushedresult);
BLI_remlink(&RenderList, re);
MEM_freeN(re);
@@ -845,7 +1037,7 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
make_sample_tables(re);
/* make empty render result, so display callbacks can initialize */
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
re->result= MEM_callocN(sizeof(RenderResult), "new render result");
re->result->rectx= re->rectx;
re->result->recty= re->recty;
@@ -862,7 +1054,7 @@ void RE_SetDispRect (struct Render *re, rcti *disprect)
re->recty= disprect->ymax-disprect->ymin;
/* initialize render result */
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
}
@@ -981,7 +1173,7 @@ static void render_tile_processor(Render *re, int firsttile)
/* hrmf... exception, this is used for preview render, re-entrant, so render result has to be re-used */
if(re->result==NULL || re->result->layers.first==NULL) {
- if(re->result) free_render_result(re->result);
+ if(re->result) RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
}
@@ -1010,7 +1202,7 @@ static void render_tile_processor(Render *re, int firsttile)
re->i.partsdone++;
re->stats_draw(&re->i);
}
- free_render_result(pa->result);
+ RE_FreeRenderResult(pa->result);
pa->result= NULL;
}
if(re->test_break())
@@ -1143,7 +1335,7 @@ static void threaded_tile_processor(Render *re)
int rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;
/* first step; the entire render result, or prepare exr buffer saving */
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
rr= re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & R_EXR_TILE_FILE);
if(rr==NULL)
@@ -1155,7 +1347,7 @@ static void threaded_tile_processor(Render *re)
initparts(re);
if(rr->exrhandle) {
- char str[FILE_MAXDIR+FILE_MAXFILE];
+ char str[FILE_MAX];
render_unique_exr_name(re, str);
@@ -1213,7 +1405,7 @@ static void threaded_tile_processor(Render *re)
re->display_draw(pa->result, NULL);
print_part_stats(re, pa);
- free_render_result(pa->result);
+ RE_FreeRenderResult(pa->result);
pa->result= NULL;
re->i.partsdone++;
hasdrawn= 1;
@@ -1361,7 +1553,7 @@ static void do_render_blur_3d(Render *re)
}
/* swap results */
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
re->result= rres;
set_mblur_offs(0.0f);
@@ -1467,9 +1659,9 @@ static void do_render_fields_3d(Render *re)
else
merge_renderresult_fields(re->result, rr1, rr2);
- free_render_result(rr2);
+ RE_FreeRenderResult(rr2);
}
- free_render_result(rr1);
+ RE_FreeRenderResult(rr1);
re->i.curfield= 0; /* stats */
@@ -1481,7 +1673,7 @@ static void do_render_fields_3d(Render *re)
static void load_backbuffer(Render *re)
{
if(re->r.alphamode == R_ADDSKY) {
- Image *bima;
+ ImBuf *ibuf;
char name[256];
strcpy(name, re->r.backbuf);
@@ -1489,32 +1681,21 @@ static void load_backbuffer(Render *re)
if(re->backbuf) {
re->backbuf->id.us--;
- bima= re->backbuf;
+ if(re->backbuf->id.us<1)
+ BKE_image_signal(re->backbuf, NULL, IMA_SIGNAL_RELOAD);
}
- else bima= NULL;
-
- re->backbuf= add_image(name);
- if(bima && bima->id.us<1) {
- free_image_buffers(bima);
- }
-
- if(re->backbuf && re->backbuf->ibuf==NULL) {
- re->backbuf->ibuf= IMB_loadiffname(re->backbuf->name, IB_rect);
- if(re->backbuf->ibuf==NULL)
- re->backbuf->ok= 0;
- else {
- re->backbuf->ok= 1;
-
- if (re->r.mode & R_FIELDS)
- image_de_interlace(re->backbuf, re->r.mode & R_ODDFIELD);
- }
- }
- if(re->backbuf==NULL || re->backbuf->ok==0) {
+ re->backbuf= BKE_add_image_file(name);
+ ibuf= BKE_image_get_ibuf(re->backbuf, NULL);
+ if(ibuf==NULL) {
// error() doesnt work with render window open
//error("No backbuf there!");
printf("Error: No backbuf %s\n", name);
}
+ else {
+ if (re->r.mode & R_FIELDS)
+ image_de_interlace(re->backbuf, re->r.mode & R_ODDFIELD);
+ }
}
}
@@ -1561,7 +1742,7 @@ static void do_render_fields_blur_3d(Render *re)
rres= new_render_result(re, &re->disprect, 0, RR_USEMEM);
merge_render_result(rres, re->result);
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
re->result= rres;
/* weak... the display callback wants an active renderlayer pointer... */
@@ -1716,7 +1897,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
/* yafray: main yafray render/export call */
static void yafrayRender(Render *re)
{
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
// need this too, for aspect/ortho/etc info
@@ -1756,7 +1937,7 @@ static void yafrayRender(Render *re)
rres= new_render_result(re, &re->disprect, 0, RR_USEMEM);
merge_render_result(rres, re->result);
- free_render_result(re->result);
+ RE_FreeRenderResult(re->result);
re->result= rres;
re->display_init(re->result);
@@ -1776,12 +1957,14 @@ static void yafrayRender(Render *re)
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
/* main loop: doing sequence + fields + blur + 3d render + compositing */
static void do_render_all_options(Render *re)
{
re->i.starttime= PIL_check_seconds_timer();
+ /* ensure no images are in memory from previous animated sequences */
+ BKE_image_all_free_anim_ibufs(re->r.cfra);
+
if(re->r.scemode & R_DOSEQ) {
/* note: do_render_seq() frees rect32 when sequencer returns float images */
if(!re->test_break())
@@ -1802,6 +1985,9 @@ static void do_render_all_options(Render *re)
#endif
}
+ /* for UI only */
+ renderresult_add_names(re->result);
+
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(&re->i);
}
@@ -1835,7 +2021,7 @@ static int is_rendering_allowed(Render *re)
}
if(re->r.scemode & R_EXR_TILE_FILE) {
- char str[FILE_MAXDIR+FILE_MAXFILE];
+ char str[FILE_MAX];
render_unique_exr_name(re, str);
@@ -1964,7 +2150,7 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
{
- char name[FILE_MAXDIR+FILE_MAXFILE];
+ char name[FILE_MAX];
RenderResult rres;
RE_GetResultImage(re, &rres);
@@ -1983,40 +2169,49 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
MEM_freeN(rres.rect32);
}
printf("Append frame %d", scene->r.cfra);
- } else {
- ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
- int ok;
-
+ }
+ else {
BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype);
-
- /* if not exists, BKE_write_ibuf makes one */
- ibuf->rect= rres.rect32;
- ibuf->rect_float= rres.rectf;
- ibuf->zbuf_float= rres.rectz;
- /* float factor for random dither, imbuf takes care of it */
- ibuf->dither= scene->r.dither_intensity;
-
- ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
-
- if(ok==0) {
- printf("Render error: cannot save %s\n", name);
- G.afbreek=1;
+ if(re->r.imtype==R_MULTILAYER) {
+ if(re->result) {
+ RE_WriteRenderResult(re->result, name);
+ printf("Saved: %s", name);
+ }
}
- else printf("Saved: %s", name);
-
- /* optional preview images for exr */
- if(ok && scene->r.imtype==R_OPENEXR && (scene->r.subimtype & R_PREVIEW_JPG)) {
- if(BLI_testextensie(name, ".exr"))
- name[strlen(name)-4]= 0;
- BKE_add_image_extension(name, R_JPEG90);
- ibuf->depth= 24;
- BKE_write_ibuf(ibuf, name, R_JPEG90, scene->r.subimtype, scene->r.quality);
- printf("\nSaved: %s", name);
+ else {
+ ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
+ int ok;
+
+ /* if not exists, BKE_write_ibuf makes one */
+ ibuf->rect= rres.rect32;
+ ibuf->rect_float= rres.rectf;
+ ibuf->zbuf_float= rres.rectz;
+
+ /* float factor for random dither, imbuf takes care of it */
+ ibuf->dither= scene->r.dither_intensity;
+
+ ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
+
+ if(ok==0) {
+ printf("Render error: cannot save %s\n", name);
+ G.afbreek=1;
+ }
+ else printf("Saved: %s", name);
+
+ /* optional preview images for exr */
+ if(ok && scene->r.imtype==R_OPENEXR && (scene->r.subimtype & R_PREVIEW_JPG)) {
+ if(BLI_testextensie(name, ".exr"))
+ name[strlen(name)-4]= 0;
+ BKE_add_image_extension(name, R_JPEG90);
+ ibuf->depth= 24;
+ BKE_write_ibuf(ibuf, name, R_JPEG90, scene->r.subimtype, scene->r.quality);
+ printf("\nSaved: %s", name);
+ }
+
+ /* imbuf knows which rects are not part of ibuf */
+ IMB_freeImBuf(ibuf);
}
-
- /* imbuf knows which rects are not part of ibuf */
- IMB_freeImBuf(ibuf);
}
BLI_timestr(re->i.lastframetime, name);
@@ -2083,6 +2278,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
/* note; repeated win/disprect calc... solve that nicer, also in compo */
+/* only temp file! */
void RE_ReadRenderResult(Scene *scene, Scene *scenode)
{
Render *re;
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index e6bb07ff20b..0ebd778754e 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -48,6 +48,7 @@
#include "DNA_meshdata_types.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_texture.h"
@@ -1330,6 +1331,7 @@ typedef struct BakeShade {
ZSpan *zspan;
Image *ima;
+ ImBuf *ibuf;
int rectx, recty, quad, type, vdone, ready;
@@ -1457,12 +1459,16 @@ static int get_next_bake_face(BakeShade *bs)
if(vlr->ob->flag & SELECT) {
if(vlr->tface && vlr->tface->tpage) {
Image *ima= vlr->tface->tpage;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
- if(ima->ibuf==NULL)
+ if(ibuf==NULL)
continue;
- if(ima->ibuf->rect==NULL && ima->ibuf->rect_float==NULL)
+ if(ibuf->rect==NULL && ibuf->rect_float==NULL)
+ continue;
+
+ if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
continue;
/* find the image for the first time? */
@@ -1470,10 +1476,10 @@ static int get_next_bake_face(BakeShade *bs)
ima->id.flag &= ~LIB_DOIT;
/* we either fill in float or char, this ensures things go fine */
- if(ima->ibuf->rect_float)
- imb_freerectImBuf(ima->ibuf);
+ if(ibuf->rect_float)
+ imb_freerectImBuf(ibuf);
/* clear image */
- IMB_rectfill(ima->ibuf, vec);
+ IMB_rectfill(ibuf, vec);
/* might be read by UI to set active image for display */
R.bakebuf= ima;
@@ -1511,15 +1517,16 @@ static void shade_tface(BakeShade *bs)
/* check valid zspan */
if(ima!=bs->ima) {
bs->ima= ima;
+ bs->ibuf= BKE_image_get_ibuf(ima, NULL);
/* note, these calls only free/fill contents of zspan struct, not zspan itself */
zbuf_free_span(bs->zspan);
- zbuf_alloc_span(bs->zspan, ima->ibuf->x, ima->ibuf->y);
+ zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y);
}
- bs->rectx= ima->ibuf->x;
- bs->recty= ima->ibuf->y;
- bs->rect= ima->ibuf->rect;
- bs->rect_float= ima->ibuf->rect_float;
+ bs->rectx= bs->ibuf->x;
+ bs->recty= bs->ibuf->y;
+ bs->rect= bs->ibuf->rect;
+ bs->rect_float= bs->ibuf->rect_float;
bs->quad= 0;
/* get pixel level vertex coordinates */
@@ -1607,10 +1614,10 @@ int RE_bake_shade_all_selected(Render *re, int type)
/* filter images */
for(ima= G.main->image.first; ima; ima= ima->id.next) {
if((ima->id.flag & LIB_DOIT)==0) {
-
- IMB_filter_extend(ima->ibuf);
- IMB_filter_extend(ima->ibuf); /* 2nd pixel extra */
- ima->ibuf->userflags |= IB_BITMAPDIRTY;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ IMB_filter_extend(ibuf);
+ IMB_filter_extend(ibuf); /* 2nd pixel extra */
+ ibuf->userflags |= IB_BITMAPDIRTY;
}
}
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 04f192b3d7d..3860ca1f4c4 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -47,6 +47,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "BKE_image.h"
#include "BKE_plugin_types.h"
#include "BKE_utildefines.h"
@@ -73,112 +74,26 @@ extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/* prototypes */
-static int calcimanr(int cfra, Tex *tex);
-/* ------------------------------------------------------------------------- */
-int calcimanr(int cfra, Tex *tex)
+/* note; this is called WITH RENDER IS NULL in src/drawview.c for animated
+ background image, option should move to kernel */
+void init_render_texture(Render *re, Tex *tex)
{
- int imanr, len, a, fra, dur;
-
- /* here (+fie_ima/2-1) makes sure that division happens correctly */
-
- if(tex->frames==0) return 1;
-
- cfra= cfra-tex->sfra+1;
-
- /* cyclic */
- if(tex->len==0) len= (tex->fie_ima*tex->frames)/2;
- else len= tex->len;
-
- if(tex->imaflag & TEX_ANIMCYCLIC) {
- cfra= ( (cfra) % len );
- if(cfra < 0) cfra+= len;
- if(cfra==0) cfra= len;
- }
-
- if(cfra<1) cfra= 1;
- else if(cfra>len) cfra= len;
+ int cfra= G.scene->r.cfra;
- /* convert current frame to current field */
- cfra= 2*(cfra);
- if(R.flag & R_SEC_FIELD) cfra++;
+ if(re) cfra= re->r.cfra;
- /* transform to images space */
- imanr= (cfra+tex->fie_ima-2)/tex->fie_ima;
- if(imanr>tex->frames) imanr= tex->frames;
- imanr+= tex->offset;
-
- if(tex->imaflag & TEX_ANIMCYCLIC) {
- imanr= ( (imanr) % len );
- while(imanr < 0) imanr+= len;
- if(imanr==0) imanr= len;
- }
-
- /* are there images that last longer? */
- for(a=0; a<4; a++) {
- if(tex->fradur[a][0]) {
-
- fra= tex->fradur[a][0];
- dur= tex->fradur[a][1]-1;
-
- while(dur>0 && imanr>fra) {
- imanr--;
- dur--;
- }
- }
- }
-
- return imanr;
-}
-
-/* note; this function is called in src/drawview.c for animated background image, option should move to kernel */
-void init_render_texture(Render *re, Tex *tex)
-{
- Image *ima;
- int imanr;
- unsigned short numlen;
- char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE];
-
/* imap test */
- if(tex->frames && tex->ima && tex->ima->name) { /* frames */
- strcpy(name, tex->ima->name);
-
- imanr= calcimanr(G.scene->r.cfra, tex);
-
- if(tex->imaflag & TEX_ANIM5) {
- if(tex->ima->lastframe != imanr) {
- if(tex->ima->ibuf) IMB_freeImBuf(tex->ima->ibuf);
- tex->ima->ibuf= 0;
- tex->ima->lastframe= imanr;
- }
- }
- else {
- /* for patch field-ima rendering */
- tex->ima->lastframe= imanr;
-
- BLI_stringdec(name, head, tail, &numlen);
- BLI_stringenc(name, head, tail, numlen, imanr);
-
- ima= add_image(name);
-
- if(ima) {
- ima->flag |= IMA_FROMANIM;
-
- if(tex->ima) tex->ima->id.us--;
- tex->ima= ima;
-
- ima->ok= 1;
- }
- }
+ if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ BKE_image_user_calc_imanr(&tex->iuser, cfra, re?re->flag & R_SEC_FIELD:0);
}
if(tex->type==TEX_PLUGIN) {
if(tex->plugin && tex->plugin->doit) {
- if(tex->plugin->cfra) {
- *(tex->plugin->cfra)= frame_to_float(G.scene->r.cfra);
- }
+ if(tex->plugin->cfra) {
+ *(tex->plugin->cfra)= frame_to_float(cfra);
+ }
}
}
else if(tex->type==TEX_ENVMAP) {
@@ -191,7 +106,7 @@ void init_render_texture(Render *re, Tex *tex)
tex->extend= TEX_EXTEND;
/* only free envmap when rendermode was set to render envmaps, for previewrender */
- if(G.rendering) {
+ if(G.rendering && re) {
if (re->r.mode & R_ENVMAP)
if(tex->env->stype==ENV_ANIM)
BKE_free_envmapdata(tex->env);
@@ -211,8 +126,6 @@ void init_render_textures(Render *re)
if(tex->id.us) init_render_texture(re, tex);
tex= tex->id.next;
}
-
- free_unused_animimages();
}
/* ------------------------------------------------------------------------- */
@@ -1189,8 +1102,8 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex,
retval= texnoise(tex, texres);
break;
case TEX_IMAGE:
- if(osatex) retval= imagewraposa(tex, tex->ima, texvec, dxt, dyt, texres);
- else retval= imagewrap(tex, tex->ima, texvec, texres);
+ if(osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres);
+ else retval= imagewrap(tex, tex->ima, NULL, texvec, texres);
tag_image_time(tex->ima); /* tag image as having being used */
break;
case TEX_PLUGIN:
@@ -2486,8 +2399,8 @@ void render_realtime_texture(ShadeInput *shi)
texr.nor= NULL;
- if(shi->osatex) imagewraposa(tex, ima, texvec, dx, dy, &texr);
- else imagewrap(tex, ima, texvec, &texr);
+ if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr);
+ else imagewrap(tex, ima, NULL, texvec, &texr);
shi->vcol[0]*= texr.tr;
shi->vcol[1]*= texr.tg;
diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c
index cdc99f13b82..d8b69e41255 100644
--- a/source/blender/src/butspace.c
+++ b/source/blender/src/butspace.c
@@ -100,29 +100,8 @@ char texstr[20][12]= {"None" , "Clouds" , "Wood", "Marble", "Magic" , "Blend",
void test_idbutton_cb(void *namev, void *arg2)
{
char *name= namev;
- test_idbutton(name+2);
- /* temporal! image rename for procedural Image has issues */
- if(arg2 && GS(name)==ID_IM) {
- /* when name changed */
- if(strcmp(name+2, (char *)arg2)) {
- ID *id= NULL;
- if(strcmp((char *)arg2, "Render Result")==0)
- id= find_id(name, name+2);
- else if(strcmp((char *)arg2, "Compositor")==0)
- id= find_id(name, name+2);
- if(id) {
- Image *ima= (Image *)id;
- if(ima->ibuf) {
- /* ibuf rect or rect_float is possibly not allocated but borrowed */
- ImBuf *ibuf= IMB_dupImBuf(ima->ibuf);
- IMB_freeImBuf(ima->ibuf);
- ima->ibuf= ibuf;
- printf("changed ima %s\n", name);
- }
- }
- }
- }
+ test_idbutton(name+2);
}
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index 2d76f4f5ca9..059afee3cf3 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -124,7 +124,7 @@ void playback_anim(void);
/* ************************ SOUND *************************** */
static void load_new_sample(char *str) /* called from fileselect */
{
- char name[FILE_MAXDIR+FILE_MAXFILE];
+ char name[FILE_MAX];
bSound *sound;
bSample *sample, *newsample;
@@ -164,7 +164,7 @@ static void load_new_sample(char *str) /* called from fileselect */
void do_soundbuts(unsigned short event)
{
- char name[FILE_MAXDIR+FILE_MAXFILE];
+ char name[FILE_MAX];
bSound *sound;
bSample *sample;
bSound* tempsound;
@@ -481,11 +481,10 @@ static void backbuf_pic(char *name)
strcpy(G.scene->r.backbuf, name);
allqueue(REDRAWBUTSSCENE, 0);
- ima= add_image(name);
- if(ima) {
- free_image_buffers(ima); /* force read again */
- ima->ok= 1;
- }
+ ima= BKE_add_image_file(name);
+ if(ima)
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
+
BIF_undo_push("Change background picture");
}
@@ -498,7 +497,7 @@ static void ftype_pic(char *name)
static void run_playanim(char *file)
{
extern char bprogname[]; /* usiblender.c */
- char str[FILE_MAXDIR+FILE_MAXFILE];
+ char str[FILE_MAX];
int pos[2], size[2];
/* use current settings for defining position of window. it actually should test image size */
@@ -511,7 +510,7 @@ static void run_playanim(char *file)
void playback_anim(void)
{
- char file[FILE_MAXDIR+FILE_MAXFILE];
+ char file[FILE_MAX];
if(BKE_imtype_is_movie(G.scene->r.imtype)) {
switch (G.scene->r.imtype) {
@@ -1115,6 +1114,8 @@ static char *imagetype_pup(void)
strcpy(formatstring, "|%s %%x%d");
sprintf(appendstring, formatstring, "OpenEXR", R_OPENEXR);
strcat(string, appendstring);
+ sprintf(appendstring, formatstring, "MultiLayer", R_MULTILAYER);
+ strcat(string, appendstring);
#endif
if (G.have_libtiff) {
@@ -1815,7 +1816,8 @@ static void render_panel_layers(void)
uiDefButS(block, MENU, B_ADD_RENDERLAYER, strp, 30,145,23,20, &(G.scene->r.actlay), 0, 0, 0, 0, "Choose Active Render Layer");
MEM_freeN(strp);
- bt= uiDefBut(block, TEX, REDRAWNODE, "", 53,145,172,20, srl->name, 0.0, 31.0, 0, 0, "");
+ /* name max 20, exr format limit... */
+ bt= uiDefBut(block, TEX, REDRAWNODE, "", 53,145,172,20, srl->name, 0.0, 20.0, 0, 0, "");
uiButSetFunc(bt, rename_scene_layer_func, srl, NULL);
uiDefButBitS(block, TOG, R_SINGLE_LAYER, B_NOP, "Single", 230,145,60,20, &G.scene->r.scemode, 0, 0, 0, 0, "Only render this layer");
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index 2dcf7b001da..8557cea5468 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -81,6 +81,7 @@
#include "BDR_drawmesh.h"
+#include "BIF_drawimage.h"
#include "BIF_gl.h"
#include "BIF_graphics.h"
#include "BIF_keyval.h"
@@ -102,15 +103,12 @@
#include "blendef.h"
#include "radio.h"
+#include "RE_pipeline.h"
+
/* -----includes for this file specific----- */
#include "butspace.h" // own module
-/* ---------function prototypes ------------- */
-void load_tex_image(char *);
-void load_plugin_tex(char *);
-
-void save_env(char *);
static MTex emptytex;
static int packdummy = 0;
@@ -178,40 +176,37 @@ void shade_buttons_change_3d(void)
/* *************************** TEXTURE ******************************** */
-Tex *cur_imatex=0;
-int prv_win= 0;
-
-void load_tex_image(char *str) /* called from fileselect */
+static void load_image_cb(char *str, void *ima_pp_v, void *iuser_v) /* called from fileselect or button */
{
- Image *ima=0;
- Tex *tex;
+ Image **ima_pp= (Image **)ima_pp_v;
+ Image *ima= NULL;
- tex= cur_imatex;
- if(tex->type==TEX_IMAGE || tex->type==TEX_ENVMAP) {
+ ima= BKE_add_image_file(str);
+ if(ima) {
+ if(*ima_pp) {
+ (*ima_pp)->id.us--;
+ }
+ *ima_pp= ima;
- ima= add_image(str);
- if(ima) {
- if(tex->ima) {
- tex->ima->id.us--;
+ BKE_image_signal(ima, iuser_v, IMA_SIGNAL_RELOAD);
+
+ /* button event gets lost when it goes via filewindow */
+ if(G.buts && G.buts->lockpoin) {
+ Tex *tex= G.buts->lockpoin;
+ if(GS(tex->id.name)==ID_TE) {
+ BIF_preview_changed(ID_TE);
+ allqueue(REDRAWBUTSSHADING, 0);
}
- tex->ima= ima;
-
- free_image_buffers(ima); /* force reading again */
- ima->ok= 1;
}
-
- BIF_undo_push("Load image");
- allqueue(REDRAWBUTSSHADING, 0);
-
- BIF_preview_changed(ID_TE);
}
+
+ BIF_undo_push("Load image");
}
-void load_plugin_tex(char *str) /* called from fileselect */
+static void load_plugin_tex(char *str, void *tex_v, void *unused) /* called from fileselect */
{
- Tex *tex;
+ Tex *tex= tex_v;
- tex= cur_imatex;
if(tex->type!=TEX_PLUGIN) return;
if(tex->plugin) free_plugin_tex(tex->plugin);
@@ -223,10 +218,10 @@ void load_plugin_tex(char *str) /* called from fileselect */
BIF_preview_changed(ID_TE);
}
-void save_env(char *name)
+static void save_env(char *name)
{
Tex *tex;
- char str[FILE_MAXDIR+FILE_MAXFILE];
+ char str[FILE_MAX];
strcpy(str, name);
BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
@@ -255,11 +250,8 @@ static int vergcband(const void *a1, const void *a2)
void do_texbuts(unsigned short event)
{
Tex *tex;
- ImBuf *ibuf;
ScrArea *sa;
- ID *id;
- int nr;
- char *name, str[FILE_MAXDIR+FILE_MAXFILE];
+ char str[FILE_MAX];
tex= G.buts->lockpoin;
@@ -279,7 +271,7 @@ void do_texbuts(unsigned short event)
allqueue(REDRAWBUTSSHADING, 0);
break;
case B_TEXTYPE:
- if(tex==0) return;
+ if(tex==NULL) return;
tex->stype= 0;
allqueue(REDRAWBUTSSHADING, 0);
BIF_preview_changed(ID_TE);
@@ -290,175 +282,41 @@ void do_texbuts(unsigned short event)
}
break;
case B_DEFTEXVAR:
- if(tex==0) return;
+ if(tex==NULL) return;
default_tex(tex);
BIF_undo_push("Default texture vars");
allqueue(REDRAWBUTSSHADING, 0);
BIF_preview_changed(ID_TE);
break;
- case B_LOADTEXIMA:
- if(tex==0) return;
- /* globals: temporal store them: we make another area a fileselect */
- cur_imatex= tex;
- prv_win= curarea->win;
- sa= closest_bigger_area();
- areawinset(sa->win);
- if(tex->ima) name= tex->ima->name;
-#ifdef _WIN32
- else {
- if (strcmp (U.textudir, "/") == 0)
- name= G.sce;
- else
- name= U.textudir;
- }
-#else
- else name = U.textudir;
-#endif
-
- if(G.qual==LR_CTRLKEY)
- activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_tex_image);
- else
- activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_tex_image);
-
- break;
- case B_NAMEIMA:
- if(tex==0) return;
- if(tex->ima) {
- cur_imatex= tex;
- prv_win= curarea->win;
-
- /* name in tex->ima has been changed by button! */
- strcpy(str, tex->ima->name);
- if(tex->ima->ibuf) strcpy(tex->ima->name, tex->ima->ibuf->name);
-
- load_tex_image(str);
- }
- break;
- case B_TEXREDR_PRV:
- allqueue(REDRAWBUTSSHADING, 0);
+ case B_IMAGECHANGED:
BIF_preview_changed(ID_TE);
- shade_buttons_change_3d();
- break;
- case B_TEXIMABROWSE:
+ allqueue(REDRAWBUTSSHADING, 0);
+
if(tex) {
- id= (ID*) tex->ima;
-
- if(G.buts->menunr== -2) {
- activate_databrowse(id, ID_IM, 0, B_TEXIMABROWSE, &G.buts->menunr, do_texbuts);
- } else if (G.buts->menunr>0) {
- Image *newima= (Image*) BLI_findlink(&G.main->image, G.buts->menunr-1);
-
- if (newima && newima!=(Image*) id) {
- tex->ima= newima;
- id_us_plus((ID*) newima);
- if(id) id->us--;
-
- BIF_undo_push("Browse image");
- allqueue(REDRAWBUTSSHADING, 0);
- BIF_preview_changed(ID_TE);
- }
+ if(G.scene->nodetree) {
+ NodeTagIDChanged(G.scene->nodetree, &tex->id);
+ allqueue(RECALC_COMPOSITE, 0);
}
- }
- break;
- case B_IMAPTEST:
- if(tex) {
- if( (tex->imaflag & (TEX_FIELDS+TEX_MIPMAP))== TEX_FIELDS+TEX_MIPMAP ) {
+ if(tex->ima && (tex->imaflag & TEX_MIPMAP) && (tex->ima->flag & IMA_FIELDS)) {
error("Cannot combine fields and mipmap");
tex->imaflag -= TEX_MIPMAP;
- allqueue(REDRAWBUTSSHADING, 0);
- }
-
- if(tex->ima && tex->ima->ibuf) {
- ibuf= tex->ima->ibuf;
- nr= 0;
- if( !(tex->imaflag & TEX_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1;
- if( (tex->imaflag & TEX_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1;
- if(nr) {
- IMB_freeImBuf(ibuf);
- tex->ima->ibuf= 0;
- tex->ima->ok= 1;
- BIF_preview_changed(ID_TE);
- }
}
- }
- break;
- case B_RELOADIMA:
- if(tex && tex->ima) {
- // check if there is a newer packedfile
-
- if (tex->ima->packedfile) {
- PackedFile *pf;
- pf = newPackedFile(tex->ima->name);
- if (pf) {
- freePackedFile(tex->ima->packedfile);
- tex->ima->packedfile = pf;
- } else {
- error("Image not available. Keeping packed image.");
- }
- }
- if (tex->ima->preview) {
- free_image_preview(tex->ima);
- }
-
- IMB_freeImBuf(tex->ima->ibuf);
- tex->ima->ibuf= NULL;
- tex->ima->ok= 1;
-
if(tex->env)
BKE_free_envmapdata(tex->env);
-
- free_realtime_image(tex->ima);
-
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWIMAGE, 0);
- BIF_preview_changed(ID_TE);
- }
- allqueue(REDRAWBUTSSHADING, 0); // redraw buttons
-
- break;
- case B_UNLINKIMA:
- if(tex && tex->ima) {
- tex->ima->id.us--;
- tex->ima= NULL;
- allqueue(REDRAWBUTSSHADING, 0); // redraw buttons
- BIF_preview_changed(ID_TE);
}
+
break;
- case B_TEXSETFRAMES:
- if(tex->ima->anim) tex->frames = IMB_anim_get_duration(tex->ima->anim);
+
+ case B_TEXREDR_PRV:
allqueue(REDRAWBUTSSHADING, 0);
+ BIF_preview_changed(ID_TE);
+ shade_buttons_change_3d();
break;
- case B_PACKIMA:
- if(tex && tex->ima) {
- if (tex->ima->packedfile) {
- if (G.fileflags & G_AUTOPACK) {
- if (okee("Disable AutoPack ?")) {
- G.fileflags &= ~G_AUTOPACK;
- }
- }
-
- if ((G.fileflags & G_AUTOPACK) == 0) {
- unpackImage(tex->ima, PF_ASK);
- }
- } else {
- if (tex->ima->ibuf && (tex->ima->ibuf->userflags & IB_BITMAPDIRTY)) {
- error("Can't pack painted image. Save image from Image window first.");
- } else {
- tex->ima->packedfile = newPackedFile(tex->ima->name);
- }
- }
- allqueue(REDRAWBUTSSHADING, 0);
- allqueue(REDRAWHEADERS, 0);
- }
- break;
- case B_LOADPLUGIN:
- if(tex==0) return;
- /* globals: store temporal: we make another area a fileselect */
- cur_imatex= tex;
- prv_win= curarea->win;
+ case B_LOADPLUGIN:
+ if(tex==NULL) return;
sa= closest_bigger_area();
areawinset(sa->win);
@@ -466,12 +324,12 @@ void do_texbuts(unsigned short event)
else {
strcpy(str, U.plugtexdir);
}
- activate_fileselect(FILE_SPECIAL, "SELECT PLUGIN", str, load_plugin_tex);
+ activate_fileselect_args(FILE_SPECIAL, "SELECT PLUGIN", str, load_plugin_tex, tex, NULL);
break;
case B_NAMEPLUGIN:
- if(tex==0 || tex->plugin==0) return;
+ if(tex==NULL || tex->plugin==NULL) return;
strcpy(str, tex->plugin->name);
free_plugin_tex(tex->plugin);
tex->stype= 0;
@@ -481,8 +339,8 @@ void do_texbuts(unsigned short event)
break;
case B_COLORBAND:
- if(tex==0) return;
- if(tex->coba==0) tex->coba= add_colorband(0);
+ if(tex==NULL) return;
+ if(tex->coba==NULL) tex->coba= add_colorband(0);
allqueue(REDRAWBUTSSHADING, 0);
BIF_preview_changed(ID_TE); // also ramps, so we do this
break;
@@ -854,11 +712,559 @@ static void texture_panel_voronoi(Tex *tex)
}
+static char *layer_menu(RenderResult *rr, short *curlay)
+{
+ RenderLayer *rl;
+ int len= 64 + 32*BLI_countlist(&rr->layers);
+ short a, nr= 0;
+ char *str= MEM_callocN(len, "menu layers");
+
+ strcpy(str, "Layer %t");
+ a= strlen(str);
+
+ /* compo result */
+ if(rr->rectf) {
+ a+= sprintf(str+a, "|Composite %%x0");
+ nr= 1;
+ }
+ for(rl= rr->layers.first; rl; rl= rl->next, nr++) {
+ a+= sprintf(str+a, "|%s %%x%d", rl->name, nr);
+ }
+
+ if(*curlay >= nr)
+ *curlay= 0;
+
+ return str;
+}
+
+/* rl==NULL means composite result */
+static char *pass_menu(RenderLayer *rl, short *curpass)
+{
+ RenderPass *rpass;
+ int len= 64 + 32*(rl?BLI_countlist(&rl->passes):1);
+ short a, nr= 0;
+ char *str= MEM_callocN(len, "menu layers");
+
+ strcpy(str, "Pass %t");
+ a= strlen(str);
+
+ /* rendered results don't have a Combined pass */
+ if(rl==NULL || rl->rectf) {
+ a+= sprintf(str+a, "|Combined %%x0");
+ nr= 1;
+ }
+
+ if(rl)
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next, nr++)
+ a+= sprintf(str+a, "|%s %%x%d", rpass->name, nr);
+
+ if(*curpass >= nr)
+ *curpass= 0;
+
+ return str;
+}
+
+static void set_frames_cb(void *ima_v, void *iuser_v)
+{
+ Image *ima= ima_v;
+ ImageUser *iuser= iuser_v;
+
+ if(ima->anim) {
+ iuser->frames = IMB_anim_get_duration(ima->anim);
+ BKE_image_user_calc_imanr(iuser, G.scene->r.cfra, 0);
+ }
+}
+
+static void image_src_change_cb(void *ima_v, void *iuser_v)
+{
+ BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_SRC_CHANGE);
+}
+
+/* buttons have 2 arg callbacks, filewindow has 3 args... so thats why the wrapper below */
+static void image_browse_cb1(char *unused, void *ima_pp_v, void *iuser_v)
+{
+ Image **ima_pp= (Image **)ima_pp_v;
+ ImageUser *iuser= iuser_v;
+
+ if(ima_pp) {
+ Image *ima= *ima_pp;
+
+ if(iuser->menunr== -2) {
+ activate_databrowse_args(&ima->id, ID_IM, 0, &iuser->menunr, image_browse_cb1, ima_pp, iuser);
+ }
+ else if (iuser->menunr>0) {
+ Image *newima= (Image*) BLI_findlink(&G.main->image, iuser->menunr-1);
+
+ if (newima && newima!=ima) {
+ *ima_pp= newima;
+ id_us_plus(&newima->id);
+ if(ima) ima->id.us--;
+
+ BKE_image_signal(newima, iuser, IMA_SIGNAL_USER_NEW_IMAGE);
+
+ BIF_undo_push("Browse image");
+ }
+ }
+ }
+}
+
+static void image_browse_cb(void *ima_pp_v, void *iuser_v)
+{
+ image_browse_cb1(NULL, ima_pp_v, iuser_v);
+}
+
+static void image_reload_cb(void *ima_v, void *iuser_v)
+{
+ if(ima_v) {
+ BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_RELOAD);
+ }
+}
+
+static void image_field_test(void *ima_v, void *iuser_v)
+{
+ Image *ima= ima_v;
+
+ if(ima) {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
+ if(ibuf) {
+ short nr= 0;
+ if( !(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1;
+ if( (ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1;
+ if(nr) {
+ BKE_image_signal(ima, iuser_v, IMA_SIGNAL_FREE);
+ }
+ }
+ }
+}
+
+static void image_unlink_cb(void *ima_pp_v, void *unused)
+{
+ Image **ima_pp= (Image **)ima_pp_v;
+
+ if(ima_pp && *ima_pp) {
+ Image *ima= *ima_pp;
+ ima->id.us--;
+ *ima_pp= NULL;
+ }
+}
+
+static void image_load_fs_cb(void *ima_pp_v, void *iuser_v)
+{
+ Image **ima_pp= (Image **)ima_pp_v;
+ ScrArea *sa;
+ char *name;
+
+ if(ima_pp==NULL) return;
+
+ sa= closest_bigger_area();
+ areawinset(sa->win);
+ if(*ima_pp) name= (*ima_pp)->name;
+#ifdef _WIN32
+ else {
+ if (strcmp (U.textudir, "/") == 0)
+ name= G.sce;
+ else
+ name= U.textudir;
+ }
+#else
+ else name = U.textudir;
+#endif
+ activate_fileselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
+}
+
+/* 5 layer button callbacks... */
+static void image_multi_cb(void *rr_v, void *iuser_v)
+{
+ BKE_image_multilayer_index(rr_v, iuser_v);
+}
+static void image_multi_inclay_cb(void *rr_v, void *iuser_v)
+{
+ RenderResult *rr= rr_v;
+ ImageUser *iuser= iuser_v;
+ int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0); /* fake compo result layer */
+ if(iuser->layer<tot-1)
+ iuser->layer++;
+ BKE_image_multilayer_index(rr, iuser);
+}
+static void image_multi_declay_cb(void *rr_v, void *iuser_v)
+{
+ ImageUser *iuser= iuser_v;
+ if(iuser->layer>0)
+ iuser->layer--;
+ BKE_image_multilayer_index(rr_v, iuser);
+}
+static void image_multi_incpass_cb(void *rr_v, void *iuser_v)
+{
+ RenderResult *rr= rr_v;
+ ImageUser *iuser= iuser_v;
+ RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer);
+ if(rl) {
+ int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0); /* builtin render result has no combined pass in list */
+ if(iuser->pass<tot-1) {
+ iuser->pass++;
+ BKE_image_multilayer_index(rr, iuser);
+ }
+ }
+}
+static void image_multi_decpass_cb(void *rr_v, void *iuser_v)
+{
+ ImageUser *iuser= iuser_v;
+ if(iuser->pass>0) {
+ iuser->pass--;
+ BKE_image_multilayer_index(rr_v, iuser);
+ }
+}
+
+static void image_pack_cb(void *ima_v, void *iuser_v)
+{
+ if(ima_v) {
+ Image *ima= ima_v;
+ if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) {
+ if (ima->packedfile) {
+ if (G.fileflags & G_AUTOPACK) {
+ if (okee("Disable AutoPack ?")) {
+ G.fileflags &= ~G_AUTOPACK;
+ }
+ }
+
+ if ((G.fileflags & G_AUTOPACK) == 0) {
+ unpackImage(ima, PF_ASK);
+ BIF_undo_push("Unpack image");
+ }
+ }
+ else {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
+ if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
+ error("Can't pack painted image. Save image or use Repack as PNG.");
+ } else {
+ ima->packedfile = newPackedFile(ima->name);
+ BIF_undo_push("Pack image");
+ }
+ }
+ }
+ }
+}
+
+static void image_load_cb(void *ima_pp_v, void *iuser_v)
+{
+ if(ima_pp_v) {
+ Image *ima= *((Image **)ima_pp_v);
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
+ char str[FILE_MAX];
+
+ /* name in ima has been changed by button! */
+ BLI_strncpy(str, ima->name, FILE_MAX);
+ if(ibuf) BLI_strncpy(ima->name, ibuf->name, FILE_MAX);
+
+ load_image_cb(str, ima_pp_v, iuser_v);
+ }
+}
+
+static void image_freecache_cb(void *ima_v, void *unused)
+{
+ BKE_image_free_anim_ibufs(ima_v, G.scene->r.cfra);
+ allqueue(REDRAWIMAGE, 0);
+}
+
+static void image_generated_change_cb(void *ima_v, void *iuser_v)
+{
+ BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_FREE);
+}
+
+static void image_user_change(void *iuser_v, void *unused)
+{
+ BKE_image_user_calc_imanr(iuser_v, G.scene->r.cfra, 0);
+}
+
+void uiblock_layer_pass_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int event, int x, int y, int w)
+{
+ uiBut *but;
+ RenderLayer *rl= NULL;
+ int wmenu1, wmenu2;
+ char *strp;
+
+ /* layer menu is 1/3 larger than pass */
+ wmenu1= (3*w)/5;
+ wmenu2= (2*w)/5;
+
+ /* menu buts */
+ strp= layer_menu(rr, &iuser->layer);
+ but= uiDefButS(block, MENU, event, strp, x, y, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer");
+ uiButSetFunc(but, image_multi_cb, rr, iuser);
+ MEM_freeN(strp);
+
+ rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */
+ strp= pass_menu(rl, &iuser->pass);
+ but= uiDefButS(block, MENU, event, strp, x+wmenu1, y, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass");
+ uiButSetFunc(but, image_multi_cb, rr, iuser);
+ MEM_freeN(strp);
+}
+
+static void uiblock_layer_pass_arrow_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int imagechanged)
+{
+ uiBut *but;
+
+ if(rr==NULL || iuser==NULL)
+ return;
+ if(rr->layers.first==NULL) {
+ uiDefBut(block, LABEL, 0, "No Layers in Render Result,", 10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
+ return;
+ }
+
+ uiBlockBeginAlign(block);
+
+ /* decrease, increase arrows */
+ but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 10,107,17,20, NULL, 0, 0, 0, 0, "Previous Layer");
+ uiButSetFunc(but, image_multi_declay_cb, rr, iuser);
+ but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 27,107,18,20, NULL, 0, 0, 0, 0, "Next Layer");
+ uiButSetFunc(but, image_multi_inclay_cb, rr, iuser);
+
+ uiblock_layer_pass_buttons(block, rr, iuser, imagechanged, 45, 107, 230);
+
+ /* decrease, increase arrows */
+ but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 275,107,17,20, NULL, 0, 0, 0, 0, "Previous Pass");
+ uiButSetFunc(but, image_multi_decpass_cb, rr, iuser);
+ but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 292,107,18,20, NULL, 0, 0, 0, 0, "Next Pass");
+ uiButSetFunc(but, image_multi_incpass_cb, rr, iuser);
+
+ uiBlockEndAlign(block);
+
+}
+
+/* The general Image panel with the loadsa callbacks! */
+void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
+ short redraw, short imagechanged)
+{
+ Image *ima= *ima_pp;
+ uiBut *but;
+ char str[128], *strp;
+
+ /* different stuff when we show viewer */
+ if(ima && ima->source==IMA_SRC_VIEWER) {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
+
+ image_info(ima, ibuf, str);
+ uiDefBut(block, LABEL, 0, ima->id.name+2, 10, 180, 300, 20, NULL, 1, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, str, 10, 160, 300, 20, NULL, 1, 0, 0, 0, "");
+
+ if(ima->type==IMA_TYPE_COMPOSITE) {
+ iuser= ntree_get_active_iuser(G.scene->nodetree);
+
+ uiBlockBeginAlign(block);
+ uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, "");
+ uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, "");
+ but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, "");
+ uiButSetFunc(but, image_freecache_cb, ima, NULL);
+
+ if(iuser->frames)
+ sprintf(str, "(%d) Frames:", iuser->framenr);
+ else strcpy(str, "Frames:");
+ uiBlockBeginAlign(block);
+ uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
+ uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
+ }
+ else if(ima->type==IMA_TYPE_R_RESULT) {
+ /* browse layer/passes */
+ uiblock_layer_pass_arrow_buttons(block, RE_GetResult(RE_GetRender(G.scene->id.name)), iuser, imagechanged);
+ }
+ return;
+ }
+
+ /* the main ima source types */
+ if(ima) {
+ uiSetButLock(ima->id.lib!=NULL, "Can't edit library data");
+ uiBlockBeginAlign(block);
+ uiBlockSetFunc(block, image_src_change_cb, ima, iuser);
+ uiDefButS(block, ROW, imagechanged, "Still", 10, 180, 60, 20, &ima->source, 0.0, IMA_SRC_FILE, 0, 0, "Single Image file");
+ uiDefButS(block, ROW, imagechanged, "Movie", 70, 180, 60, 20, &ima->source, 0.0, IMA_SRC_MOVIE, 0, 0, "Movie file");
+ uiDefButS(block, ROW, imagechanged, "Sequence", 130, 180, 90, 20, &ima->source, 0.0, IMA_SRC_SEQUENCE, 0, 0, "Multiple Image files, as a sequence");
+ uiDefButS(block, ROW, imagechanged, "Generated", 220, 180, 90, 20, &ima->source, 0.0, IMA_SRC_GENERATED, 0, 0, "Generated Image");
+ uiBlockSetFunc(block, NULL, NULL, NULL);
+ }
+ else
+ uiDefBut(block, LABEL, 0, " ", 10, 180, 300, 20, 0, 0, 0, 0, 0, ""); /* for align in panel */
+
+ /* Browse */
+ IMAnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), NULL, &iuser->menunr);
+
+ uiBlockBeginAlign(block);
+ but= uiDefButS(block, MENU, imagechanged, strp, 10,155,23,20, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie");
+ uiButSetFunc(but, image_browse_cb, ima_pp, iuser);
+
+ MEM_freeN(strp);
+
+ /* name + options, or only load */
+ if(ima) {
+ int drawpack= (ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE && ima->ok);
+
+ but= uiDefBut(block, TEX, B_IDNAME, "IM:", 33, 155, 177, 20, ima->id.name+2, 0.0, 19.0, 0, 0, "Current Image Datablock name.");
+ uiButSetFunc(but, test_idbutton_cb, ima->id.name, NULL);
+ but= uiDefBut(block, BUT, imagechanged, "Reload", 210, 155, 60, 20, NULL, 0, 0, 0, 0, "Reloads Image or Movie");
+ uiButSetFunc(but, image_reload_cb, ima, iuser);
+
+ but= uiDefIconBut(block, BUT, imagechanged, ICON_X, 270,155,20,20, 0, 0, 0, 0, 0, "Unlink Image block");
+ uiButSetFunc(but, image_unlink_cb, ima_pp, NULL);
+ sprintf(str, "%d", ima->id.us);
+ uiDefBut(block, BUT, B_NOP, str, 290,155,20,20, 0, 0, 0, 0, 0, "Only displays number of users of Image block");
+
+ but= uiDefIconBut(block, BUT, imagechanged, ICON_FILESEL, 10, 135, 23, 20, 0, 0, 0, 0, 0, "Open Fileselect to load new Image");
+ uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
+ but= uiDefBut(block, TEX, imagechanged, "", 33,135,257+(drawpack?0:20),20, ima->name, 0.0, 239.0, 0, 0, "Image/Movie file name, change to load new");
+ uiButSetFunc(but, image_load_cb, ima_pp, iuser);
+
+ if(drawpack) {
+ if (ima->packedfile) packdummy = 1;
+ else packdummy = 0;
+ but= uiDefIconButBitI(block, TOG, 1, redraw, ICON_PACKAGE, 290,135,20,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image");
+ uiButSetFunc(but, image_pack_cb, ima, iuser);
+ }
+
+ }
+ else {
+ but= uiDefBut(block, BUT, imagechanged, "Load", 33, 155, 100,20, NULL, 0, 0, 0, 0, "Load new Image of Movie");
+ uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
+ }
+ uiBlockEndAlign(block);
+
+ if(ima) {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
+
+ /* check for re-render, only buttons */
+ if(imagechanged==B_IMAGECHANGED) {
+ if(iuser->flag & IMA_ANIM_REFRESHED) {
+ iuser->flag &= ~IMA_ANIM_REFRESHED;
+ BIF_preview_changed(ID_TE);
+ }
+ }
+
+ /* multilayer? */
+ if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
+ uiblock_layer_pass_arrow_buttons(block, ima->rr, iuser, imagechanged);
+ }
+ else {
+ image_info(ima, ibuf, str);
+ uiDefBut(block, LABEL, 0, str, 10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
+ }
+
+ /* left side default per-image options, right half the additional options */
+
+ /* fields */
+ uiBlockBeginAlign(block);
+ but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 70, 100, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
+ uiButSetFunc(but, image_field_test, ima, iuser);
+ uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 10, 50, 100, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
+ uiBlockEndAlign(block);
+
+ uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 10, 100, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
+
+ if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ sprintf(str, "(%d) Frames:", iuser->framenr);
+
+ uiBlockBeginAlign(block);
+ uiBlockSetFunc(block, image_user_change, iuser, NULL);
+ uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 70, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes");
+
+ if(ima->anim) {
+ uiDefButI(block, NUM, imagechanged, str, 120, 50,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
+ but= uiDefBut(block, BUT, redraw, "<", 290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
+ uiButSetFunc(but, set_frames_cb, ima, iuser);
+ }
+ else
+ uiDefButI(block, NUM, imagechanged, str, 120, 50,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
+
+ uiDefButI(block, NUM, imagechanged, "Offs:", 120,30,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
+ uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,30,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)");
+
+ uiDefButI(block, NUM, imagechanged, "StartFr:", 120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
+ uiDefButS(block, TOG, imagechanged, "Cyclic", 220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
+
+ uiBlockSetFunc(block, NULL, iuser, NULL);
+ }
+ else if(ima->source==IMA_SRC_GENERATED) {
+
+ uiBlockBeginAlign(block);
+ uiBlockSetFunc(block, image_generated_change_cb, ima, iuser);
+ uiDefButS(block, NUM, imagechanged, "SizeX:", 120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
+ uiDefButS(block, NUM, imagechanged, "SizeY:", 220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
+ uiDefButS(block, TOG, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
+ uiBlockSetFunc(block, NULL, NULL, NULL);
+ }
+ }
+
+}
+
+static void texture_panel_image(Image **ima, ImageUser *iuser)
+{
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "texture_panel_image", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Image", "Texture", 960, 0, 318, 204)==0) return;
+
+ uiblock_image_panel(block, ima, iuser, B_REDR, B_IMAGECHANGED);
+}
+
+static void texture_panel_image_map(Tex *tex)
+{
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "texture_panel_image_map", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Map Image", "Texture", 640, 0, 318, 204)==0) return;
+ uiSetButLock(tex->id.lib!=0, "Can't edit library data");
+
+ /* types */
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, TEX_MIPMAP, B_IMAGECHANGED, "MipMap", 10, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Generates and uses mipmaps");
+ uiDefButBitS(block, TOG, TEX_GAUSS_MIP, 0, "Gauss", 85, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Enable Gauss filter to sample down mipmaps");
+ uiDefButBitS(block, TOG, TEX_INTERPOL, 0, "Interpol", 160, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Interpolates pixels using Area filter");
+ uiDefButBitS(block, TOG, TEX_IMAROT, B_TEXPRV, "Rot90", 235, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Actually flips X and Y for rendering, rotates and mirrors");
+
+ uiDefButBitS(block, TOG, TEX_USEALPHA, B_TEXPRV, "UseAlpha", 10, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to use Image's alpha channel");
+ uiDefButBitS(block, TOG, TEX_CALCALPHA, B_TEXPRV, "CalcAlpha", 110, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to calculate an alpha channel based on Image RGB values");
+ uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha", 210, 160, 100, 20, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values");
+ uiBlockEndAlign(block);
+
+ uiDefButF(block, NUM, B_TEXPRV, "Filter :", 10,120,150,20, &tex->filtersize, 0.1, 25.0, 0, 3, "Sets the filter size used by mipmap and interpol");
+
+ uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map", 160,120,150,20, &tex->imaflag,
+ 0, 0, 0, 0, "Use image RGB values for normal mapping");
+
+ /* crop extend clip */
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_TEXREDR_PRV, "Extend", 10,90,63,19, &tex->extend, 4.0, 1.0, 0, 0, "Extends the colour of the edge pixels");
+ uiDefButS(block, ROW, B_TEXREDR_PRV, "Clip", 73,90,48,19, &tex->extend, 4.0, 2.0, 0, 0, "Sets alpha 0.0 outside Image edges");
+ uiDefButS(block, ROW, B_TEXREDR_PRV, "ClipCube", 121,90,63,19, &tex->extend, 4.0, 4.0, 0, 0, "Sets alpha to 0.0 outside cubeshaped area around Image");
+ uiDefButS(block, ROW, B_TEXREDR_PRV, "Repeat", 184,90,63,19, &tex->extend, 4.0, 3.0, 0, 0, "Causes Image to repeat horizontally and vertically");
+ uiDefButS(block, ROW, B_TEXREDR_PRV, "Checker", 247,90,63,19, &tex->extend, 4.0, 5.0, 0, 0, "Causes Image to repeat in checker pattern");
+
+ if(tex->extend==TEX_REPEAT) {
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_TEXPRV, "Xrepeat:", 10,60,150,19, &tex->xrepeat, 1.0, 512.0, 0, 0, "Sets a repetition multiplier in the X direction");
+ uiDefButS(block, NUM, B_TEXPRV, "Yrepeat:", 160,60,150,19, &tex->yrepeat, 1.0, 512.0, 0, 0, "Sets a repetition multiplier in the Y direction");
+ }
+ else if(tex->extend==TEX_CHECKER) {
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, TEX_CHECKER_ODD, B_TEXPRV, "Odd", 10,60,100,19, &tex->flag, 0.0, 0.0, 0, 0, "Sets odd checker tiles");
+ uiDefButBitS(block, TOG, TEX_CHECKER_EVEN, B_TEXPRV, "Even", 110,60,100,19, &tex->flag, 0.0, 0.0, 0, 0, "Sets even checker tiles");
+ uiDefButF(block, NUM, B_TEXPRV, "Mortar:", 210,60,100,19, &tex->checkerdist, 0.0, 0.99, 0, 0, "Set checkers distance (like mortar)");
+ }
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_TEXPRV, "MinX ", 10,30,150,19, &tex->cropxmin, -10.0, 10.0, 10, 0, "Sets minimum X value to crop Image");
+ uiDefButF(block, NUM, B_TEXPRV, "MinY ", 10,10,150,19, &tex->cropymin, -10.0, 10.0, 10, 0, "Sets minimum Y value to crop Image");
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_TEXPRV, "MaxX ", 160,30,150,19, &tex->cropxmax, -10.0, 10.0, 10, 0, "Sets maximum X value to crop Image");
+ uiDefButF(block, NUM, B_TEXPRV, "MaxY ", 160,10,150,19, &tex->cropymax, -10.0, 10.0, 10, 0, "Sets maximum Y value to crop Image");
+ uiBlockEndAlign(block);
+
+}
+
/***************************************/
static void texture_panel_envmap(Tex *tex)
{
uiBlock *block;
+ uiBut *but;
EnvMap *env;
ID *id;
short a, xco, yco, dx, dy;
@@ -867,7 +1273,7 @@ static void texture_panel_envmap(Tex *tex)
block= uiNewBlock(&curarea->uiblocks, "texture_panel_envmap", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Envmap", "Texture", 640, 0, 318, 204)==0) return;
uiSetButLock(tex->id.lib!=0, "Can't edit library data");
-
+
if(tex->env==NULL) {
tex->env= BKE_add_envmap();
tex->env->object= OBACT;
@@ -884,28 +1290,35 @@ static void texture_panel_envmap(Tex *tex)
if(env->stype==ENV_LOAD) {
/* file input */
id= (ID *)tex->ima;
- IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr));
+ IMAnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr));
if(strp[0]) {
uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_TEXIMABROWSE, strp, 10,145,23,20, &(G.buts->menunr), 0, 0, 0, 0, "Selects an existing environment map or creates new");
+
+ but= uiDefButS(block, MENU, B_TEXPRV, strp, 10,145,23,20, &tex->iuser.menunr, 0, 0, 0, 0, "Selects an existing environment map");
+ uiButSetFunc(but, image_browse_cb, &tex->ima, &tex->iuser);
if(tex->ima) {
- uiDefBut(block, TEX, B_NAMEIMA, "", 35,145,255,20, tex->ima->name, 0.0, 79.0, 0, 0, "Displays environment map name: click to change");
+ but= uiDefBut(block, TEX, B_NAMEIMA, "", 35,145,255,20, tex->ima->name, 0.0, 79.0, 0, 0, "Displays environment map name: click to change");
+ uiButSetFunc(but, image_load_cb, &tex->ima, &tex->iuser);
+
sprintf(str, "%d", tex->ima->id.us);
uiDefBut(block, BUT, 0, str, 290,145,20,20, 0, 0, 0, 0, 0, "Displays number of users of environment map: click to make single user");
uiBlockEndAlign(block);
- uiDefBut(block, BUT, B_RELOADIMA, "Reload", 230,125,80,20, 0, 0, 0, 0, 0, "Reloads saved environment map");
-
+ but= uiDefBut(block, BUT, B_IMAGECHANGED, "Reload", 230,125,80,20, 0, 0, 0, 0, 0, "Reloads saved environment map");
+ uiButSetFunc(but, image_reload_cb, tex->ima, NULL);
+
if (tex->ima->packedfile) packdummy = 1;
else packdummy = 0;
- uiDefIconButBitI(block, TOG, 1, B_PACKIMA, ICON_PACKAGE, 205,125,24,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this environment map");
+ but= uiDefIconButBitI(block, TOG, 1, B_REDR, ICON_PACKAGE, 205,125,24,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this environment map");
+ uiButSetFunc(but, image_pack_cb, tex->ima, &tex->iuser);
}
else uiBlockEndAlign(block);
}
MEM_freeN(strp);
-
- uiDefBut(block, BUT, B_LOADTEXIMA, "Load Image", 10,125,150,20, 0, 0, 0, 0, 0, "Loads saved environment map - file select");
+
+ but= uiDefBut(block, BUT, B_IMAGECHANGED, "Load Image", 10,125,150,20, 0, 0, 0, 0, 0, "Loads saved environment map - file select");
+ uiButSetFunc(but, image_load_fs_cb, &tex->ima, &tex->iuser);
}
else {
uiBlockBeginAlign(block);
@@ -919,15 +1332,15 @@ static void texture_panel_envmap(Tex *tex)
uiDefButF(block, NUM, B_NOP, "Zoom: ", 210,120,100,20, &env->viewscale, 0.5f, 5.0f, 100, 2, "Zoom factor for planar environment map");
uiBlockEndAlign(block);
}
-
+
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_ENV_OB, "Ob:", 10,90,150,20, &(env->object), "Displays object to use as viewpoint for environment map: click to change");
if(env->stype!=ENV_LOAD)
uiDefButS(block, NUM, B_ENV_FREE, "CubeRes", 160,90,150,20, &env->cuberes, 50, 4096.0, 0, 0, "Sets the pixel resolution of the rendered environment map");
-
+
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_TEXPRV, "Filter :", 10,65,150,20, &tex->filtersize, 0.1, 25.0, 0, 3, "Adjusts sharpness or blurriness of the reflection"),
- uiDefButS(block, NUM, B_ENV_FREE, "Depth:", 160,65,150,20, &env->depth, 0, 5.0, 0, 0, "Sets the number of times a map will be rendered recursively mirror effects"),
- uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 10,40,150,20, &env->clipsta, 0.01, 50.0, 100, 0, "Sets start value for clipping: objects nearer than this are not visible to map");
+ uiDefButS(block, NUM, B_ENV_FREE, "Depth:", 160,65,150,20, &env->depth, 0, 5.0, 0, 0, "Sets the number of times a map will be rendered recursively mirror effects"),
+ uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 10,40,150,20, &env->clipsta, 0.01, 50.0, 100, 0, "Sets start value for clipping: objects nearer than this are not visible to map");
uiDefButF(block, NUM, B_NOP, "ClipEnd", 160,40,150,20, &env->clipend, 0.1, 5000.0, 1000, 0, "Sets end value for clipping beyond which objects are not visible to map");
uiBlockEndAlign(block);
@@ -942,146 +1355,15 @@ static void texture_panel_envmap(Tex *tex)
uiDefButBitI(block, TOG, 1<<a, 0, "", (xco+a*(dx/2)), (yco+dy/2), (dx/2), (1+dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
for(a=0; a<5; a++)
uiDefButBitI(block, TOG, 1<<(a+10), 0, "",(xco+a*(dx/2)), yco, (dx/2), (dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
-
+
uiBlockBeginAlign(block);
xco+= 5;
for(a=5; a<10; a++)
uiDefButBitI(block, TOG, 1<<a, 0, "", (xco+a*(dx/2)), (yco+dy/2), (dx/2), (1+dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
for(a=5; a<10; a++)
uiDefButBitI(block, TOG, 1<<(a+10), 0, "",(xco+a*(dx/2)), yco, (dx/2), (dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
-
- }
-}
-
-
-static void texture_panel_image1(Tex *tex)
-{
- uiBlock *block;
- char str[32];
-
- block= uiNewBlock(&curarea->uiblocks, "texture_panel1", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Anim and Movie", "Texture", 960, 0, 318, 204)==0) return;
- uiSetButLock(tex->id.lib!=0, "Can't edit library data");
-
- /* print amount of frames anim */
- if(tex->ima && tex->ima->anim) {
- uiDefBut(block, BUT, B_TEXSETFRAMES, "<", 802, 110, 20, 18, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
- sprintf(str, "%d frs ", IMB_anim_get_duration(tex->ima->anim));
- uiDefBut(block, LABEL, 0, str, 834, 110, 90, 18, 0, 0, 0, 0, 0, "Number of frames in movie file");
- sprintf(str, "%d cur ", tex->ima->lastframe);
- uiDefBut(block, LABEL, 0, str, 834, 90, 90, 18, 0, 0, 0, 0, 0, "");
- }
- else uiDefBut(block, LABEL, 0, "<", 802, 110, 20, 18, 0, 0, 0, 0, 0, "");
-
- uiDefButI(block, NUM, B_TEXPRV, "Frames :", 642,110,150,19, &tex->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of frames of a movie to use and activates animation options");
- uiDefButI(block, NUM, B_TEXPRV, "Offset :", 642,90,150,19, &tex->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the first movie frame to use in the animation");
- uiDefButS(block, NUM, B_TEXPRV, "Fie/Ima:", 642,60,98,19, &tex->fie_ima, 1.0, 200.0, 0, 0, "Sets the number of fields per rendered frame");
- uiDefButI(block, NUM, B_TEXPRV, "StartFr:", 642,30,150,19, &tex->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the starting frame of the movie to use in animation");
- uiDefButI(block, NUM, B_TEXPRV, "Len:", 642,10,150,19, &tex->len, 0.0, MAXFRAMEF, 0, 0, "Sets the number of movie frames to use in animation: 0=all");
-
- uiBlockBeginAlign(block);
- uiDefButI(block, NUM, B_TEXPRV, "Fra:", 802,70,73,19, &(tex->fradur[0][0]), 0.0, MAXFRAMEF, 0, 0, "Montage mode: frame start");
- uiDefButI(block, NUM, B_TEXPRV, "Fra:", 802,50,73,19, &(tex->fradur[1][0]), 0.0, MAXFRAMEF, 0, 0, "Montage mode: frame start");
- uiDefButI(block, NUM, B_TEXPRV, "Fra:", 802,30,73,19, &(tex->fradur[2][0]), 0.0, MAXFRAMEF, 0, 0, "Montage mode: frame start");
- uiDefButI(block, NUM, B_TEXPRV, "Fra:", 802,10,73,19, &(tex->fradur[3][0]), 0.0, MAXFRAMEF, 0, 0, "Montage mode: frame start");
- uiBlockBeginAlign(block);
- uiDefButI(block, NUM, B_TEXPRV, "", 879,70,37,19, &(tex->fradur[0][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames");
- uiDefButI(block, NUM, B_TEXPRV, "", 879,50,37,19, &(tex->fradur[1][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames");
- uiDefButI(block, NUM, B_TEXPRV, "", 879,30,37,19, &(tex->fradur[2][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames");
- uiDefButI(block, NUM, B_TEXPRV, "", 879,10,37,19, &(tex->fradur[3][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames");
- uiBlockEndAlign(block);
- uiDefButBitS(block, TOG, TEX_ANIMCYCLIC, B_TEXPRV, "Cyclic", 743,60,48,19, &tex->imaflag, 0, 0, 0, 0, "Toggles looping of animated frames");
-}
-
-
-static void texture_panel_image(Tex *tex)
-{
- uiBlock *block;
- ID *id;
- char *strp, str[32];
-
- block= uiNewBlock(&curarea->uiblocks, "texture_panel_image", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Image", "Texture", 640, 0, 318, 204)==0) return;
- uiSetButLock(tex->id.lib!=0, "Can't edit library data");
-
- /* types */
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, TEX_MIPMAP, B_IMAPTEST, "MipMap", 10, 180, 60, 18, &tex->imaflag, 0, 0, 0, 0, "Generates and uses mipmaps");
- uiDefButBitS(block, TOG, TEX_GAUSS_MIP, 0, "Gauss", 70, 180, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Enable Gauss filter to sample down mipmaps");
- uiDefButBitS(block, TOG, TEX_INTERPOL, 0, "Interpol", 120, 180, 60, 18, &tex->imaflag, 0, 0, 0, 0, "Interpolates pixels using Area filter");
- uiDefButBitS(block, TOG, TEX_IMAROT, B_TEXPRV, "Rot90", 180, 180, 40, 18, &tex->imaflag, 0, 0, 0, 0, "Actually flips X and Y for rendering, rotates and mirrors");
- uiDefButBitS(block, TOG, TEX_ANTIALI, 0, "Anti", 220, 180, 40, 18, &tex->imaflag, 0, 0, 0, 0, "Toggles Image anti-aliasing");
- uiDefButBitS(block, TOG, TEX_ANIM5, B_RELOADIMA, "Movie", 260, 180, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Click to enable movie frames as Images");
-
- uiDefButBitS(block, TOG, TEX_USEALPHA, B_TEXPRV, "UseAlpha", 10, 160, 70, 18, &tex->imaflag, 0, 0, 0, 0, "Click to use Image's alpha channel");
- uiDefButBitS(block, TOG, TEX_CALCALPHA, B_TEXPRV, "CalcAlpha", 80, 160, 70, 18, &tex->imaflag, 0, 0, 0, 0, "Click to calculate an alpha channel based on Image RGB values");
- uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha", 150, 160, 60, 18, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values");
- uiDefButBitS(block, TOG, TEX_FIELDS, B_IMAPTEST, "Fields", 210, 160, 60, 18, &tex->imaflag, 0, 0, 0, 0, "Click to enable use of fields in Image");
- uiDefButBitS(block, TOG, TEX_STD_FIELD, 0, "Odd", 270, 160, 40, 18, &tex->imaflag, 0, 0, 0, 0, "Standard Field Toggle");
- uiBlockEndAlign(block);
-
- /* file input */
- id= (ID *)tex->ima;
- IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr));
- if(strp[0]) {
- uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_TEXIMABROWSE, strp, 10,135,23,20, &(G.buts->menunr), 0, 0, 0, 0, "Selects an existing texture or creates new");
- if(tex->ima) {
- uiDefBut(block, TEX, B_NAMEIMA, "", 35,135,235,20, tex->ima->name, 0.0, 79.0, 0, 0, "Displays name of the Image file: click to change");
- uiDefIconBut(block, BUT, B_UNLINKIMA, ICON_X, 270,135,20,20, 0, 0, 0, 0, 0, "Unlink Image block from Texture");
-
- sprintf(str, "%d", tex->ima->id.us);
- uiDefBut(block, BUT, 0, str, 290,135,20,20, 0, 0, 0, 0, 0, "Displays number of users of texture");
- uiBlockEndAlign(block);
-
- uiDefBut(block, BUT, B_RELOADIMA, "Reload", 230,115,80,19, 0, 0, 0, 0, 0, "Reloads Image");
-
- if (tex->ima->packedfile) packdummy = 1;
- else packdummy = 0;
-
- uiDefIconButBitI(block, TOG, 1, B_PACKIMA, ICON_PACKAGE, 205,115,24,19, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image");
- }
- else uiBlockEndAlign(block);
}
- MEM_freeN(strp);
-
- uiDefBut(block, BUT, B_LOADTEXIMA, "Load Image", 10,115,150,19, 0, 0, 0, 0, 0, "Click to load an Image");
-
- /* crop extend clip */
-
- uiDefButF(block, NUM, B_TEXPRV, "Filter :", 10,92,150,19, &tex->filtersize, 0.1, 25.0, 0, 3, "Sets the filter size used by mipmap and interpol");
-
- uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map", 160,92,150,19, &tex->imaflag,
- 0, 0, 0, 0, "Use image RGB values for normal mapping");
-
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXREDR_PRV, "Extend", 10,70,63,19, &tex->extend, 4.0, 1.0, 0, 0, "Extends the colour of the edge pixels");
- uiDefButS(block, ROW, B_TEXREDR_PRV, "Clip", 73,70,48,19, &tex->extend, 4.0, 2.0, 0, 0, "Sets alpha 0.0 outside Image edges");
- uiDefButS(block, ROW, B_TEXREDR_PRV, "ClipCube", 121,70,63,19, &tex->extend, 4.0, 4.0, 0, 0, "Sets alpha to 0.0 outside cubeshaped area around Image");
- uiDefButS(block, ROW, B_TEXREDR_PRV, "Repeat", 184,70,63,19, &tex->extend, 4.0, 3.0, 0, 0, "Causes Image to repeat horizontally and vertically");
- uiDefButS(block, ROW, B_TEXREDR_PRV, "Checker", 247,70,63,19, &tex->extend, 4.0, 5.0, 0, 0, "Causes Image to repeat in checker pattern");
-
- if(tex->extend==TEX_REPEAT) {
- uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_TEXPRV, "Xrepeat:", 10,50,150,19, &tex->xrepeat, 1.0, 512.0, 0, 0, "Sets a repetition multiplier in the X direction");
- uiDefButS(block, NUM, B_TEXPRV, "Yrepeat:", 160,50,150,19, &tex->yrepeat, 1.0, 512.0, 0, 0, "Sets a repetition multiplier in the Y direction");
- }
- else if(tex->extend==TEX_CHECKER) {
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, TEX_CHECKER_ODD, B_TEXPRV, "Odd", 10,50,100,19, &tex->flag, 0.0, 0.0, 0, 0, "Sets odd checker tiles");
- uiDefButBitS(block, TOG, TEX_CHECKER_EVEN, B_TEXPRV, "Even", 110,50,100,19, &tex->flag, 0.0, 0.0, 0, 0, "Sets even checker tiles");
- uiDefButF(block, NUM, B_TEXPRV, "Mortar:", 210,50,100,19, &tex->checkerdist, 0.0, 0.99, 0, 0, "Set checkers distance (like mortar)");
- }
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_TEXPRV, "MinX ", 10,28,150,19, &tex->cropxmin, -10.0, 10.0, 10, 0, "Sets minimum X value to crop Image");
- uiDefButF(block, NUM, B_TEXPRV, "MinY ", 10,8,150,19, &tex->cropymin, -10.0, 10.0, 10, 0, "Sets minimum Y value to crop Image");
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_TEXPRV, "MaxX ", 160,28,150,19, &tex->cropxmax, -10.0, 10.0, 10, 0, "Sets maximum X value to crop Image");
- uiDefButF(block, NUM, B_TEXPRV, "MaxY ", 160,8,150,19, &tex->cropymax, -10.0, 10.0, 10, 0, "Sets maximum Y value to crop Image");
- uiBlockEndAlign(block);
-
}
static void colorband_pos_cb(void *coba_v, void *unused_v)
@@ -1594,7 +1876,7 @@ void do_worldbuts(unsigned short event)
wrld= G.buts->lockpoin;
if(wrld && wrld->mtex[(int)wrld->texact] ) {
mtex= wrld->mtex[(int)wrld->texact];
- if(mtex->tex==0) {
+ if(mtex->tex==NULL) {
error("No texture available");
}
else {
@@ -1606,7 +1888,7 @@ void do_worldbuts(unsigned short event)
case B_WMTEXPASTE:
wrld= G.buts->lockpoin;
if(wrld && mtexcopied && mtexcopybuf.tex) {
- if(wrld->mtex[(int)wrld->texact]==0 )
+ if(wrld->mtex[(int)wrld->texact]==NULL )
wrld->mtex[(int)wrld->texact]= MEM_mallocN(sizeof(MTex), "mtex");
else if(wrld->mtex[(int)wrld->texact]->tex)
wrld->mtex[(int)wrld->texact]->tex->id.us--;
@@ -1641,7 +1923,7 @@ static void world_panel_mapto(World *wrld)
uiSetButLock(wrld->id.lib!=0, "Can't edit library data");
mtex= wrld->mtex[ wrld->texact ];
- if(mtex==0) {
+ if(mtex==NULL) {
mtex= &emptytex;
default_mtex(mtex);
mtex->texco= TEXCO_VIEW;
@@ -1707,7 +1989,7 @@ static void world_panel_texture(World *wrld)
uiBlockEndAlign(block);
mtex= wrld->mtex[ wrld->texact ];
- if(mtex==0) {
+ if(mtex==NULL) {
mtex= &emptytex;
default_mtex(mtex);
mtex->texco= TEXCO_VIEW;
@@ -1984,7 +2266,7 @@ void do_lampbuts(unsigned short event)
la= G.buts->lockpoin;
if(la && la->mtex[(int)la->texact] ) {
mtex= la->mtex[(int)la->texact];
- if(mtex->tex==0) {
+ if(mtex->tex==NULL) {
error("No texture available");
}
else {
@@ -1996,7 +2278,7 @@ void do_lampbuts(unsigned short event)
case B_LMTEXPASTE:
la= G.buts->lockpoin;
if(la && mtexcopied && mtexcopybuf.tex) {
- if(la->mtex[(int)la->texact]==0 )
+ if(la->mtex[(int)la->texact]==NULL )
la->mtex[(int)la->texact]= MEM_mallocN(sizeof(MTex), "mtex");
else if(la->mtex[(int)la->texact]->tex)
la->mtex[(int)la->texact]->tex->id.us--;
@@ -2026,7 +2308,7 @@ static void lamp_panel_mapto(Object *ob, Lamp *la)
uiSetButLock(la->id.lib!=0, "Can't edit library data");
mtex= la->mtex[ la->texact ];
- if(mtex==0) {
+ if(mtex==NULL) {
mtex= &emptytex;
default_mtex(mtex);
mtex->texco= TEXCO_VIEW;
@@ -2085,7 +2367,7 @@ static void lamp_panel_texture(Object *ob, Lamp *la)
uiBlockEndAlign(block);
mtex= la->mtex[ la->texact ];
- if(mtex==0) {
+ if(mtex==NULL) {
mtex= &emptytex;
default_mtex(mtex);
mtex->texco= TEXCO_VIEW;
@@ -2233,7 +2515,7 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
if(la->area_shape==LA_AREA_CUBE)
uiDefButS(block, NUM,0,"Samples:", 100,160,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp x samp)");
- if ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX) {
+ if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)) {
uiDefButS(block, NUM,0,"SamplesX:", 100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of X samples taken extra");
uiDefButS(block, NUM,0,"SamplesY:", 100,160,200,19, &la->ray_sampy, 1.0, 16.0, 100, 0, "Sets the amount of Y samples taken extra");
if(la->area_shape==LA_AREA_BOX)
@@ -2361,16 +2643,16 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
//uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1|Cube %x2|Box %x3",
uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1",
10, 150, 100, 19, &la->area_shape, 0,0,0,0, "Sets area light shape");
- if ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX){
+ if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)){
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeX ", 10,130,100,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size X, doesn't affect energy amount");
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeY ", 10,110,100,19, &la->area_sizey, 0.01, 100.0, 10, 0, "Area light size Y, doesn't affect energy amount");
}
if(la->area_shape==LA_AREA_BOX)
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeZ ", 10,90,100,19, &la->area_sizez, 0.01, 100.0, 10, 0, "Area light size Z, doesn't affect energy amount");
- if ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_CUBE)
+ if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_CUBE))
uiDefButF(block, NUM,B_LAMPREDRAW,"Size ", 10,130,100,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size, doesn't affect energy amount");
}
- else if ELEM(la->type, LA_LOCAL, LA_SPOT) {
+ else if( ELEM(la->type, LA_LOCAL, LA_SPOT)) {
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButBitS(block, TOG, LA_QUAD, B_LAMPPRV,"Quad", 10,150,100,19,&la->mode, 0, 0, 0, 0, "Uses inverse quadratic proportion for light attenuation");
uiDefButBitS(block, TOG, LA_SPHERE, REDRAWVIEW3D,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value");
@@ -2396,7 +2678,7 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
uiDefButF(block, COL, B_LAMPPRV, "", 120,52,180,24, &la->r, 0, 0, 0, B_COLLAMP, "");
uiBlockBeginAlign(block);
- if ELEM(la->type, LA_LOCAL, LA_SPOT) {
+ if (ELEM(la->type, LA_LOCAL, LA_SPOT)) {
uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad1 ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp");
uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad2 ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuatation for a quad lamp");
}
@@ -2561,7 +2843,7 @@ void do_matbuts(unsigned short event)
case B_MTEXCOPY:
if(ma && ma->mtex[(int)ma->texact] ) {
mtex= ma->mtex[(int)ma->texact];
- if(mtex->tex==0) {
+ if(mtex->tex==NULL) {
error("No texture available");
}
else {
@@ -2572,7 +2854,7 @@ void do_matbuts(unsigned short event)
break;
case B_MTEXPASTE:
if(ma && mtexcopied && mtexcopybuf.tex) {
- if(ma->mtex[(int)ma->texact]==0 )
+ if(ma->mtex[(int)ma->texact]==NULL )
ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex");
else if(ma->mtex[(int)ma->texact]->tex)
ma->mtex[(int)ma->texact]->tex->id.us--;
@@ -2657,7 +2939,7 @@ static void material_panel_map_to(Material *ma)
if(uiNewPanel(curarea, block, "Map To", "Material", 1600, 0, 318, 204)==0) return;
mtex= ma->mtex[ ma->texact ];
- if(mtex==0) {
+ if(mtex==NULL) {
mtex= &emptytex;
default_mtex(mtex);
}
@@ -2734,7 +3016,7 @@ static void material_panel_map_input(Object *ob, Material *ma)
if(uiNewPanel(curarea, block, "Map Input", "Material", 1280, 0, 318, 204)==0) return;
mtex= ma->mtex[ ma->texact ];
- if(mtex==0) {
+ if(mtex==NULL) {
mtex= &emptytex;
default_mtex(mtex);
}
@@ -2835,14 +3117,14 @@ static void material_panel_texture(Material *ma)
uiBlockSetCol(block, TH_AUTO);
mtex= ma->mtex[ ma->texact ];
- if(mtex==0) {
+ if(mtex==NULL) {
mtex= &emptytex;
default_mtex(mtex);
}
/* TEXTUREBLOK SELECT */
uiBlockSetCol(block, TH_BUT_SETTING2);
- if(G.main->tex.first==0)
+ if(G.main->tex.first==NULL)
id= NULL;
else
id= (ID*) mtex->tex;
@@ -3388,7 +3670,7 @@ void material_panels()
MTex *mtex;
Object *ob= OBACT;
- if(ob==0) return;
+ if(ob==NULL) return;
// type numbers are ordered
if((ob->type<OB_LAMP) && ob->type) {
@@ -3537,8 +3819,8 @@ void texture_panels()
switch(tex->type) {
case TEX_IMAGE:
- texture_panel_image(tex);
- texture_panel_image1(tex);
+ texture_panel_image(&tex->ima, &tex->iuser);
+ texture_panel_image_map(tex);
break;
case TEX_ENVMAP:
texture_panel_envmap(tex);
@@ -3589,7 +3871,7 @@ void radio_panels()
int flag;
rad= G.scene->radio;
- if(rad==0) {
+ if(rad==NULL) {
add_radio();
rad= G.scene->radio;
}
diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c
index 7e77432158e..48a99168923 100644
--- a/source/blender/src/drawimage.c
+++ b/source/blender/src/drawimage.c
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -25,9 +22,9 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Blender Foundation, 2002-2006
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
#include <math.h>
@@ -56,6 +53,7 @@
#include "DNA_image_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
@@ -99,8 +97,10 @@
#include "BIF_transform.h"
#include "BSE_drawipo.h"
+#include "BSE_drawview.h"
#include "BSE_filesel.h"
#include "BSE_headerbuttons.h"
+#include "BSE_node.h"
#include "BSE_trans_types.h"
#include "BSE_view.h"
@@ -118,26 +118,24 @@
static unsigned char *alloc_alpha_clone_image(int *width, int *height)
{
Brush *brush = G.scene->toolsettings->imapaint.brush;
- Image *image;
+ ImBuf *ibuf;
unsigned int size, alpha;
unsigned char *rect, *cp;
if(!brush || !brush->clone.image)
return NULL;
- image= brush->clone.image;
- if(!image->ibuf)
- load_image(image, IB_rect, G.sce, G.scene->r.cfra);
+ ibuf= BKE_image_get_ibuf(brush->clone.image, NULL);
- if(!image->ibuf || !image->ibuf->rect)
+ if(!ibuf || !ibuf->rect)
return NULL;
- rect= MEM_dupallocN(image->ibuf->rect);
+ rect= MEM_dupallocN(ibuf->rect);
if(!rect)
return NULL;
- *width= image->ibuf->x;
- *height= image->ibuf->y;
+ *width= ibuf->x;
+ *height= ibuf->y;
size= (*width)*(*height);
alpha= (unsigned char)255*brush->clone.alpha;
@@ -190,11 +188,13 @@ void calc_image_view(SpaceImage *sima, char mode)
if(image_preview_active(curarea, &xim, &yim));
else if(sima->image) {
- if(sima->image->ibuf) {
- xim= sima->image->ibuf->x;
- yim= sima->image->ibuf->y;
+ ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+
+ if(ibuf) {
+ xim= ibuf->x;
+ yim= ibuf->y;
}
- else if( BLI_streq(sima->image->id.name+2, "Render Result") ) {
+ else if( sima->image->type==IMA_TYPE_R_RESULT ) {
/* not very important, just nice */
xim= (G.scene->r.xsch*G.scene->r.size)/100;
yim= (G.scene->r.ysch*G.scene->r.size)/100;
@@ -246,24 +246,8 @@ void what_image(SpaceImage *sima)
if(sima->mode==SI_TEXTURE) {
- if(sima->image && BLI_streq(sima->image->id.name+2, "Render Result")) {
- if(sima->image->ibuf==NULL) {
- RenderResult rres;
-
- /* make ibuf if needed, and initialize it */
- RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
- if(rres.rectf || rres.rect32) {
- ImBuf *ibuf= sima->image->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, 0, 0);
-
- ibuf->x= rres.rectx;
- ibuf->y= rres.recty;
- ibuf->rect= rres.rect32;
- ibuf->rect_float= rres.rectf;
-
- sima->image->ok= 1;
- }
- }
- }
+ /* viewer overrides faceselect */
+ if(sima->image && sima->image->source==IMA_SRC_VIEWER);
else if((G.f & G_FACESELECT)) {
sima->image= NULL;
@@ -301,11 +285,11 @@ void image_changed(SpaceImage *sima, int dotile)
if(G.f & G_FACESELECT) {
- /* exception images, name rules are actually weak... */
+ /* skip assigning these procedural images... */
if(sima->image) {
- if(BLI_streq(sima->image->id.name+2, "Render Result"))
+ if(sima->image->type==IMA_TYPE_R_RESULT)
return;
- if(BLI_streq(sima->image->id.name+2, "Composite"))
+ if(sima->image->type==IMA_TYPE_COMPOSITE)
return;
}
@@ -740,26 +724,25 @@ static void draw_image_view_tool(void)
/* ************ panel stuff ************* */
-// button define is local, only events defined here possible
-#define B_TRANS_IMAGE 1
-
/* is used for both read and write... */
-static void image_editvertex_buts(uiBlock *block)
+void image_editvertex_buts(uiBlock *block)
{
static float ocent[2];
float cent[2]= {0.0, 0.0};
- int imx, imy;
+ int imx= 256, imy= 256;
int i, nactive= 0, step, digits;
Mesh *me;
if( is_uv_tface_editing_allowed_silent()==0 ) return;
me= get_mesh(OBACT);
- if (G.sima->image && G.sima->image->ibuf) {
- imx= G.sima->image->ibuf->x;
- imy= G.sima->image->ibuf->y;
- } else
- imx= imy= 256;
+ if (G.sima->image) {
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ if(ibuf) {
+ imx= ibuf->x;
+ imy= ibuf->y;
+ }
+ }
for (i=0; i<me->totface; i++) {
MFace *mf= &((MFace*) me->mface)[i];
@@ -863,174 +846,77 @@ static void image_editvertex_buts(uiBlock *block)
}
}
-
-void do_imagebuts(unsigned short event)
+void image_info(Image *ima, ImBuf *ibuf, char *str)
{
- ToolSettings *settings= G.scene->toolsettings;
-
- switch(event) {
- case B_TRANS_IMAGE:
- image_editvertex_buts(NULL);
- break;
-
- case B_SIMAGEDRAW:
- if(G.f & G_FACESELECT) {
- make_repbind(G.sima->image);
- image_changed(G.sima, 1);
- }
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWIMAGE, 0);
- break;
-
- case B_SIMAGEDRAW1:
- image_changed(G.sima, 2); /* 2: only tileflag */
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWIMAGE, 0);
- break;
-
- case B_TWINANIM:
- {
- Image *ima;
- int nr;
-
- ima = G.sima->image;
- if (ima) {
- if(ima->flag & IMA_TWINANIM) {
- nr= ima->xrep*ima->yrep;
- if(ima->twsta>=nr) ima->twsta= 1;
- if(ima->twend>=nr) ima->twend= nr-1;
- if(ima->twsta>ima->twend) ima->twsta= 1;
- allqueue(REDRAWIMAGE, 0);
- }
- }
- }
- break;
-
- case B_SIMACLONEBROWSE:
- if (settings->imapaint.brush)
- if (brush_clone_image_set_nr(settings->imapaint.brush, G.sima->menunr))
- allqueue(REDRAWIMAGE, 0);
- break;
-
- case B_SIMACLONEDELETE:
- if (settings->imapaint.brush)
- if (brush_clone_image_delete(settings->imapaint.brush))
- allqueue(REDRAWIMAGE, 0);
- break;
+ int ofs= 0;
+
+ str[0]= 0;
+
+ if(ima==NULL) return;
+ if(ibuf==NULL) {
+ sprintf(str, "Can not get an image");
+ return;
+ }
+
+ if(ima->source==IMA_SRC_MOVIE) {
+ ofs= sprintf(str, "Movie ");
+ if(ima->anim)
+ ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim));
+ }
+ else
+ ofs= sprintf(str, "Image ");
- case B_SIMABRUSHCHANGE:
- allqueue(REDRAWIMAGE, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- break;
-
- case B_SIMACURVES:
- curvemapping_do_image(G.sima->cumap, G.sima->image);
- allqueue(REDRAWIMAGE, 0);
- break;
-
- case B_SIMARANGE:
- curvemapping_set_black_white(G.sima->cumap, NULL, NULL);
- curvemapping_do_image(G.sima->cumap, G.sima->image);
- allqueue(REDRAWIMAGE, 0);
- break;
+ ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y);
- case B_SIMABRUSHBROWSE:
- if(G.sima->menunr==-2) {
- activate_databrowse((ID*)settings->imapaint.brush, ID_BR, 0, B_SIMABRUSHBROWSE, &G.sima->menunr, do_global_buttons);
- break;
- }
- else if(G.sima->menunr < 0) break;
-
- if(brush_set_nr(&settings->imapaint.brush, G.sima->menunr)) {
- BIF_undo_push("Browse Brush");
- allqueue(REDRAWBUTSEDIT, 0);
- allqueue(REDRAWIMAGE, 0);
- }
- break;
- case B_SIMABRUSHDELETE:
- if(brush_delete(&settings->imapaint.brush)) {
- BIF_undo_push("Unlink Brush");
- allqueue(REDRAWIMAGE, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- }
- break;
- case B_KEEPDATA:
- brush_toggle_fake_user(settings->imapaint.brush);
- allqueue(REDRAWIMAGE, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- break;
- case B_SIMABRUSHLOCAL:
- if(settings->imapaint.brush && settings->imapaint.brush->id.lib) {
- if(okee("Make local")) {
- make_local_brush(settings->imapaint.brush);
- allqueue(REDRAWIMAGE, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- }
- }
- break;
- case B_SIMABTEXBROWSE:
- if(settings->imapaint.brush) {
- Brush *brush= settings->imapaint.brush;
-
- if(G.sima->menunr==-2) {
- MTex *mtex= brush->mtex[brush->texact];
- ID *id= (ID*)((mtex)? mtex->tex: NULL);
- activate_databrowse(id, ID_TE, 0, B_SIMABTEXBROWSE, &G.sima->menunr, do_global_buttons);
- break;
- }
- else if(G.sima->menunr < 0) break;
-
- if(brush_texture_set_nr(brush, G.sima->menunr)) {
- BIF_undo_push("Browse Brush Texture");
- allqueue(REDRAWBUTSSHADING, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- allqueue(REDRAWIMAGE, 0);
- }
+ if(ibuf->rect_float) {
+ if(ibuf->channels!=4) {
+ sprintf(str+ofs, "%d float channel(s)", ibuf->channels);
}
- break;
- case B_SIMABTEXDELETE:
- if(settings->imapaint.brush) {
- if (brush_texture_delete(settings->imapaint.brush)) {
- BIF_undo_push("Unlink Brush Texture");
- allqueue(REDRAWBUTSSHADING, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- allqueue(REDRAWIMAGE, 0);
- }
- }
- break;
+ else if(ibuf->depth==32)
+ strcat(str, " RGBA float");
+ else
+ strcat(str, " RGB float");
}
+ else {
+ if(ibuf->depth==32)
+ strcat(str, " RGBA byte");
+ else
+ strcat(str, " RGB byte");
+ }
+ if(ibuf->zbuf || ibuf->zbuf_float)
+ strcat(str, " + Z");
+
}
static void image_panel_properties(short cntrl) // IMAGE_HANDLER_PROPERTIES
{
uiBlock *block;
-
+
block= uiNewBlock(&curarea->uiblocks, "image_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(IMAGE_HANDLER_PROPERTIES); // for close and esc
if(uiNewPanel(curarea, block, "Properties", "Image", 10, 10, 318, 204)==0)
return;
+
+ uiblock_image_panel(block, &G.sima->image, &G.sima->iuser, B_REDR, B_REDR);
- if (G.sima->image && G.sima->image->ibuf) {
- ImBuf *ibuf= G.sima->image->ibuf;
- char str[64];
+}
- sprintf(str, "Image: size %d x %d", ibuf->x, ibuf->y);
- if(ibuf->rect_float) {
- if(ibuf->depth==32)
- strcat(str, " RGBA float");
- else
- strcat(str, " RGB float");
- }
- else {
- if(ibuf->depth==32)
- strcat(str, " RGBA byte");
- else
- strcat(str, " RGB byte");
- }
- if(ibuf->zbuf || ibuf->zbuf_float)
- strcat(str, " + Z");
+static void image_panel_game_properties(short cntrl) // IMAGE_HANDLER_GAME_PROPERTIES
+{
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "image_panel_game_properties", UI_EMBOSS, UI_HELV, curarea->win);
+ uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+ uiSetPanelHandler(IMAGE_HANDLER_GAME_PROPERTIES); // for close and esc
+ if(uiNewPanel(curarea, block, "Game Properties", "Image", 10, 10, 318, 204)==0)
+ return;
+
+ if (ibuf) {
+ char str[128];
+ image_info(G.sima->image, ibuf, str);
uiDefBut(block, LABEL, B_NOP, str, 10,180,300,19, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
@@ -1050,7 +936,7 @@ static void image_panel_properties(short cntrl) // IMAGE_HANDLER_PROPERTIES
image_editvertex_buts(block);
}
-static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES
+static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PAINT
{
/* B_SIMABRUSHCHANGE only redraws and eats the mouse messages */
/* so that LEFTMOUSE does not 'punch' through the floating panel */
@@ -1135,7 +1021,7 @@ static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES
#endif
}
-static void image_panel_curves_reset(void *cumap_v, void *unused)
+static void image_panel_curves_reset(void *cumap_v, void *ibuf_v)
{
CurveMapping *cumap = cumap_v;
int a;
@@ -1148,14 +1034,15 @@ static void image_panel_curves_reset(void *cumap_v, void *unused)
curvemapping_set_black_white(cumap, NULL, NULL);
curvemapping_changed(cumap, 0);
- curvemapping_do_image(cumap, G.sima->image);
+ curvemapping_do_ibuf(cumap, ibuf_v);
allqueue(REDRAWIMAGE, 0);
}
-static void image_panel_curves(short cntrl) // IMAGE_HANDLER_PROPERTIES
+static void image_panel_curves(short cntrl) // IMAGE_HANDLER_CURVES
{
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
uiBlock *block;
uiBut *bt;
@@ -1165,7 +1052,7 @@ static void image_panel_curves(short cntrl) // IMAGE_HANDLER_PROPERTIES
if(uiNewPanel(curarea, block, "Curves", "Image", 10, 450, 318, 204)==0)
return;
- if (G.sima->image && G.sima->image->ibuf) {
+ if (ibuf) {
rctf rect;
if(G.sima->cumap==NULL)
@@ -1176,7 +1063,7 @@ static void image_panel_curves(short cntrl) // IMAGE_HANDLER_PROPERTIES
curvemap_buttons(block, G.sima->cumap, 'c', B_SIMACURVES, B_SIMAGEDRAW, &rect);
bt=uiDefBut(block, BUT, B_SIMARANGE, "Reset", 10, 160, 90, 19, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves");
- uiButSetFunc(bt, image_panel_curves_reset, G.sima->cumap, NULL);
+ uiButSetFunc(bt, image_panel_curves_reset, G.sima->cumap, ibuf);
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_SIMARANGE, "Min R:", 10, 120, 90, 19, G.sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level");
@@ -1339,6 +1226,9 @@ static void image_blockhandlers(ScrArea *sa)
case IMAGE_HANDLER_PROPERTIES:
image_panel_properties(sima->blockhandler[a+1]);
break;
+ case IMAGE_HANDLER_GAME_PROPERTIES:
+ image_panel_game_properties(sima->blockhandler[a+1]);
+ break;
case IMAGE_HANDLER_PAINT:
image_panel_paint(sima->blockhandler[a+1]);
break;
@@ -1355,6 +1245,53 @@ static void image_blockhandlers(ScrArea *sa)
uiDrawBlocksPanels(sa, 0);
}
+void imagespace_composite_flipbook(ScrArea *sa)
+{
+ SpaceImage *sima= sa->spacedata.first;
+ ImBuf *ibuf;
+ int cfrao= G.scene->r.cfra;
+ int sfra, efra;
+
+ if(sa->spacetype!=SPACE_IMAGE)
+ return;
+ if(sima->iuser.frames<2)
+ return;
+ if(G.scene->nodetree==NULL)
+ return;
+
+ sfra= sima->iuser.sfra;
+ efra= sima->iuser.sfra + sima->iuser.frames-1;
+ G.scene->nodetree->test_break= blender_test_break;
+
+ for(G.scene->r.cfra=sfra; G.scene->r.cfra<=efra; G.scene->r.cfra++) {
+
+ set_timecursor(CFRA);
+
+ BKE_image_all_free_anim_ibufs(CFRA);
+ ntreeCompositTagAnimated(G.scene->nodetree);
+ ntreeCompositExecTree(G.scene->nodetree, &G.scene->r, G.scene->r.cfra!=cfrao); /* 1 is no previews */
+
+ force_draw(0);
+
+ ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+ /* save memory in flipbooks */
+ if(ibuf)
+ imb_freerectfloatImBuf(ibuf);
+
+ if(blender_test_break())
+ break;
+ }
+ G.scene->nodetree->test_break= NULL;
+ waitcursor(0);
+
+ play_anim(0);
+
+ allqueue(REDRAWNODE, 1);
+ allqueue(REDRAWIMAGE, 1);
+
+ G.scene->r.cfra= cfrao;
+}
+
static void imagespace_grid(SpaceImage *sima)
{
float gridsize, gridstep= 1.0f/32.0f;
@@ -1548,8 +1485,9 @@ static void imagewindow_draw_renderinfo(ScrArea *sa)
SpaceImage *sima= sa->spacedata.first;
rcti rect;
float colf[3];
+ char *str= sima->showspare?sima->info_spare:sima->info_str;
- if(sima->info_str==NULL)
+ if(str==NULL)
return;
rect= sa->winrct;
@@ -1564,7 +1502,11 @@ static void imagewindow_draw_renderinfo(ScrArea *sa)
BIF_ThemeColor(TH_TEXT_HI);
glRasterPos2i(12, 5);
- BMF_DrawString(G.fonts, sima->info_str);
+ if(sima->showspare) {
+ BMF_DrawString(G.fonts, "(Previous)");
+ glRasterPos2i(72, 5);
+ }
+ BMF_DrawString(G.fonts, str);
}
void drawimagespace(ScrArea *sa, void *spacedata)
@@ -1575,7 +1517,7 @@ void drawimagespace(ScrArea *sa, void *spacedata)
float col[3];
unsigned int *rect;
float x1, y1;
- short sx, sy, dx, dy, show_render= 0;
+ short sx, sy, dx, dy, show_render= 0, show_viewer= 0;
/* If derived data is used then make sure that object
* is up-to-date... might not be the case because updates
@@ -1593,24 +1535,33 @@ void drawimagespace(ScrArea *sa, void *spacedata)
bwin_clear_viewmat(sa->win); /* clear buttons view */
glLoadIdentity();
- if(sima->image && BLI_streq(sima->image->id.name+2, "Render Result") )
- show_render= 1;
-
+ if(sima->image && sima->image->source==IMA_SRC_VIEWER) {
+ show_viewer= 1;
+ if(sima->image->type==IMA_TYPE_R_RESULT)
+ show_render= 1;
+ }
what_image(sima);
if(sima->image) {
- if(sima->image->ibuf==NULL && show_render==0) {
- load_image(sima->image, IB_rect, G.sce, G.scene->r.cfra);
- scrarea_queue_headredraw(sa); /* update header for image options */
- }
- tag_image_time(sima->image);
- ibuf= sima->image->ibuf;
+ /* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */
+ if(sima->image->type==IMA_TYPE_COMPOSITE) {
+ ImageUser *iuser= ntree_get_active_iuser(G.scene->nodetree);
+ if(iuser) {
+ BKE_image_user_calc_imanr(iuser, G.scene->r.cfra, 0);
+ G.sima->iuser= *iuser;
+ }
+ }
+ /* and we check for spare */
+ if(sima->image->type==IMA_TYPE_R_RESULT && sima->showspare)
+ ibuf= sima->spare;
+ else
+ ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
}
if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
imagespace_grid(sima);
- if(show_render==0)
+ if(show_viewer==0)
draw_tfaces();
}
else {
@@ -1706,14 +1657,16 @@ void drawimagespace(ScrArea *sa, void *spacedata)
if(sima->flag & SI_SHOW_ALPHA) {
if(ibuf->rect)
sima_draw_alpha_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->rect);
- else if(ibuf->rect_float)
+ else if(ibuf->rect_float && ibuf->channels==4)
sima_draw_alpha_pixelsf(x1, y1, ibuf->x, ibuf->y, ibuf->rect_float);
}
else if(sima->flag & SI_SHOW_ZBUF) {
if(ibuf->zbuf)
sima_draw_zbuf_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->zbuf);
- else
+ else if(ibuf->zbuf_float)
sima_draw_zbuffloat_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->zbuf_float);
+ else if(ibuf->channels==1)
+ sima_draw_zbuffloat_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->rect_float);
}
else {
if(sima->flag & SI_USE_ALPHA) {
@@ -1725,11 +1678,14 @@ void drawimagespace(ScrArea *sa, void *spacedata)
/* detect if we need to redo the curve map.
ibuf->rect is zero for compositor and render results after change
convert to 32 bits always... drawing float rects isnt supported well (atis)
+
+ NOTE: if float buffer changes, we have to manually remove the rect
*/
+
if(ibuf->rect_float) {
if(ibuf->rect==NULL) {
if(image_curves_active(sa))
- curvemapping_do_image(G.sima->cumap, G.sima->image);
+ curvemapping_do_ibuf(G.sima->cumap, ibuf);
else
IMB_rect_from_float(ibuf);
}
@@ -1770,7 +1726,7 @@ void drawimagespace(ScrArea *sa, void *spacedata)
glPixelZoom(1.0, 1.0);
- if(show_render==0)
+ if(show_viewer==0)
draw_tfaces();
}
@@ -1828,7 +1784,9 @@ static void image_zoom_set_factor(float zoomfac)
width= 256;
height= 256;
if (sima->image) {
- if (sima->image->ibuf) {
+ ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+
+ if (ibuf) {
float xim, yim;
/* I know a bit weak... but preview uses not actual image size */
if(image_preview_active(curarea, &xim, &yim)) {
@@ -1836,8 +1794,8 @@ static void image_zoom_set_factor(float zoomfac)
height= (int) yim;
}
else {
- width= sima->image->ibuf->x;
- height= sima->image->ibuf->y;
+ width= ibuf->x;
+ height= ibuf->y;
}
}
}
@@ -1938,18 +1896,19 @@ void image_viewzoom(unsigned short event, int invert)
*/
void image_home(void)
{
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
int width, height, imgwidth, imgheight;
float zoomX, zoomY;
if (curarea->spacetype != SPACE_IMAGE) return;
- if ((G.sima->image == NULL) || (G.sima->image->ibuf == NULL)) {
+ if (ibuf == NULL) {
imgwidth = 256;
imgheight = 256;
}
else {
- imgwidth = G.sima->image->ibuf->x;
- imgheight = G.sima->image->ibuf->y;
+ imgwidth = ibuf->x;
+ imgheight = ibuf->y;
}
/* Check if the image will fit in the image with zoom==1 */
@@ -1977,15 +1936,16 @@ void image_home(void)
void image_viewcentre(void)
{
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
float size, min[2], max[2], d[2], xim=256.0f, yim=256.0f;
if( is_uv_tface_editing_allowed()==0 ) return;
if (!minmax_tface_uv(min, max)) return;
- if(G.sima->image && G.sima->image->ibuf) {
- xim= G.sima->image->ibuf->x;
- yim= G.sima->image->ibuf->y;
+ if(ibuf) {
+ xim= ibuf->x;
+ yim= ibuf->y;
}
G.sima->xof= (int) (((min[0] + max[0])*0.5f - 0.5f)*xim);
@@ -2090,14 +2050,6 @@ static void imagewindow_progress_display_cb(RenderResult *rr, volatile rcti *rec
if (image_area) {
- if(rect==NULL) {
- SpaceImage *sima= image_area->spacedata.first;
-
- /* this enforces reading correct buffer in what_image(), renderlayers/scenes/compo/sequences... */
- IMB_freeImBuf(sima->image->ibuf);
- sima->image->ibuf= NULL;
- }
-
imagewindow_progress(image_area, rr, rect);
/* no screen_swapbuffers, prevent any other window to draw */
@@ -2153,7 +2105,7 @@ static ScrArea *biggest_area(void)
make a new temp fullscreen area with Image Window
*/
-static ScrArea *imagewindow_set_render_display(void)
+static ScrArea *find_area_showing_r_result(void)
{
ScrArea *sa;
SpaceImage *sima;
@@ -2162,11 +2114,20 @@ static ScrArea *imagewindow_set_render_display(void)
for(sa=G.curscreen->areabase.first; sa; sa= sa->next) {
if(sa->spacetype==SPACE_IMAGE) {
sima= sa->spacedata.first;
-
- if(sima->image && BLI_streq(sima->image->id.name+2, "Render Result") )
+ if(sima->image && sima->image->type==IMA_TYPE_R_RESULT)
break;
}
}
+ return sa;
+}
+
+static ScrArea *imagewindow_set_render_display(void)
+{
+ ScrArea *sa;
+ SpaceImage *sima;
+
+ sa= find_area_showing_r_result();
+
if(sa==NULL) {
/* find largest open non-image area */
sa= biggest_non_image_area();
@@ -2193,21 +2154,7 @@ static ScrArea *imagewindow_set_render_display(void)
sima= sa->spacedata.first;
/* get the correct image, and scale it */
- sima->image = (Image *)find_id("IM", "Render Result");
-
- if(sima->image==NULL) {
- Image *ima= alloc_libblock(&G.main->image, ID_IM, "Render Result");
- strcpy(ima->name, "Render Result");
- ima->ok= 1;
- ima->xrep= ima->yrep= 1;
- sima->image= ima;
- }
- else if(sima->image->id.us==0) /* well... happens on reload, dunno yet what todo, imagewindow cannot be user when hidden*/
- id_us_plus(&sima->image->id);
-
- /* this enforces reading empty buffer in what_image(), so display is cleared */
- IMB_freeImBuf(sima->image->ibuf);
- sima->image->ibuf= NULL;
+ sima->image= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
if(G.displaymode==R_DISPLAYSCREEN) {
if(sa->full==0) {
@@ -2260,7 +2207,7 @@ void imagewindow_toggle_render(void)
if(sa->spacetype==SPACE_IMAGE) {
SpaceImage *sima= sa->spacedata.first;
- if(sima->image && BLI_streq(sima->image->id.name+2, "Render Result") )
+ if(sima->image && sima->image->type==IMA_TYPE_R_RESULT)
if(sima->flag & (SI_PREVSPACE|SI_FULLWINDOW))
break;
}
@@ -2292,7 +2239,6 @@ static void imagewindow_renderinfo_cb(RenderStats *rs)
}
}
-
void imagewindow_render_callbacks(Render *re)
{
RE_display_init_cb(re, imagewindow_init_display_cb);
@@ -2301,3 +2247,53 @@ void imagewindow_render_callbacks(Render *re)
RE_stats_draw_cb(re, imagewindow_renderinfo_cb);
}
+void imagewin_store_spare(void)
+{
+ ScrArea *sa= find_area_showing_r_result();
+
+ if(sa) {
+ ImBuf *ibuf;
+ SpaceImage *sima= sa->spacedata.first;
+
+ if(sima->spare==NULL)
+ return;
+
+ /* only store when it does not show spare */
+ if(sima->showspare==0)
+ return;
+ sima->showspare= 0;
+
+ /* free spare */
+ IMB_freeImBuf(sima->spare);
+
+ /* make a copy of render result */
+ ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+ sima->spare= IMB_dupImBuf(ibuf);
+
+ BLI_strncpy(sima->info_spare, sima->info_str, RW_MAXTEXT);
+
+ }
+}
+
+/* context: in current image window? */
+void imagewindow_swap_render_rects(void)
+{
+ ScrArea *sa= find_area_showing_r_result();
+
+ if(sa) {
+ SpaceImage *sima= sa->spacedata.first;
+ ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+ if(ibuf) {
+
+ sima->showspare ^= 1;
+
+ if(sima->spare==NULL)
+ sima->spare= IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0, 0);
+ if(sima->info_spare==NULL)
+ sima->info_spare= MEM_callocN(RW_MAXTEXT, "info str imagewin");
+
+ allqueue(REDRAWIMAGE, 0);
+ }
+ }
+}
+
diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c
index c6b0a874ff4..94255384108 100644
--- a/source/blender/src/drawmesh.c
+++ b/source/blender/src/drawmesh.c
@@ -183,6 +183,7 @@ int set_tpage(MTFace *tface)
static int alphamode= -1;
static MTFace *lasttface= 0;
Image *ima;
+ ImBuf *ibuf;
unsigned int *rect=NULL, *bind;
int tpx=0, tpy=0, tilemode, tileXRep,tileYRep;
@@ -256,8 +257,7 @@ int set_tpage(MTFace *tface)
tilemode= tface->mode & TF_TILES;
tileXRep = 0;
tileYRep = 0;
- if (ima)
- {
+ if (ima) {
tileXRep = ima->xrep;
tileYRep = ima->yrep;
}
@@ -265,18 +265,17 @@ int set_tpage(MTFace *tface)
if(ima==fCurpage && fCurtile==tface->tile && tilemode==fCurmode && fCurtileXRep==tileXRep && fCurtileYRep == tileYRep) return ima!=0;
- if(tilemode!=fCurmode || fCurtileXRep!=tileXRep || fCurtileYRep != tileYRep)
- {
+ if(tilemode!=fCurmode || fCurtileXRep!=tileXRep || fCurtileYRep != tileYRep) {
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
- if(tilemode && ima!=0)
+ if(tilemode && ima!=NULL)
glScalef(ima->xrep, ima->yrep, 1.0);
glMatrixMode(GL_MODELVIEW);
}
- if(ima==0 || ima->ok==0) {
+ if(ima==NULL || ima->ok==0) {
glDisable(GL_TEXTURE_2D);
fCurtile= tface->tile;
@@ -288,25 +287,21 @@ int set_tpage(MTFace *tface)
return 0;
}
- if(ima->ibuf==0) {
- load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
+ ibuf= BKE_image_get_ibuf(ima, NULL);
+ if(ibuf==NULL) {
- if(ima->ibuf==0) {
- ima->ok= 0;
-
- fCurtile= tface->tile;
- fCurpage= 0;
- fCurmode= tilemode;
- fCurtileXRep = tileXRep;
- fCurtileYRep = tileYRep;
-
- glDisable(GL_TEXTURE_2D);
- return 0;
- }
+ fCurtile= tface->tile;
+ fCurpage= 0;
+ fCurmode= tilemode;
+ fCurtileXRep = tileXRep;
+ fCurtileYRep = tileYRep;
+
+ glDisable(GL_TEXTURE_2D);
+ return 0;
}
- if ((ima->ibuf->rect==NULL) && ima->ibuf->rect_float)
- IMB_rect_from_float(ima->ibuf);
+ if ((ibuf->rect==NULL) && ibuf->rect_float)
+ IMB_rect_from_float(ibuf);
if(ima->tpageflag & IMA_TWINANIM) fCurtile= ima->lastframe;
else fCurtile= tface->tile;
@@ -323,8 +318,8 @@ int set_tpage(MTFace *tface)
if(*bind==0) {
- fTexwindx= ima->ibuf->x/ima->xrep;
- fTexwindy= ima->ibuf->y/ima->yrep;
+ fTexwindx= ibuf->x/ima->xrep;
+ fTexwindy= ibuf->y/ima->yrep;
if(fCurtile>=ima->xrep*ima->yrep) fCurtile= ima->xrep*ima->yrep-1;
@@ -337,16 +332,16 @@ int set_tpage(MTFace *tface)
tpx= fTexwindx;
tpy= fTexwindy;
- rect= ima->ibuf->rect + fTexwinsy*ima->ibuf->x + fTexwinsx;
+ rect= ibuf->rect + fTexwinsy*ibuf->x + fTexwinsx;
}
}
else {
bind= &ima->bindcode;
if(*bind==0) {
- tpx= ima->ibuf->x;
- tpy= ima->ibuf->y;
- rect= ima->ibuf->rect;
+ tpx= ibuf->x;
+ tpy= ibuf->y;
+ rect= ibuf->rect;
}
}
@@ -367,7 +362,7 @@ int set_tpage(MTFace *tface)
tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
for (y=0; y<recth; y++) {
- unsigned int *rectrow= &rect[y*ima->ibuf->x];
+ unsigned int *rectrow= &rect[y*ibuf->x];
unsigned int *tilerectrow= &tilerect[y*rectw];
memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
@@ -422,8 +417,6 @@ int set_tpage(MTFace *tface)
}
else glBindTexture( GL_TEXTURE_2D, *bind);
- tag_image_time(ima);
-
glEnable(GL_TEXTURE_2D);
fCurpage= ima;
@@ -436,8 +429,10 @@ int set_tpage(MTFace *tface)
void update_realtime_image(Image *ima, int x, int y, int w, int h)
{
- if (ima->repbind || get_mipmap() || !ima->bindcode || !ima->ibuf ||
- (!is_pow2(ima->ibuf->x) || !is_pow2(ima->ibuf->y)) ||
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ if (ima->repbind || get_mipmap() || !ima->bindcode || !ibuf ||
+ (!is_pow2(ibuf->x) || !is_pow2(ibuf->y)) ||
(w == 0) || (h == 0)) {
/* these special cases require full reload still */
free_realtime_image(ima);
@@ -447,17 +442,17 @@ void update_realtime_image(Image *ima, int x, int y, int w, int h)
int skip_pixels = glaGetOneInteger(GL_UNPACK_SKIP_PIXELS);
int skip_rows = glaGetOneInteger(GL_UNPACK_SKIP_ROWS);
- if ((ima->ibuf->rect==NULL) && ima->ibuf->rect_float)
- IMB_rect_from_float(ima->ibuf);
+ if ((ibuf->rect==NULL) && ibuf->rect_float)
+ IMB_rect_from_float(ibuf);
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, ima->ibuf->x);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
- GL_UNSIGNED_BYTE, ima->ibuf->rect);
+ GL_UNSIGNED_BYTE, ibuf->rect);
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
@@ -536,7 +531,9 @@ void texpaint_enable_mipmap(void)
void make_repbind(Image *ima)
{
- if(ima==0 || ima->ibuf==0) return;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ if(ibuf==NULL) return;
if(ima->repbind) {
glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
@@ -1050,7 +1047,7 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt)
float v1[3], v2[3], v3[3], v4[3];
char string[MAX_PROPSTRING];
int characters, index;
- Image *ima;
+ ImBuf *ibuf;
float curpos;
if (badtex)
@@ -1068,8 +1065,8 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt)
set_property_valstr(prop, string);
characters = strlen(string);
- ima = tface->tpage;
- if (ima == NULL) {
+ ibuf= BKE_image_get_ibuf(tface->tpage, NULL);
+ if (ibuf == NULL) {
characters = 0;
}
@@ -1092,7 +1089,7 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt)
// space starts at offset 1
// character = character - ' ' + 1;
- matrixGlyph(ima->ibuf, character, & centerx, &centery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+ matrixGlyph(ibuf, character, & centerx, &centery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
movex+= curpos;
if (tface->mode & TF_OBCOL) glColor3ubv(obcol);
diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c
index d23f86ce4df..831387de931 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -647,7 +647,7 @@ static void node_shader_set_butfunc(bNodeType *ntype)
}
}
-/* ****************** BUTTON CALLBACKS FOR COMPOSIT NODES ***************** */
+/* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
@@ -670,6 +670,7 @@ static void node_browse_image_cb(void *ntree_v, void *node_v)
BLI_strncpy(node->name, node->id->name+2, 21);
NodeTagChanged(ntree, node);
+ BKE_image_signal((Image *)node->id, node->storage, IMA_SIGNAL_USER_NEW_IMAGE);
addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC+node->nr);
}
node->menunr= 0;
@@ -679,24 +680,57 @@ static void node_active_cb(void *ntree_v, void *node_v)
{
nodeSetActive(ntree_v, node_v);
}
-static void node_image_anim_cb(void *node_v, void *unused)
+static void node_image_type_cb(void *node_v, void *unused)
{
- bNode *node= node_v;
- NodeImageAnim *nia;
- if(node->storage) {
- MEM_freeN(node->storage);
- node->storage= NULL;
- }
- else {
- nia= node->storage= MEM_callocN(sizeof(NodeImageAnim), "node image anim");
- nia->sfra= nia->nr= 1;
- }
allqueue(REDRAWNODE, 1);
}
+static char *node_image_type_pup(void)
+{
+ char *str= MEM_mallocN(256, "image type pup");
+ int a;
+
+ str[0]= 0;
+
+ a= sprintf(str, "Image Type %%t|");
+ a+= sprintf(str+a, " Image %%x%d %%i%d|", IMA_SRC_FILE, ICON_IMAGE_DEHLT);
+ a+= sprintf(str+a, " Movie %%x%d %%i%d|", IMA_SRC_MOVIE, ICON_SEQUENCE);
+ a+= sprintf(str+a, " Sequence %%x%d %%i%d|", IMA_SRC_SEQUENCE, ICON_IMAGE_COL);
+ a+= sprintf(str+a, " Generated %%x%d %%i%d", IMA_SRC_GENERATED, ICON_BLANK1);
+
+ return str;
+}
+
+/* copy from buttons_shading.c */
+static char *layer_menu(RenderResult *rr)
+{
+ RenderLayer *rl;
+ int len= 40 + 40*BLI_countlist(&rr->layers);
+ short a, nr;
+ char *str= MEM_callocN(len, "menu layers");
+
+ strcpy(str, "Layer %t");
+ a= strlen(str);
+ for(nr=0, rl= rr->layers.first; rl; rl= rl->next, nr++) {
+ a+= sprintf(str+a, "|%s %%x%d", rl->name, nr);
+ }
+
+ return str;
+}
+
+static void image_layer_cb(void *ima_v, void *iuser_v)
+{
+
+ ntreeCompositForceHidden(G.scene->nodetree);
+ BKE_image_multilayer_index(ima_v, iuser_v);
+ allqueue(REDRAWNODE, 0);
+}
+
static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
+ ImageUser *iuser= node->storage;
+
if(block) {
uiBut *bt;
short dy= (short)butr->ymax-19;
@@ -706,7 +740,7 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
uiBlockSetCol(block, TH_BUT_SETTING2);
/* browse button */
- IDnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL);
+ IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL);
node->menunr= 0;
bt= uiDefButS(block, MENU, B_NOP, strp,
butr->xmin, dy, 19, 19,
@@ -723,44 +757,82 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
uiBlockSetCol(block, TH_AUTO);
}
else {
- /* name button */
- short width= (short)(butr->xmax-butr->xmin-38.0f);
- bt= uiDefBut(block, TEX, B_NOP, "IMA:",
- butr->xmin+19, dy, width, 19,
+ /* name button + type */
+ Image *ima= (Image *)node->id;
+ short xmin= (short)butr->xmin, xmax= (short)butr->xmax;
+ short width= xmax - xmin - 45;
+ short icon= ICON_IMAGE_DEHLT;
+
+ if(ima->source==IMA_SRC_MOVIE) icon= ICON_SEQUENCE;
+ else if(ima->source==IMA_SRC_SEQUENCE) icon= ICON_IMAGE_COL;
+ else if(ima->source==IMA_SRC_GENERATED) icon= ICON_BLANK1;
+
+ bt= uiDefBut(block, TEX, B_NOP, "IM:",
+ xmin+19, dy, width, 19,
node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
uiButSetFunc(bt, node_ID_title_cb, node, NULL);
- bt= uiDefIconBut(block, BUT, B_NOP, ICON_SEQUENCE,
- butr->xmax-19, dy, 19, 19,
- node->id->name+2, 0.0, 19.0, 0, 0, "Enable/Disable Image animation");
- uiButSetFunc(bt, node_image_anim_cb, node, NULL);
- }
- if(node->storage) {
- NodeImageAnim *nia= node->storage;
- short width= (short)(butr->xmax-butr->xmin)/2;
- dy-= 19;
- uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "Frs:",
- butr->xmin, dy, width, 19,
- &nia->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation");
- uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "SFra:",
- butr->xmin+width, dy, width, 19,
- &nia->sfra, 1.0, 10000.0, 0, 0, "Start frame of animation");
- dy-= 19;
- uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "First:",
- butr->xmin, dy, width, 19,
- &nia->nr, 0.0, 10000.0, 0, 0, "Number in image name, used as first in animation");
- uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "Cycl",
- butr->xmin+width, dy, width-19, 19,
- &nia->cyclic, 0.0, 0.0, 0, 0, "Make animation go cyclic");
- bt= uiDefIconButC(block, TOG, B_NODE_EXEC+node->nr, ICON_SEQUENCE,
- butr->xmax-19, dy, 19, 19,
- &nia->movie, 0.0, 19.0, 0, 0, "Enable/Disable reading Image from Movie file");
+ /* buffer type option */
+ strp= node_image_type_pup();
+ bt= uiDefIconTextButS(block, MENU, B_NOP, icon, strp,
+ xmax-26, dy, 26, 19,
+ &ima->source, 0.0, 19.0, 0, 0, "Image type");
+ uiButSetFunc(bt, node_image_type_cb, node, ima);
+ MEM_freeN(strp);
+ if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) ) {
+ width= (xmax-xmin)/2;
+
+ dy-= 19;
+ uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "Frs:",
+ xmin, dy, width, 19,
+ &iuser->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation");
+ uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "SFra:",
+ xmin+width, dy, width, 19,
+ &iuser->sfra, 1.0, 10000.0, 0, 0, "Start frame of animation");
+ dy-= 19;
+ uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "Offs:",
+ xmin, dy, width, 19,
+ &iuser->offset, 0.0, 10000.0, 0, 0, "Offsets the number of the frame to use in the animation");
+ uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "Cycl",
+ xmin+width, dy, width-20, 19,
+ &iuser->cycl, 0.0, 0.0, 0, 0, "Make animation go cyclic");
+ uiDefIconButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NODE_EXEC+node->nr, ICON_AUTO,
+ xmax-20, dy, 20, 19,
+ &iuser->flag, 0.0, 0.0, 0, 0, "Always refresh Image on frame changes");
+ }
+ if( ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
+ RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
+ if(rl) {
+ width= (xmax-xmin);
+ dy-= 19;
+ strp= layer_menu(ima->rr);
+ bt= uiDefButS(block, MENU, B_NODE_EXEC+node->nr, strp,
+ xmin, dy, width, 19,
+ &iuser->layer, 0.0, 10000.0, 0, 0, "Layer");
+ uiButSetFunc(bt, image_layer_cb, ima, node->storage);
+ MEM_freeN(strp);
+ }
+ }
}
}
- if(node->storage)
- return 57;
+ if(node->id) {
+ Image *ima= (Image *)node->id;
+ int retval= 19;
+
+ /* for each draw we test for anim refresh event */
+ if(iuser->flag & IMA_ANIM_REFRESHED) {
+ iuser->flag &= ~IMA_ANIM_REFRESHED;
+ addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC+node->nr);
+ }
+
+ if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) )
+ retval+= 38;
+ if( ima->type==IMA_TYPE_MULTILAYER)
+ retval+= 19;
+ return retval;
+ }
else
return 19;
}
@@ -1445,27 +1517,27 @@ static void draw_nodespace_grid(SpaceNode *snode)
static void draw_nodespace_back(ScrArea *sa, SpaceNode *snode)
{
- Image *ima;
- int x, y;
-
+
draw_nodespace_grid(snode);
if(snode->flag & SNODE_BACKDRAW) {
- ima= (Image *)find_id("IM", "Viewer Node");
- if(ima && ima->ibuf) {
+ Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ if(ibuf) {
+ int x, y;
/* somehow the offset has to be calculated inverse */
glaDefine2DArea(&sa->winrct);
/* ortho at pixel level curarea */
myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
- x = (sa->winx-ima->ibuf->x)/2 + snode->xof;
- y = (sa->winx-ima->ibuf->y)/2 + snode->yof;
+ x = (sa->winx-ibuf->x)/2 + snode->xof;
+ y = (sa->winx-ibuf->y)/2 + snode->yof;
- if(ima->ibuf->rect)
- glaDrawPixelsSafe(x, y, ima->ibuf->x, ima->ibuf->y, ima->ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ima->ibuf->rect);
- else
- glaDrawPixelsSafe(x, y, ima->ibuf->x, ima->ibuf->y, ima->ibuf->x, GL_RGBA, GL_FLOAT, ima->ibuf->rect_float);
+ if(ibuf->rect)
+ glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ else if(ibuf->channels==4)
+ glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);
/* sort this out, this should not be needed */
myortho2(snode->v2d.cur.xmin, snode->v2d.cur.xmax, snode->v2d.cur.ymin, snode->v2d.cur.ymax);
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index d22408f02e3..4706dcff9d0 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -168,22 +168,6 @@ static void star_stuff_term_func(void)
glEnd();
}
-static void setalpha_bgpic(BGpic *bgpic)
-{
- int x, y, alph;
- char *rect;
-
- alph= (int)(255.0*(1.0-bgpic->blend));
-
- rect= (char *)bgpic->rect;
- for(y=0; y< bgpic->yim; y++) {
- for(x= bgpic->xim; x>0; x--, rect+=4) {
- rect[3]= alph;
- }
- }
-}
-
-
void default_gl_light(void)
{
int a;
@@ -349,63 +333,24 @@ static void draw_bgpic(void)
{
BGpic *bgpic;
Image *ima;
+ ImBuf *ibuf= NULL;
float vec[4], fac, asp, zoomx, zoomy;
float x1, y1, x2, y2, cx, cy;
bgpic= G.vd->bgpic;
if(bgpic==NULL) return;
- if(bgpic->tex) {
- extern void init_render_texture(struct Render *re, Tex *tex);
- /* note; bad call, this has to be recoded to move to blenkernel */
- init_render_texture(NULL, bgpic->tex);
- free_unused_animimages();
- ima= bgpic->tex->ima;
- }
- else {
- ima= bgpic->ima;
- }
-
- if(ima==NULL) return;
- if(ima->ok==0) return;
-
- tag_image_time(ima);
-
- /* test for image */
- if(ima->ibuf==NULL) {
+ ima= bgpic->ima;
- if(bgpic->rect) MEM_freeN(bgpic->rect);
- bgpic->rect= NULL;
-
- if(bgpic->tex) {
- ima_ibuf_is_nul(bgpic->tex, bgpic->tex->ima);
- }
- else {
- waitcursor(1);
- load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
- waitcursor(0);
- }
- if(ima->ibuf==NULL) {
- ima->ok= 0;
- return;
- }
- }
-
- /* this ensures that when ibuf changed (reloaded) the backbuf changes too */
- if(bgpic->ibuf!=ima->ibuf) {
- if(bgpic->rect) MEM_freeN(bgpic->rect);
- bgpic->rect= NULL;
- }
- bgpic->ibuf= ima->ibuf;
+ if(ima)
+ ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser);
+ if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL) )
+ return;
+ if(ibuf->channels!=4)
+ return;
+ if(ibuf->rect==NULL)
+ IMB_rect_from_float(ibuf);
- if(bgpic->rect==NULL) {
-
- bgpic->rect= MEM_dupallocN(ima->ibuf->rect);
- bgpic->xim= ima->ibuf->x;
- bgpic->yim= ima->ibuf->y;
- setalpha_bgpic(bgpic);
- }
-
if(G.vd->persp==2) {
rctf vb;
@@ -425,7 +370,7 @@ static void draw_bgpic(void)
fac= MAX3( fabs(vec[0]), fabs(vec[1]), fabs(vec[1]) );
fac= 1.0/fac;
- asp= ( (float)ima->ibuf->y)/(float)ima->ibuf->x;
+ asp= ( (float)ibuf->y)/(float)ibuf->x;
vec[0] = vec[1] = vec[2] = 0.0;
view3d_project_float(curarea, vec, sco, G.vd->persmat);
@@ -445,10 +390,27 @@ static void draw_bgpic(void)
if(x1 > curarea->winx ) return;
if(y1 > curarea->winy ) return;
- zoomx= (x2-x1)/ima->ibuf->x;
- zoomy= (y2-y1)/ima->ibuf->y;
-
- glEnable(GL_BLEND);
+ zoomx= (x2-x1)/ibuf->x;
+ zoomy= (y2-y1)/ibuf->y;
+
+ /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
+ if(zoomx < 1.0f || zoomy < 1.0f) {
+ float tzoom= MIN2(zoomx, zoomy);
+ int mip= 0;
+
+ if(ibuf->mipmap[0]==NULL)
+ IMB_makemipmap(ibuf, 0);
+
+ while(tzoom < 1.0f && mip<8 && ibuf->mipmap[mip]) {
+ tzoom*= 2.0f;
+ zoomx*= 2.0f;
+ zoomy*= 2.0f;
+ mip++;
+ }
+ if(mip>0)
+ ibuf= ibuf->mipmap[mip-1];
+ }
+
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -459,16 +421,18 @@ static void draw_bgpic(void)
glPushMatrix();
glaDefine2DArea(&curarea->winrct);
+ glEnable(GL_BLEND);
+ glPixelTransferf(GL_ALPHA_SCALE, (1.0f-bgpic->blend));
glPixelZoom(zoomx, zoomy);
- glaDrawPixelsSafe(x1, y1, ima->ibuf->x, ima->ibuf->y, ima->ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, bgpic->rect);
+ glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
glPixelZoom(1.0, 1.0);
+ glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
- glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
@@ -1213,9 +1177,6 @@ ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax)
dr++;
}
- ibuf->ftype= PNG;
- IMB_saveiff(ibuf, "/tmp/rt.png", IB_rect);
-
/* put clipped result back, if needed */
if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax)
return ibuf;
@@ -1444,7 +1405,6 @@ static void draw_view_icon(void)
BIF_icon_draw(5.0, 5.0, icon);
- glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
}
@@ -1475,54 +1435,6 @@ static void draw_viewport_name(ScrArea *sa)
/* ******************* view3d space & buttons ************** */
-static void view3d_change_bgpic_ima(View3D *v3d, Image *newima) {
- if (v3d->bgpic && v3d->bgpic->ima!=newima) {
- if (newima)
- id_us_plus((ID*) newima);
- if (v3d->bgpic->ima)
- v3d->bgpic->ima->id.us--;
- v3d->bgpic->ima= newima;
-
- if(v3d->bgpic->rect) MEM_freeN(v3d->bgpic->rect);
- v3d->bgpic->rect= NULL;
-
- allqueue(REDRAWVIEW3D, 0);
- }
-}
-static void view3d_change_bgpic_tex(View3D *v3d, Tex *newtex) {
- if (v3d->bgpic && v3d->bgpic->tex!=newtex) {
- if (newtex)
- id_us_plus((ID*) newtex);
- if (v3d->bgpic->tex)
- v3d->bgpic->tex->id.us--;
- v3d->bgpic->tex= newtex;
-
- allqueue(REDRAWVIEW3D, 0);
- }
-}
-
-static void load_bgpic_image(char *name)
-{
- Image *ima;
- View3D *vd;
-
- areawinset(curarea->win);
- vd= G.vd;
- if(vd==0 || vd->bgpic==0) return;
-
- ima= add_image(name);
- if(ima) {
- if(vd->bgpic->ima) {
- vd->bgpic->ima->id.us--;
- }
- vd->bgpic->ima= ima;
-
- free_image_buffers(ima); /* force read again */
- ima->ok= 1;
- }
- allqueue(REDRAWVIEW3D, 0);
-
-}
/* temporal struct for storing transform properties */
typedef struct {
@@ -1975,63 +1887,12 @@ void do_viewbuts(unsigned short event)
View3D *vd;
Object *ob= OBACT;
TransformProperties *tfp= G.vd->properties_storage;
- char *name;
vd= G.vd;
- if(vd==0) return;
+ if(vd==NULL) return;
switch(event) {
- case B_LOADBGPIC:
- if(vd->bgpic && vd->bgpic->ima) name= vd->bgpic->ima->name;
- else name= G.ima;
-
- if(G.qual==LR_CTRLKEY)
- activate_imageselect(FILE_SPECIAL, "Select Image", name, load_bgpic_image);
- else
- activate_fileselect(FILE_SPECIAL, "Select Image", name, load_bgpic_image);
- break;
-
- case B_BLENDBGPIC:
- if(vd->bgpic && vd->bgpic->rect) setalpha_bgpic(vd->bgpic);
- addqueue(curarea->win, REDRAW, 1);
- break;
-
- case B_BGPICBROWSE:
- if(vd->bgpic) {
- if (vd->menunr==-2) {
- activate_databrowse((ID*) vd->bgpic->ima, ID_IM, 0, B_BGPICBROWSE, &vd->menunr, do_viewbuts);
- } else if (vd->menunr>0) {
- Image *newima= (Image*) BLI_findlink(&G.main->image, vd->menunr-1);
-
- if (newima)
- view3d_change_bgpic_ima(vd, newima);
- }
- }
- break;
-
- case B_BGPICCLEAR:
- if (vd->bgpic)
- view3d_change_bgpic_ima(vd, NULL);
- break;
- case B_BGPICTEX:
- if (vd->bgpic) {
- if (vd->texnr==-2) {
- activate_databrowse((ID*) vd->bgpic->tex, ID_TE, 0, B_BGPICTEX, &vd->texnr, do_viewbuts);
- } else if (vd->texnr>0) {
- Tex *newtex= (Tex*) BLI_findlink(&G.main->tex, vd->texnr-1);
-
- if (newtex)
- view3d_change_bgpic_tex(vd, newtex);
- }
- }
- break;
-
- case B_BGPICTEXCLEAR:
- if (vd->bgpic)
- view3d_change_bgpic_tex(vd, NULL);
- break;
-
case B_OBJECTPANEL:
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
allqueue(REDRAWVIEW3D, 1);
@@ -2371,8 +2232,6 @@ static void view3d_panel_background(short cntrl) // VIEW3D_HANDLER_BACKGROUND
{
uiBlock *block;
View3D *vd;
- ID *id;
- char *strp;
vd= G.vd;
@@ -2386,68 +2245,29 @@ static void view3d_panel_background(short cntrl) // VIEW3D_HANDLER_BACKGROUND
}
if(vd->flag & V3D_DISPBGPIC) {
- if(vd->bgpic==0) {
+ if(vd->bgpic==NULL) {
vd->bgpic= MEM_callocN(sizeof(BGpic), "bgpic");
vd->bgpic->size= 5.0;
vd->bgpic->blend= 0.5;
+ vd->bgpic->iuser.fie_ima= 2;
+ vd->bgpic->iuser.ok= 1;
}
}
- uiDefButBitS(block, TOG, V3D_DISPBGPIC, REDRAWVIEW3D, "Use Background Image", 0, 162, 200, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of the 3D View");
-
- uiDefBut(block, LABEL, 1, " ", 206, 162, 84, 20, NULL, 0.0, 0.0, 0, 0, "");
-
-
- if(vd->flag & V3D_DISPBGPIC) {
-
- /* Background Image */
- uiDefBut(block, LABEL, 1, "Image:", 0, 128, 76, 19, NULL, 0.0, 0.0, 0, 0, "");
-
+ if(!(vd->flag & V3D_DISPBGPIC)) {
+ uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use Background Image", 10, 180, 150, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of the 3D View");
+ uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
+ }
+ else {
uiBlockBeginAlign(block);
- uiDefIconBut(block, BUT, B_LOADBGPIC, ICON_FILESEL, 90, 128, 20, 20, 0, 0, 0, 0, 0, "Open a new background image");
+ uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use", 10, 225, 50, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of the 3D View");
+ uiDefButF(block, NUMSLI, B_REDR, "Blend:", 60, 225, 150, 20, &vd->bgpic->blend, 0.0,1.0, 0, 0, "Set the transparency of the background image");
+ uiDefButF(block, NUM, B_REDR, "Size:", 210, 225, 100, 20, &vd->bgpic->size, 0.1, 250.0*vd->grid, 100, 0, "Set the size (width) of the background image");
- id= (ID *)vd->bgpic->ima;
- IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(vd->menunr));
- if(strp[0]) {
-
- uiDefButS(block, MENU, B_BGPICBROWSE, strp, 110, 128, 20, 20, &(vd->menunr), 0, 0, 0, 0, "Select a background image");
+ uiDefButF(block, NUM, B_REDR, "X Offset:", 10, 205, 150, 20, &vd->bgpic->xof, -250.0*vd->grid,250.0*vd->grid, 10, 2, "Set the horizontal offset of the background image");
+ uiDefButF(block, NUM, B_REDR, "Y Offset:", 160, 205, 150, 20, &vd->bgpic->yof, -250.0*vd->grid,250.0*vd->grid, 10, 2, "Set the vertical offset of the background image");
- if(vd->bgpic->ima) {
- uiDefBut(block, TEX, 0,"BG: ", 130, 128, 140, 20, &vd->bgpic->ima->name,0.0,100.0, 0, 0, "The currently selected background image");
- uiDefIconBut(block, BUT, B_BGPICCLEAR, ICON_X, 270, 128, 20, 20, 0, 0, 0, 0, 0, "Remove background image link");
- }
- uiBlockEndAlign(block);
- } else {
- uiBlockEndAlign(block);
- }
- MEM_freeN(strp);
-
-
- /* Background texture */
- uiDefBut(block, LABEL, 1, "Texture:", 0, 100, 76, 19, NULL, 0.0, 0.0, 0, 0, "");
-
- id= (ID *)vd->bgpic->tex;
- IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->tex), id, &(vd->texnr));
- if (strp[0])
- uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_BGPICTEX, strp, 90, 100, 20,20, &(vd->texnr), 0, 0, 0, 0, "Select a texture to use as an animated background image");
- MEM_freeN(strp);
-
- if (id) {
- uiDefBut(block, TEX, B_IDNAME, "TE:", 110, 100, 160, 20, id->name+2, 0.0, 18.0, 0, 0, "");
- uiDefIconBut(block, BUT, B_BGPICTEXCLEAR, ICON_X, 270, 100, 20, 20, 0, 0, 0, 0, 0, "Remove background texture link");
- uiBlockEndAlign(block);
- } else {
- uiBlockEndAlign(block);
- }
-
- uiDefButF(block, NUMSLI, B_BLENDBGPIC, "Blend:", 0, 60 , 290, 19, &vd->bgpic->blend, 0.0,1.0, 0, 0, "Set the transparency of the background image");
-
- uiDefButF(block, NUM, REDRAWVIEW3D, "Size:", 0, 28, 140, 19, &vd->bgpic->size, 0.1, 250.0*vd->grid, 100, 0, "Set the size (width) of the background image");
-
- uiDefButF(block, NUM, REDRAWVIEW3D, "X Offset:", 0, 6, 140, 19, &vd->bgpic->xof, -250.0*vd->grid,250.0*vd->grid, 10, 2, "Set the horizontal offset of the background image");
- uiDefButF(block, NUM, REDRAWVIEW3D, "Y Offset:", 150, 6, 140, 19, &vd->bgpic->yof, -250.0*vd->grid,250.0*vd->grid, 10, 2, "Set the vertical offset of the background image");
-
+ uiblock_image_panel(block, &vd->bgpic->ima, &vd->bgpic->iuser, B_REDR, B_REDR);
}
}
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index 9eb3f8794e4..e2faa3649eb 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -154,7 +154,9 @@ static void snode_handle_recalc(SpaceNode *snode)
snode->nodetree->timecursor= set_timecursor;
G.afbreek= 0;
snode->nodetree->test_break= blender_test_break;
-
+
+ BIF_store_spare();
+
ntreeCompositExecTree(snode->nodetree, &G.scene->r, 1); /* 1 is do_previews */
snode->nodetree->timecursor= NULL;
@@ -191,7 +193,7 @@ static void load_node_image(char *str) /* called from fileselect */
bNode *node= nodeGetActive(snode->edittree);
Image *ima= NULL;
- ima= add_image(str);
+ ima= BKE_add_image_file(str);
if(ima) {
if(node->id)
node->id->us--;
@@ -201,8 +203,7 @@ static void load_node_image(char *str) /* called from fileselect */
BLI_strncpy(node->name, node->id->name+2, 21);
- free_image_buffers(ima); /* force read again */
- ima->ok= 1;
+ BKE_image_signal(ima, node->storage, IMA_SIGNAL_RELOAD);
NodeTagChanged(snode->edittree, node);
snode_handle_recalc(snode);
@@ -417,6 +418,28 @@ void snode_set_context(SpaceNode *snode)
snode->edittree= snode->nodetree;
}
+/* on activate image viewer, check if we show it */
+static void node_active_image(Image *ima)
+{
+ ScrArea *sa;
+ SpaceImage *sima= NULL;
+
+ /* find an imagewindow showing render result */
+ for(sa=G.curscreen->areabase.first; sa; sa= sa->next) {
+ if(sa->spacetype==SPACE_IMAGE) {
+ sima= sa->spacedata.first;
+ if(sima->image && sima->image->source!=IMA_SRC_VIEWER)
+ break;
+ }
+ }
+ if(sa && sima) {
+ sima->image= ima;
+ scrarea_queue_winredraw(sa);
+ scrarea_queue_headredraw(sa);
+ }
+}
+
+
static void node_set_active(SpaceNode *snode, bNode *node)
{
@@ -460,18 +483,17 @@ static void node_set_active(SpaceNode *snode, bNode *node)
snode_handle_recalc(snode);
}
- /* add node doesnt link this yet... */
- if(node->id==NULL) {
- node->id= find_id("IM", "Viewer Node");
- if(node->id==NULL) {
- Image *ima= alloc_libblock(&G.main->image, ID_IM, "Viewer Node");
- strcpy(ima->name, "Viewer Node");
- ima->ok= 1;
- ima->xrep= ima->yrep= 1;
- node->id= &ima->id;
- }
- else
- node->id->us++;
+ /* addnode() doesnt link this yet... */
+ node->id= (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ }
+ else if(node->type==CMP_NODE_IMAGE) {
+ if(node->id)
+ node_active_image((Image *)node->id);
+ }
+ else if(node->type==CMP_NODE_R_LAYERS) {
+ if(node->id==NULL || node->id==(ID *)G.scene) {
+ G.scene->r.actlay= node->custom1;
+ allqueue(REDRAWBUTSSCENE, 0);
}
}
}
@@ -746,19 +768,21 @@ void snode_zoom_in(ScrArea *sa)
static void snode_bg_viewmove(SpaceNode *snode)
{
ScrArea *sa;
+ Image *ima;
+ ImBuf *ibuf;
+ Window *win;
short mval[2], mvalo[2];
short rectx, recty, xmin, xmax, ymin, ymax, pad;
- Window *win;
int oldcursor;
- Image *ima;
- ima= (Image *)find_id("IM", "Viewer Node");
+ ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ibuf= BKE_image_get_ibuf(ima, NULL);
sa = snode->area;
- if(ima && ima->ibuf) {
- rectx = ima->ibuf->x;
- recty = ima->ibuf->y;
+ if(ibuf) {
+ rectx = ibuf->x;
+ recty = ibuf->y;
} else {
rectx = recty = 1;
}
@@ -1472,8 +1496,9 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy)
id_us_plus(node->id);
if(snode->nodetree->type==NTREE_COMPOSIT)
- ntreeCompositForceHidden(G.scene->nodetree);
+ ntreeCompositForceHidden(snode->edittree);
+ NodeTagChanged(snode->edittree, node);
}
return node;
}
@@ -1884,6 +1909,43 @@ void node_read_renderlayers(SpaceNode *snode)
snode_handle_recalc(snode);
}
+/* gets active viewer user */
+struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
+{
+ bNode *node;
+
+ if(ntree)
+ for(node= ntree->nodes.first; node; node= node->next)
+ if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+ if(node->flag & NODE_DO_OUTPUT)
+ return node->storage;
+ return NULL;
+}
+
+void imagepaint_composite_tags(bNodeTree *ntree, Image *image, ImageUser *iuser)
+{
+ bNode *node;
+
+ if(ntree==NULL)
+ return;
+
+ /* search for renderresults */
+ if(image->type==IMA_TYPE_R_RESULT) {
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) {
+ /* imageuser comes from ImageWin, so indexes are offset 1 */
+ if(node->custom1==iuser->layer-1)
+ NodeTagChanged(ntree, node);
+ }
+ }
+ }
+ else {
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->id== &image->id)
+ NodeTagChanged(ntree, node);
+ }
+ }
+}
/* ********************** */
@@ -2085,6 +2147,9 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else node_adduplicate(snode);
}
break;
+ case EKEY:
+ snode_handle_recalc(snode);
+ break;
case GKEY:
if(fromlib) fromlib= -1;
else {
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 861306a62cb..913a49c28e2 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -107,6 +107,7 @@
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_ipo.h"
+#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -5049,8 +5050,9 @@ void image_aspect(void)
for(b=0; b<MAX_MTEX; b++) {
if(ma->mtex[b] && ma->mtex[b]->tex) {
tex= ma->mtex[b]->tex;
- if(tex->type==TEX_IMAGE && tex->ima && tex->ima->ibuf) {
-
+ if(tex->type==TEX_IMAGE && tex->ima) {
+ ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, NULL);
+
/* texturespace */
space= 1.0;
if(ob->type==OB_MESH) {
@@ -5063,8 +5065,8 @@ void image_aspect(void)
space= cu->size[0]/cu->size[1];
}
- x= tex->ima->ibuf->x/space;
- y= tex->ima->ibuf->y;
+ x= ibuf->x/space;
+ y= ibuf->y;
if(x>y) ob->size[0]= ob->size[1]*x/y;
else ob->size[1]= ob->size[0]*y/x;
diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c
index d69b1db1365..a8551656343 100644
--- a/source/blender/src/editscreen.c
+++ b/source/blender/src/editscreen.c
@@ -480,8 +480,7 @@ static void headmenu(ScrArea *sa)
static void addqueue_ext(short win, unsigned short event, short val, char ascii)
{
if (win<4 || !areawinar[win]) {
- if(win==0 && !G.background) /* other win ids are for mainwin & renderwin */
- printf("bad call to addqueue: %d (%d, %d)\n", win, event, val);
+ /* other win ids are for mainwin & renderwin */
}
else {
BWinEvent evt;
@@ -1842,8 +1841,8 @@ static void del_area(ScrArea *sa)
if(sa==g_activearea) g_activearea= NULL;
}
-/* sa2 to sa1 */
-static void copy_areadata(ScrArea *sa1, ScrArea *sa2)
+/* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
+static void copy_areadata(ScrArea *sa1, ScrArea *sa2, int swap_space)
{
Panel *pa1, *pa2, *patab;
ScriptLink *slink1 = &sa1->scriptlink, *slink2 = &sa2->scriptlink;
@@ -1852,8 +1851,13 @@ static void copy_areadata(ScrArea *sa1, ScrArea *sa2)
sa1->spacetype= sa2->spacetype;
Mat4CpyMat4(sa1->winmat, sa2->winmat);
- freespacelist(sa1);
- duplicatespacelist(sa1, &sa1->spacedata, &sa2->spacedata);
+ if(swap_space) {
+ SWAP(ListBase, sa1->spacedata, sa2->spacedata);
+ }
+ else {
+ freespacelist(sa1);
+ duplicatespacelist(sa1, &sa1->spacedata, &sa2->spacedata);
+ }
BLI_freelistN(&sa1->panels);
duplicatelist(&sa1->panels, &sa2->panels);
@@ -2332,7 +2336,7 @@ void area_fullscreen(void) /* with curarea */
headertype = curarea->headertype;
}
- copy_areadata(old, curarea);
+ copy_areadata(old, curarea, 1); /* 1 = swap spacelist */
old->headertype = headertype;
old->full= 0;
@@ -2364,7 +2368,7 @@ void area_fullscreen(void) /* with curarea */
G.curscreen= oldscreen; /* needed because of setscreen */
/* copy area */
- copy_areadata(newa, curarea);
+ copy_areadata(newa, curarea, 1); /* 1 = swap spacelist */
curarea->full= oldscreen;
newa->full= oldscreen;
@@ -2416,7 +2420,7 @@ static void area_autoplayscreen(void)
G.curscreen= oldscreen; /* because of setscreen */
/* copy area settings */
- copy_areadata(newa, curarea);
+ copy_areadata(newa, curarea, 1); /* swap spacedata */
newa->headertype= 0;
curarea->full= oldscreen;
@@ -2470,7 +2474,7 @@ static void copy_screen(bScreen *to, bScreen *from)
sa->spacedata.first= sa->spacedata.last= NULL;
sa->uiblocks.first= sa->uiblocks.last= NULL;
sa->panels.first= sa->panels.last= NULL;
- copy_areadata(sa, saf);
+ copy_areadata(sa, saf, 0);
sa= sa->next;
saf= saf->next;
@@ -2939,7 +2943,7 @@ static void splitarea(ScrArea *sa, char dir, float fac)
/* new areas: top */
newa= screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->headertype, sa->spacetype);
- copy_areadata(newa, sa);
+ copy_areadata(newa, sa, 0);
/* area below */
sa->v2= sv1;
@@ -2960,7 +2964,7 @@ static void splitarea(ScrArea *sa, char dir, float fac)
/* new areas: left */
newa= screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->headertype, sa->spacetype);
- copy_areadata(newa, sa);
+ copy_areadata(newa, sa, 0);
/* area right */
sa->v1= sv1;
diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c
index 3e25340048f..d7b025c53f3 100644
--- a/source/blender/src/editsima.c
+++ b/source/blender/src/editsima.c
@@ -49,17 +49,20 @@
#include "BLI_arithb.h"
#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "DNA_image_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object)
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
+#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
-#include "DNA_space_types.h"
-#include "DNA_image_types.h"
-#include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object)
+#include "DNA_view3d_types.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
@@ -69,6 +72,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_packedFile.h"
#include "BKE_utildefines.h"
@@ -97,6 +101,8 @@
#include "BMF_Api.h"
+#include "RE_pipeline.h"
+
#include "blendef.h"
#include "mydevice.h"
@@ -142,10 +148,10 @@ int is_uv_tface_editing_allowed(void)
void get_connected_limit_tface_uv(float *limit)
{
- if(G.sima->image && G.sima->image->ibuf && G.sima->image->ibuf->x > 0 &&
- G.sima->image->ibuf->y > 0) {
- limit[0]= 0.05/(float)G.sima->image->ibuf->x;
- limit[1]= 0.05/(float)G.sima->image->ibuf->y;
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
+ limit[0]= 0.05/(float)ibuf->x;
+ limit[1]= 0.05/(float)ibuf->y;
}
else
limit[0]= limit[1]= 0.05/256.0;
@@ -154,18 +160,20 @@ void get_connected_limit_tface_uv(float *limit)
void clever_numbuts_sima(void)
{
float ocent[2], cent[2]= {0.0, 0.0};
- int imx, imy;
+ int imx= 256, imy= 256;
int i, nactive= 0;
Mesh *me;
if( is_uv_tface_editing_allowed()==0 ) return;
me= get_mesh(OBACT);
- if (G.sima->image && G.sima->image->ibuf) {
- imx= G.sima->image->ibuf->x;
- imy= G.sima->image->ibuf->y;
- } else
- imx= imy= 256;
+ if (G.sima->image) {
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ if(ibuf) {
+ imx= ibuf->x;
+ imy= ibuf->y;
+ }
+ }
for (i=0; i<me->totface; i++) {
MFace *mf= &((MFace*) me->mface)[i];
@@ -312,9 +320,11 @@ void transform_aspect_ratio_tface_uv(float *aspx, float *aspy)
void transform_width_height_tface_uv(int *width, int *height)
{
- if(G.sima->image && G.sima->image->ibuf) {
- *width= G.sima->image->ibuf->x;
- *height= G.sima->image->ibuf->y;
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+
+ if(ibuf) {
+ *width= ibuf->x;
+ *height= ibuf->y;
}
else {
*width= 256;
@@ -861,14 +871,14 @@ void sel_uvco_inside_radius(short sel, MTFace *tface, int index, float *offset,
/** gets image dimensions of the 2D view 'v' */
static void getSpaceImageDimension(SpaceImage *sima, float *xy)
{
- Image *img = sima->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
float z;
z = sima->zoom;
- if (img && img->ibuf) {
- xy[0] = img->ibuf->x * z;
- xy[1] = img->ibuf->y * z;
+ if (ibuf) {
+ xy[0] = ibuf->x * z;
+ xy[1] = ibuf->y * z;
} else {
xy[0] = 256 * z;
xy[1] = 256 * z;
@@ -1049,13 +1059,15 @@ void stitch_uv_tface(int mode)
return;
}
- if(G.sima->image && G.sima->image->ibuf && G.sima->image->ibuf->x > 0 &&
- G.sima->image->ibuf->y > 0) {
- limit[1]= limit[0]/(float)G.sima->image->ibuf->y;
- limit[0]= limit[0]/(float)G.sima->image->ibuf->x;
+ limit[0]= limit[1]= limit[0]/256.0;
+ if(G.sima->image) {
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+
+ if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
+ limit[1]= limit[0]/(float)ibuf->y;
+ limit[0]= limit[0]/(float)ibuf->x;
+ }
}
- else
- limit[0]= limit[1]= limit[0]/256.0;
me= get_mesh(OBACT);
tf= me->mtface;
@@ -1418,7 +1430,7 @@ int minmax_tface_uv(float *min, float *max)
return sel;
}
-static void sima_show_info(int x, int y, char *cp, float *fp, int *zp, float *zpf)
+static void sima_show_info(int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf)
{
short ofs;
char str[256];
@@ -1426,8 +1438,14 @@ static void sima_show_info(int x, int y, char *cp, float *fp, int *zp, float *zp
ofs= sprintf(str, "X: %d Y: %d ", x, y);
if(cp)
ofs+= sprintf(str+ofs, "| R: %d G: %d B: %d A: %d ", cp[0], cp[1], cp[2], cp[3]);
- if(fp)
- ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]);
+ if(fp) {
+ if(channels==4)
+ ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]);
+ else if(channels==1)
+ ofs+= sprintf(str+ofs, "| Val: %.3f ", fp[0]);
+ else if(channels==3)
+ ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f ", fp[0], fp[1], fp[2]);
+ }
if(zp)
ofs+= sprintf(str+ofs, "| Z: %.4f ", 0.5+0.5*( ((float)*zp)/(float)0x7fffffff));
if(zpf)
@@ -1449,13 +1467,12 @@ static void sima_show_info(int x, int y, char *cp, float *fp, int *zp, float *zp
void sima_sample_color(void)
{
- ImBuf *ibuf;
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
float fx, fy;
short mval[2], mvalo[2], firsttime=1;
- if(G.sima->image==NULL) return;
- if(G.sima->image->ibuf==NULL) return;
- ibuf= G.sima->image->ibuf;
+ if(ibuf==NULL)
+ return;
calc_image_view(G.sima, 'f');
getmouseco_areawin(mvalo);
@@ -1485,7 +1502,7 @@ void sima_sample_color(void)
if(ibuf->zbuf_float)
zpf= ibuf->zbuf_float + y*ibuf->x + x;
if(ibuf->rect_float)
- fp= (ibuf->rect_float + 4*(y*ibuf->x + x));
+ fp= (ibuf->rect_float + (ibuf->channels)*(y*ibuf->x + x));
if(G.sima->cumap) {
float vec[3];
@@ -1496,20 +1513,22 @@ void sima_sample_color(void)
vec[2]= (float)cp[2]/255.0f;
}
- if(G.qual & LR_CTRLKEY) {
- curvemapping_set_black_white(G.sima->cumap, NULL, fp);
- curvemapping_do_image(G.sima->cumap, G.sima->image);
- }
- else if(G.qual & LR_SHIFTKEY) {
- curvemapping_set_black_white(G.sima->cumap, fp, NULL);
- curvemapping_do_image(G.sima->cumap, G.sima->image);
+ if(ibuf->channels==4) {
+ if(G.qual & LR_CTRLKEY) {
+ curvemapping_set_black_white(G.sima->cumap, NULL, fp);
+ curvemapping_do_ibuf(G.sima->cumap, ibuf);
+ }
+ else if(G.qual & LR_SHIFTKEY) {
+ curvemapping_set_black_white(G.sima->cumap, fp, NULL);
+ curvemapping_do_ibuf(G.sima->cumap, ibuf);
+ }
}
}
scrarea_do_windraw(curarea);
myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
glLoadIdentity();
- sima_show_info(x, y, cp, fp, zp, zpf);
+ sima_show_info(ibuf->channels, x, y, cp, fp, zp, zpf);
screen_swapbuffers();
}
@@ -1524,20 +1543,19 @@ void sima_sample_color(void)
static void load_image_filesel(char *str) /* called from fileselect */
{
- Image *ima=0;
+ Image *ima= NULL;
if(G.obedit) {
error("Can't perfom this in editmode");
return;
}
- ima= add_image(str);
+ ima= BKE_add_image_file(str);
if(ima) {
G.sima->image= ima;
- free_image_buffers(ima); /* force read again */
- ima->ok= 1;
+ BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
image_changed(G.sima, 0);
}
@@ -1591,7 +1609,7 @@ static void replace_image_filesel(char *str) /* called from fileselect */
return;
}
- ima= add_image(str);
+ ima= BKE_add_image_file(str);
if(ima) {
if(G.sima->image && G.sima->image != ima) {
@@ -1600,8 +1618,8 @@ static void replace_image_filesel(char *str) /* called from fileselect */
G.sima->image= ima;
- free_image_buffers(ima); /* force read again */
- ima->ok= 1;
+ BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
+
/* replace also assigns: */
image_changed(G.sima, 0);
@@ -1610,42 +1628,69 @@ static void replace_image_filesel(char *str) /* called from fileselect */
allqueue(REDRAWIMAGE, 0);
}
-static void save_image_filesel(char *name)
+
+static void save_image_doit(char *name)
{
- Image *ima = G.sima->image;
+ Image *ima= G.sima->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
int len;
char str[FILE_MAXDIR+FILE_MAXFILE];
- if (ima && ima->ibuf) {
+ if (ibuf) {
BLI_strncpy(str, name, sizeof(str));
BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
if(G.scene->r.scemode & R_EXTENSION)
- BKE_add_image_extension(str, G.scene->r.imtype);
-
+ BKE_add_image_extension(str, G.sima->imtypenr);
+
if (saveover(str)) {
+
/* enforce user setting for RGB or RGBA, but skip BW */
if(G.scene->r.planes==32)
- ima->ibuf->depth= 32;
+ ibuf->depth= 32;
else if(G.scene->r.planes==24)
- ima->ibuf->depth= 24;
+ ibuf->depth= 24;
waitcursor(1);
- if (BKE_write_ibuf(ima->ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality)) {
+ if(G.sima->imtypenr==R_MULTILAYER) {
+ RenderResult *rr= BKE_image_get_renderresult(ima);
+ if(rr) {
+ RE_WriteRenderResult(rr, str);
+
+ BLI_strncpy(ima->name, name, sizeof(ima->name));
+ BLI_strncpy(ibuf->name, str, sizeof(ibuf->name));
+
+ /* should be function? nevertheless, saving only happens here */
+ for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next)
+ ibuf->userflags &= ~IB_BITMAPDIRTY;
+
+ }
+ else error("Did not write, no Multilayer Image");
+ }
+ else if (BKE_write_ibuf(ibuf, str, G.sima->imtypenr, G.scene->r.subimtype, G.scene->r.quality)) {
BLI_strncpy(ima->name, name, sizeof(ima->name));
- BLI_strncpy(ima->ibuf->name, str, sizeof(ima->ibuf->name));
- ima->ibuf->userflags &= ~IB_BITMAPDIRTY;
- allqueue(REDRAWHEADERS, 0);
- allqueue(REDRAWBUTSSHADING, 0);
- } else {
+ BLI_strncpy(ibuf->name, str, sizeof(ibuf->name));
+
+ ibuf->userflags &= ~IB_BITMAPDIRTY;
+
+ /* change type? */
+ if( ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER))
+ ima->source= IMA_SRC_FILE;
+ if(ima->type==IMA_TYPE_R_RESULT)
+ ima->type= IMA_TYPE_IMAGE;
+
+ /* name image as how we saved it */
+ len= strlen(str);
+ while (len > 0 && str[len - 1] != '/' && str[len - 1] != '\\') len--;
+ rename_id(&ima->id, str+len);
+ }
+ else {
error("Couldn't write image: %s", str);
}
-
- /* name image as how we saved it */
- len= strlen(str);
- while (len > 0 && str[len - 1] != '/' && str[len - 1] != '\\') len--;
- rename_id(&ima->id, str+len);
+
+ allqueue(REDRAWHEADERS, 0);
+ allqueue(REDRAWBUTSSHADING, 0);
waitcursor(0);
}
@@ -1682,64 +1727,138 @@ void replace_image_sima(short imageselect)
activate_fileselect(FILE_SPECIAL, "Replace Image", name, replace_image_filesel);
}
-void save_as_image_sima()
+
+static char *filesel_imagetype_string(Image *ima)
+{
+ char *strp, *str= MEM_callocN(14*32, "menu for filesel");
+
+ strp= str;
+ str += sprintf(str, "Save Image as: %%t|");
+ str += sprintf(str, "Targa %%x%d|", R_TARGA);
+ str += sprintf(str, "Targa Raw %%x%d|", R_RAWTGA);
+ str += sprintf(str, "PNG %%x%d|", R_PNG);
+ str += sprintf(str, "BMP %%x%d|", R_BMP);
+ str += sprintf(str, "Jpeg %%x%d|", R_JPEG90);
+ str += sprintf(str, "Iris %%x%d|", R_IRIS);
+ if(G.have_libtiff)
+ str += sprintf(str, "Tiff %%x%d|", R_TIFF);
+ str += sprintf(str, "Radiance HDR %%x%d|", R_RADHDR);
+ str += sprintf(str, "Cineon %%x%d|", R_CINEON);
+ str += sprintf(str, "DPX %%x%d|", R_DPX);
+#ifdef WITH_OPENEXR
+ str += sprintf(str, "OpenEXR %%x%d|", R_OPENEXR);
+ /* saving sequences of multilayer won't work, they copy buffers */
+ if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
+ else str += sprintf(str, "MultiLayer %%x%d|", R_MULTILAYER);
+#endif
+ return strp;
+}
+
+/* always opens fileselect */
+void save_as_image_sima(void)
{
Image *ima = G.sima->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
char name[FILE_MAXDIR+FILE_MAXFILE];
if (ima) {
strcpy(name, ima->name);
- if (ima->ibuf) {
- char str[64];
- save_image_filesel_str(str);
+ if (ibuf) {
+ char *strp;
- /* so it shows an extension in filewindow */
- if(G.scene->r.scemode & R_EXTENSION)
- BKE_add_image_extension(name, G.scene->r.imtype);
+ strp= filesel_imagetype_string(ima);
- activate_fileselect(FILE_SPECIAL, str, name, save_image_filesel);
+ /* cant save multilayer sequence, ima->rr isn't valid for a specific frame */
+ if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
+ G.sima->imtypenr= R_MULTILAYER;
+ else if(ima->type==IMA_TYPE_R_RESULT)
+ G.sima->imtypenr= R_MULTILAYER;
+ else G.sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
+
+ activate_fileselect_menu(FILE_SPECIAL, "Save Image", name, strp, &G.sima->imtypenr, save_image_doit);
}
}
}
-void save_image_sima()
+/* if exists, saves over without fileselect */
+void save_image_sima(void)
{
Image *ima = G.sima->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
char name[FILE_MAXDIR+FILE_MAXFILE];
if (ima) {
strcpy(name, ima->name);
- if (ima->ibuf) {
- if (BLI_exists(ima->ibuf->name))
- save_image_filesel(ima->ibuf->name);
+ if (ibuf) {
+ if (BLI_exists(ibuf->name)) {
+ if(BKE_image_get_renderresult(ima))
+ G.sima->imtypenr= R_MULTILAYER;
+ else
+ G.sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
+
+ save_image_doit(ibuf->name);
+ }
else
save_as_image_sima();
}
}
}
-void reload_image_sima()
+void save_image_sequence_sima(void)
{
- Image *ima = G.sima->image;
-
- if (ima && ima->ibuf && BLI_exists(ima->ibuf->name)) {
- if (ima->packedfile) {
- PackedFile *pf;
- pf = newPackedFile(ima->name);
- if (pf) {
- freePackedFile(ima->packedfile);
- ima->packedfile = pf;
+ ImBuf *ibuf;
+ int tot= 0;
+ char di[FILE_MAX], fi[FILE_MAX];
+
+ if(G.sima->image==NULL)
+ return;
+ if(G.sima->image->source!=IMA_SRC_SEQUENCE)
+ return;
+ if(G.sima->image->type==IMA_TYPE_MULTILAYER) {
+ error("Cannot save Multilayer Sequences");
+ return;
+ }
+
+ /* get total */
+ for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next)
+ if(ibuf->userflags & IB_BITMAPDIRTY)
+ tot++;
+
+ if(tot==0) {
+ notice("No Images have been changed");
+ return;
+ }
+ /* get a filename for menu */
+ for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next)
+ if(ibuf->userflags & IB_BITMAPDIRTY)
+ break;
+
+ BLI_strncpy(di, ibuf->name, FILE_MAX);
+ BLI_splitdirstring(di, fi);
+
+ sprintf(fi, "%d Image(s) will be saved in %s", tot, di);
+ if(okee(fi)) {
+
+ for(ibuf= G.sima->image->ibufs.first; ibuf; ibuf= ibuf->next) {
+ if(ibuf->userflags & IB_BITMAPDIRTY) {
+ if(0 == IMB_saveiff(ibuf, ibuf->name, IB_rect | IB_zbuf | IB_zbuffloat)) {
+ error("Could not write image", ibuf->name);
+ break;
+ }
+ printf("Saved: %s\n", ibuf->name);
+ ibuf->userflags &= ~IB_BITMAPDIRTY;
}
- else
- error("Image not available. Keeping packed image.");
- }
- if (ima->preview) {
- free_image_preview(ima);
}
- free_image_buffers(ima); /* force read again */
- ima->ok= 1;
+ }
+}
+
+void reload_image_sima(void)
+{
+
+ if (G.sima ) {
+ BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_RELOAD);
image_changed(G.sima, 0);
}
@@ -1748,13 +1867,13 @@ void reload_image_sima()
BIF_preview_changed(ID_TE);
}
-void new_image_sima()
+void new_image_sima(void)
{
static int width= 256, height= 256;
static short uvtestgrid=0;
char name[256];
- strcpy(name, "Image");
+ strcpy(name, "Untitled");
add_numbut(0, TEX, "Name:", 0, 255, name, NULL);
add_numbut(1, NUM|INT, "Width:", 1, 5000, &width, NULL);
@@ -1763,7 +1882,7 @@ void new_image_sima()
if (!do_clever_numbuts("New Image", 4, REDRAW))
return;
- G.sima->image= new_image(width, height, name, uvtestgrid);
+ G.sima->image= BKE_add_image_size(width, height, name, uvtestgrid);
image_changed(G.sima, 0);
BIF_undo_push("Add image");
@@ -1777,28 +1896,80 @@ void pack_image_sima()
Image *ima = G.sima->image;
if (ima) {
- if (ima->packedfile) {
- if (G.fileflags & G_AUTOPACK)
- if (okee("Disable AutoPack?"))
- G.fileflags &= ~G_AUTOPACK;
-
- if ((G.fileflags & G_AUTOPACK) == 0) {
- unpackImage(ima, PF_ASK);
- BIF_undo_push("Unpack image");
- }
- }
- else {
- if (ima->ibuf && (ima->ibuf->userflags & IB_BITMAPDIRTY)) {
- error("Can't pack painted image. Save the painted image first.");
+ if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) {
+ if (ima->packedfile) {
+ if (G.fileflags & G_AUTOPACK)
+ if (okee("Disable AutoPack?"))
+ G.fileflags &= ~G_AUTOPACK;
+
+ if ((G.fileflags & G_AUTOPACK) == 0) {
+ unpackImage(ima, PF_ASK);
+ BIF_undo_push("Unpack image");
+ }
}
else {
- ima->packedfile = newPackedFile(ima->name);
- BIF_undo_push("Pack image");
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+ if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
+ error("Can't pack painted image. Save image or use Repack as PNG.");
+ }
+ else {
+ ima->packedfile = newPackedFile(ima->name);
+ BIF_undo_push("Pack image");
+ }
}
+
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWHEADERS, 0);
}
+ }
+}
+
+
- allqueue(REDRAWBUTSSHADING, 0);
- allqueue(REDRAWHEADERS, 0);
+/* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */
+void BIF_image_update_frame(void)
+{
+ Tex *tex;
+
+ /* texture users */
+ for(tex= G.main->tex.first; tex; tex= tex->id.next) {
+ if(tex->type==TEX_IMAGE && tex->ima)
+ if(ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
+ if(tex->iuser.flag & IMA_ANIM_ALWAYS)
+ BKE_image_user_calc_imanr(&tex->iuser, G.scene->r.cfra, 0);
+
+ }
+ /* image window, compo node users */
+ if(G.curscreen) {
+ ScrArea *sa;
+ for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
+ if(sa->spacetype==SPACE_VIEW3D) {
+ View3D *v3d= sa->spacedata.first;
+ if(v3d->bgpic)
+ if(v3d->bgpic->iuser.flag & IMA_ANIM_ALWAYS)
+ BKE_image_user_calc_imanr(&v3d->bgpic->iuser, G.scene->r.cfra, 0);
+ }
+ else if(sa->spacetype==SPACE_IMAGE) {
+ SpaceImage *sima= sa->spacedata.first;
+ if(sima->iuser.flag & IMA_ANIM_ALWAYS)
+ BKE_image_user_calc_imanr(&sima->iuser, G.scene->r.cfra, 0);
+ }
+ else if(sa->spacetype==SPACE_NODE) {
+ SpaceNode *snode= sa->spacedata.first;
+ if(snode->treetype==NTREE_COMPOSIT) {
+ bNode *node;
+ for(node= snode->nodetree->nodes.first; node; node= node->next) {
+ if(node->id && node->type==CMP_NODE_IMAGE) {
+ Image *ima= (Image *)node->id;
+ ImageUser *iuser= node->storage;
+ if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
+ if(iuser->flag & IMA_ANIM_ALWAYS)
+ BKE_image_user_calc_imanr(iuser, G.scene->r.cfra, 0);
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/src/edittime.c b/source/blender/src/edittime.c
index 0a000d65419..990bcd72ecf 100644
--- a/source/blender/src/edittime.c
+++ b/source/blender/src/edittime.c
@@ -718,6 +718,9 @@ static void timeline_force_draw(short val)
else if(sa->spacetype==SPACE_BUTS) {
if(val & TIME_ALL_BUTS_WIN) dodraw= 1;
}
+ else if(sa->spacetype==SPACE_IMAGE) {
+ if (val & TIME_ALL_IMAGE_WIN) dodraw = 1;
+ }
else if(sa->spacetype==SPACE_SEQ) {
if (val & TIME_SEQ) dodraw = 1;
}
diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c
index bcee676ae90..19c35580ff0 100644
--- a/source/blender/src/filesel.c
+++ b/source/blender/src/filesel.c
@@ -164,7 +164,7 @@ static rcti scrollrct, textrct, bar;
static int filebuty1, filebuty2, page_ofs, collumwidth, selecting=0;
static int filetoname= 0;
static float pixels_to_ofs;
-static char otherdir[FILE_MAXDIR+FILE_MAXFILE];
+static char otherdir[FILE_MAX];
static ScrArea *otherarea;
/* FSMENU HANDLING */
@@ -441,13 +441,13 @@ static int compare_extension(const void *a1, const void *a2) {
}
/* **************************************** */
-
-void clear_global_filesel_vars()
+static int filesel_has_func(SpaceFile *sfile)
{
- selecting= 0;
+ if(sfile->returnfunc || sfile->returnfunc_event || sfile->returnfunc_args)
+ return 1;
+ return 0;
}
-
void filesel_statistics(SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen)
{
double len;
@@ -497,7 +497,7 @@ void test_flags_file(SpaceFile *sfile)
file->flags |= BLENDERFILE;
if(sfile->type==FILE_LOADLIB) {
- char name[FILE_MAXDIR+FILE_MAXFILE];
+ char name[FILE_MAX];
BLI_strncpy(name, sfile->dir, sizeof(name));
strcat(name, file->relname);
@@ -614,7 +614,7 @@ void sort_filelist(SpaceFile *sfile)
void read_dir(SpaceFile *sfile)
{
int num, len;
- char wdir[FILE_MAXDIR+FILE_MAXFILE];
+ char wdir[FILE_MAX];
/* sfile->act is used for example in databrowse: double names of library objects */
sfile->act= -1;
@@ -675,7 +675,7 @@ void freefilelist(SpaceFile *sfile)
static void split_sfile(SpaceFile *sfile, char *s1)
{
- char string[FILE_MAXDIR+FILE_MAXFILE], dir[FILE_MAXDIR+FILE_MAXFILE], file[FILE_MAXDIR+FILE_MAXFILE];
+ char string[FILE_MAX], dir[FILE_MAX], file[FILE_MAX];
BLI_strncpy(string, s1, sizeof(string));
@@ -699,7 +699,7 @@ void parent(SpaceFile *sfile)
char *dir;
/* if databrowse: no parent */
- if(sfile->type==FILE_MAIN && sfile->returnfunc) return;
+ if(sfile->type==FILE_MAIN && filesel_has_func(sfile)) return;
dir= sfile->dir;
@@ -1135,7 +1135,7 @@ static char *library_string(void)
int nr=0, tot= BLI_countlist(&G.main->library);
if(tot==0) return NULL;
- str= MEM_callocN(tot*(FILE_MAXDIR+FILE_MAXFILE), "filesel lib menu");
+ str= MEM_callocN(tot*(FILE_MAX), "filesel lib menu");
for(tot=0, lib= G.main->library.first; lib; lib= lib->id.next, nr++) {
tot+= sprintf(str+tot, "%s %%x%d|", lib->name+2, nr);
@@ -1181,7 +1181,8 @@ void drawfilespace(ScrArea *sa, void *spacedata)
sprintf(name, "win %d", sa->win);
block= uiNewBlock(&sa->uiblocks, name, UI_EMBOSS, UI_HELV, sa->win);
- uiSetButLock( sfile->type==FILE_MAIN && sfile->returnfunc, NULL);
+ /* browse 1 datablock */
+ uiSetButLock( sfile->type==FILE_MAIN && filesel_has_func(sfile), NULL);
/* space available for load/save buttons? */
loadbutton= MAX2(80, 20+BMF_GetStringWidth(G.font, sfile->title));
@@ -1300,10 +1301,15 @@ static void do_filescrollwheel(SpaceFile *sfile, int move)
}
}
-void activate_fileselect(int type, char *title, char *file, void (*func)(char *))
+/* the complete call; pulldown menu, and three callback types */
+static void activate_fileselect_(int type, char *title, char *file, short *menup, char *pupmenu,
+ void (*func)(char *),
+ void (*func_event)(unsigned short),
+ void (*func_args)(char *, void *arg1, void *arg2),
+ void *arg1, void *arg2)
{
SpaceFile *sfile;
- char group[24], name[FILE_MAXDIR+FILE_MAXFILE], temp[FILE_MAXDIR+FILE_MAXFILE];
+ char group[24], name[FILE_MAX], temp[FILE_MAX];
if(curarea==0) return;
if(curarea->win==0) return;
@@ -1318,10 +1324,21 @@ void activate_fileselect(int type, char *title, char *file, void (*func)(char *)
BLI_strncpy(name, file, sizeof(name));
sfile= curarea->spacedata.first;
- /* sfile wants a (*)(short), but get (*)(char*) */
+
sfile->returnfunc= func;
+ sfile->returnfunc_event= func_event;
+ sfile->returnfunc_args= func_args;
+ sfile->arg1= arg1;
+ sfile->arg2= arg2;
+
sfile->type= type;
sfile->ofs= 0;
+
+ if(sfile->pupmenu)
+ MEM_freeN(sfile->pupmenu);
+ sfile->pupmenu= pupmenu;
+ sfile->menup= menup;
+
/* sfile->act is used for databrowse: double names of library objects */
sfile->act= -1;
@@ -1372,12 +1389,28 @@ void activate_fileselect(int type, char *title, char *file, void (*func)(char *)
filetoname= 1;
}
+void activate_fileselect(int type, char *title, char *file, void (*func)(char *))
+{
+ activate_fileselect_(type, title, file, NULL, NULL, func, NULL, NULL, NULL, NULL);
+}
+
+void activate_fileselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *))
+{
+ activate_fileselect_(type, title, file, menup, pupmenu, func, NULL, NULL, NULL, NULL);
+}
+
+void activate_fileselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2)
+{
+ activate_fileselect_(type, title, file, NULL, NULL, NULL, NULL, func, arg1, arg2);
+}
+
+
void activate_imageselect(int type, char *title, char *file, void (*func)(char *))
{
SpaceImaSel *simasel;
- char dir[FILE_MAXDIR+FILE_MAXFILE], name[FILE_MAXDIR+FILE_MAXFILE];
+ char dir[FILE_MAX], name[FILE_MAX];
- if(curarea==0) return;
+ if(curarea==NULL) return;
if(curarea->win==0) return;
newspace(curarea, SPACE_IMASEL);
@@ -1420,19 +1453,47 @@ void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *me
if(id) BLI_strncpy(str, id->name, sizeof(str));
else return;
- activate_fileselect(FILE_MAIN, "SELECT DATABLOCK", str, (void (*) (char*))func);
+ activate_fileselect_(FILE_MAIN, "SELECT DATABLOCK", str, menup, NULL, NULL, func, NULL, NULL, NULL);
sfile= curarea->spacedata.first;
sfile->retval= retval;
sfile->ipotype= fromcode;
- sfile->menup= menup;
}
-void filesel_prevspace()
+void activate_databrowse_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2)
{
+ ListBase *lb;
SpaceFile *sfile;
+ char str[32];
+
+ if(id==NULL) {
+ lb= wich_libbase(G.main, idcode);
+ id= lb->first;
+ }
+
+ if(id) BLI_strncpy(str, id->name, sizeof(str));
+ else return;
+
+ activate_fileselect_(FILE_MAIN, "SELECT DATABLOCK", str, menup, NULL, NULL, NULL, func, arg1, arg2);
sfile= curarea->spacedata.first;
+ sfile->ipotype= fromcode;
+}
+
+void filesel_prevspace()
+{
+ SpaceFile *sfile= curarea->spacedata.first;
+
+ /* cleanup */
+ if(sfile->spacetype==SPACE_FILE) {
+ if(sfile->menup)
+ sfile->menup= NULL;
+ if(sfile->pupmenu) {
+ MEM_freeN(sfile->pupmenu);
+ sfile->pupmenu= NULL;
+ }
+ }
+
if(sfile->next) {
BLI_remlink(&curarea->spacedata, sfile);
@@ -1527,11 +1588,11 @@ void free_filesel_spec(char *dir)
}
}
-
+/* NOTE: this is called for file read, after the execfunc no UI memory is valid! */
static void filesel_execute(SpaceFile *sfile)
{
struct direntry *files;
- char name[FILE_MAXDIR+FILE_MAXFILE];
+ char name[FILE_MAX];
int a;
filesel_prevspace();
@@ -1548,7 +1609,7 @@ static void filesel_execute(SpaceFile *sfile)
BIF_undo_push("Append from file");
allqueue(REDRAWALL, 1);
}
- else if(sfile->returnfunc) {
+ else if(filesel_has_func(sfile)) {
fsmenu_insert_entry(sfile->dir, 1);
if(sfile->type==FILE_MAIN) { /* DATABROWSE */
@@ -1593,7 +1654,10 @@ static void filesel_execute(SpaceFile *sfile)
}
}
}
- sfile->returnfunc((char*) (long)sfile->retval);
+ if(sfile->returnfunc_event)
+ sfile->returnfunc_event(sfile->retval);
+ else if(sfile->returnfunc_args)
+ sfile->returnfunc_args(NULL, sfile->arg1, sfile->arg2);
}
else {
if(strncmp(sfile->title, "Save", 4)==0) free_filesel_spec(sfile->dir);
@@ -1604,22 +1668,27 @@ static void filesel_execute(SpaceFile *sfile)
if(sfile->flag & FILE_STRINGCODE) {
if (!G.relbase_valid) {
- okee("You have to save the .blend file before using relative paths! Using absolute path instead.");
- sfile->flag &= ~FILE_STRINGCODE;
+ /* skip save */
+ if(strncmp(sfile->title, "Save", 4)) {
+ okee("You have to save the .blend file before using relative paths! Using absolute path instead.");
+ sfile->flag &= ~FILE_STRINGCODE;
+ }
}
else {
BLI_makestringcode(G.sce, name);
}
}
-
- sfile->returnfunc(name);
+ if(sfile->returnfunc)
+ sfile->returnfunc(name);
+ else if(sfile->returnfunc_args)
+ sfile->returnfunc_args(name, sfile->arg1, sfile->arg2);
}
}
}
static void do_filesel_buttons(short event, SpaceFile *sfile)
{
- char butname[FILE_MAXDIR+FILE_MAXFILE];
+ char butname[FILE_MAX];
if (event == B_FS_FILENAME) {
if (strchr(sfile->file, '*') || strchr(sfile->file, '?') || strchr(sfile->file, '[')) {
@@ -1864,7 +1933,7 @@ static void fs_fake_users(SpaceFile *sfile)
int a;
/* only for F4 DATABROWSE */
- if(sfile->returnfunc) return;
+ if(filesel_has_func(sfile)) return;
for(a=0; a<sfile->totfile; a++) {
if(sfile->filelist[a].flags & ACTIVE) {
@@ -1907,7 +1976,7 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
SpaceFile *sfile;
int act, do_draw= 0, i, test, ret = 0;
short qual, mval[2];
- char str[FILE_MAXDIR+FILE_MAXFILE+12];
+ char str[FILE_MAX+12];
sfile= curarea->spacedata.first;
if(sfile==0) return;
@@ -2297,7 +2366,7 @@ static int is_a_library(SpaceFile *sfile, char *dir, char *group)
static void do_library_append(SpaceFile *sfile)
{
Library *lib;
- char dir[FILE_MAXDIR+FILE_MAXFILE], group[32];
+ char dir[FILE_MAX], group[32];
if ( is_a_library(sfile, dir, group)==0 ) {
error("Not a library");
@@ -2344,8 +2413,8 @@ static void library_to_filelist(SpaceFile *sfile)
{
LinkNode *l, *names;
int ok, i, nnames, idcode;
- char filename[FILE_MAXDIR+FILE_MAXFILE];
- char dir[FILE_MAXDIR+FILE_MAXFILE], group[24];
+ char filename[FILE_MAX];
+ char dir[FILE_MAX], group[24];
/* name test */
ok= is_a_library(sfile, dir, group);
@@ -2420,7 +2489,7 @@ static void filesel_select_objects(SpaceFile *sfile)
int a;
/* only when F4 DATABROWSE */
- if(sfile->returnfunc) return;
+ if(filesel_has_func(sfile)) return;
if( strcmp(sfile->dir, "Object/")==0 ) {
for(a=0; a<sfile->totfile; a++) {
@@ -2462,7 +2531,7 @@ static void active_file_object(SpaceFile *sfile)
Object *ob;
/* only when F4 DATABROWSE */
- if(sfile->returnfunc) return;
+ if(filesel_has_func(sfile)) return;
if( strcmp(sfile->dir, "Object/")==0 ) {
if(sfile->act >= 0) {
@@ -2551,7 +2620,7 @@ void main_to_filelist(SpaceFile *sfile)
id= lb->first;
sfile->totfile= 0;
while(id) {
- if(sfile->returnfunc && idcode==ID_IP) {
+ if(filesel_has_func(sfile) && idcode==ID_IP) {
if(sfile->ipotype== ((Ipo *)id)->blocktype) sfile->totfile++;
}
else if (hide==0 || id->name[2] != '.')
@@ -2560,12 +2629,12 @@ void main_to_filelist(SpaceFile *sfile)
id= id->next;
}
- if(sfile->returnfunc==0) sfile->totfile+= 2;
+ if(!filesel_has_func(sfile)) sfile->totfile+= 2;
sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry));
files= sfile->filelist;
- if(sfile->returnfunc==0) {
+ if(!filesel_has_func(sfile)) {
memset( &(sfile->filelist[0]), 0 , sizeof(struct direntry));
sfile->filelist[0].relname= BLI_strdup(".");
sfile->filelist[0].type |= S_IFDIR;
@@ -2582,7 +2651,7 @@ void main_to_filelist(SpaceFile *sfile)
while(id) {
ok= 0;
- if(sfile->returnfunc && idcode==ID_IP) {
+ if(filesel_has_func(sfile) && idcode==ID_IP) {
if(sfile->ipotype== ((Ipo *)id)->blocktype) ok= 1;
}
else ok= 1;
@@ -2594,14 +2663,14 @@ void main_to_filelist(SpaceFile *sfile)
if(id->lib==NULL)
files->relname= BLI_strdup(id->name+2);
else {
- char tmp[FILE_MAXDIR+FILE_MAXFILE], fi[FILE_MAXFILE];
- BLI_strncpy(tmp, id->lib->name, FILE_MAXDIR+FILE_MAXFILE);
+ char tmp[FILE_MAX], fi[FILE_MAXFILE];
+ BLI_strncpy(tmp, id->lib->name, FILE_MAX);
BLI_splitdirstring(tmp, fi);
files->relname= MEM_mallocN(FILE_MAXFILE+32, "filename for lib");
sprintf(files->relname, "%s / %s", fi, id->name+2);
}
- if(sfile->returnfunc==0) { /* F4 DATA BROWSE */
+ if(!filesel_has_func(sfile)) { /* F4 DATA BROWSE */
if(idcode==ID_OB) {
if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE;
}
@@ -2646,7 +2715,7 @@ void main_to_filelist(SpaceFile *sfile)
if( strcmp(sfile->file, sfile->filelist[a].relname)==0) {
sfile->ofs= a-( sfile->collums*(curarea->winy-FILESELHEAD-10)/(2*FILESEL_DY));
filetoname= 0;
- if(sfile->returnfunc) sfile->filelist[a].flags |= ACTIVE;
+ if(filesel_has_func(sfile)) sfile->filelist[a].flags |= ACTIVE;
}
}
}
@@ -2656,9 +2725,9 @@ void main_to_filelist(SpaceFile *sfile)
void clever_numbuts_filesel()
{
SpaceFile *sfile;
- char orgname[FILE_MAXDIR+FILE_MAXFILE+12];
- char filename[FILE_MAXDIR+FILE_MAXFILE+12];
- char newname[FILE_MAXDIR+FILE_MAXFILE+12];
+ char orgname[FILE_MAX+12];
+ char filename[FILE_MAX+12];
+ char newname[FILE_MAX+12];
int test;
int len;
diff --git a/source/blender/src/header_filesel.c b/source/blender/src/header_filesel.c
index 4e7c94e7181..189cf8dab17 100644
--- a/source/blender/src/header_filesel.c
+++ b/source/blender/src/header_filesel.c
@@ -127,6 +127,10 @@ void file_buttons(void)
xcotitle= xco;
xco+= BIF_GetStringWidth(G.font, sfile->title, (U.transopts & USER_TR_BUTTONS));
+ if(sfile->pupmenu && sfile->menup) {
+ uiDefButS(block, MENU, B_NOP, sfile->pupmenu, xco+10,0,90,20, sfile->menup, 0, 0, 0, 0, "");
+ xco+= 100;
+ }
uiBlockBeginAlign(block);
uiDefIconButBitS(block, ICONTOG, FILE_SHOWSHORT, B_SORTFILELIST, ICON_LONGDISPLAY,xco+=XIC,0,XIC,YIC, &sfile->flag, 0, 0, 0, 0, "Toggles long info");
uiDefIconButBitS(block, TOG, FILE_HIDE_DOT, B_RELOADDIR, ICON_GHOST,xco+=XIC,0,XIC,YIC, &sfile->flag, 0, 0, 0, 0, "Hides dot files");
diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c
index 5e162b9a22e..d1bfcdbe125 100644
--- a/source/blender/src/header_image.c
+++ b/source/blender/src/header_image.c
@@ -42,21 +42,28 @@
#include <config.h>
#endif
+#include "DNA_brush_types.h"
#include "DNA_ID.h"
#include "DNA_image_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
+#include "BLI_blenlib.h"
+
#include "BDR_drawmesh.h"
#include "BDR_unwrapper.h"
#include "BKE_brush.h"
+#include "BKE_colortools.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
+#include "BKE_utildefines.h"
+#include "BIF_butspace.h"
#include "BIF_drawimage.h"
#include "BIF_editsima.h"
#include "BIF_interface.h"
@@ -64,26 +71,38 @@
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_transform.h"
+#include "BIF_toolbox.h"
+#include "BSE_drawview.h"
#include "BSE_filesel.h"
#include "BSE_headerbuttons.h"
+#include "BSE_trans_types.h"
#include "BPY_extern.h"
#include "BPY_menus.h"
#include "IMB_imbuf_types.h"
-#include "BSE_trans_types.h"
+
+#include "RE_pipeline.h"
#include "blendef.h"
+#include "butspace.h"
#include "mydevice.h"
void do_image_buttons(unsigned short event)
{
+ ToolSettings *settings= G.scene->toolsettings;
ID *id, *idtest;
int nr;
if(curarea->win==0) return;
+ if(event<=100) {
+ if(event<=50) do_global_buttons2(event);
+ else do_global_buttons(event);
+ return;
+ }
+
switch(event) {
case B_SIMAGEHOME:
image_home();
@@ -100,21 +119,15 @@ void do_image_buttons(unsigned short event)
nr= 1;
id= (ID *)G.sima->image;
- idtest= G.main->image.first;
- while(idtest) {
- if(nr==G.sima->imanr) {
- break;
- }
- nr++;
- idtest= idtest->next;
- }
- if(idtest==0) { /* no new */
+ idtest= BLI_findlink(&G.main->image, G.sima->imanr-1);
+ if(idtest==NULL) { /* no new */
return;
}
if(idtest!=id) {
G.sima->image= (Image *)idtest;
if(idtest->us==0) idtest->us= 1;
+ BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
allqueue(REDRAWIMAGE, 0);
}
/* also when image is the same: assign! 0==no tileflag: */
@@ -128,10 +141,15 @@ void do_image_buttons(unsigned short event)
make_repbind(G.sima->image);
image_changed(G.sima, 1);
}
+ /* XXX might be another event needed for this? */
+ if(G.sima->image)
+ if(ELEM(G.sima->image->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
+ if(G.sima->iuser.flag & IMA_ANIM_ALWAYS)
+ BKE_image_user_calc_imanr(&G.sima->iuser, G.scene->r.cfra, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIMAGE, 0);
break;
-
+
case B_SIMAGEDRAW1:
image_changed(G.sima, 2); /* 2: only tileflag */
allqueue(REDRAWVIEW3D, 0);
@@ -150,6 +168,11 @@ void do_image_buttons(unsigned short event)
pack_image_sima();
break;
+ case B_SIMA_REPACK:
+ BKE_image_memorypack(G.sima->image);
+ allqueue(REDRAWIMAGE, 0);
+ break;
+
case B_SIMA_USE_ALPHA:
G.sima->flag &= ~(SI_SHOW_ALPHA|SI_SHOW_ZBUF);
scrarea_queue_winredraw(curarea);
@@ -165,6 +188,157 @@ void do_image_buttons(unsigned short event)
scrarea_queue_winredraw(curarea);
scrarea_queue_headredraw(curarea);
break;
+ case B_SIMARELOAD:
+ reload_image_sima();
+ break;
+ case B_SIMAGELOAD:
+ open_image_sima(0);
+ break;
+ case B_SIMANAME:
+ if(G.sima->image) {
+ Image *ima;
+ char str[FILE_MAXDIR+FILE_MAXFILE];
+
+ /* name in ima has been changed by button! */
+ BLI_strncpy(str, G.sima->image->name, sizeof(str));
+ ima= BKE_add_image_file(str);
+ if(ima) {
+
+ G.sima->image= ima;
+
+ BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
+ image_changed(G.sima, 0);
+
+ }
+ BIF_undo_push("Load image");
+ allqueue(REDRAWIMAGE, 0);
+ }
+ break;
+ case B_SIMAMULTI:
+ if(G.sima && G.sima->image) {
+ BKE_image_multilayer_index(G.sima->image->rr, &G.sima->iuser);
+ allqueue(REDRAWIMAGE, 0);
+ }
+ break;
+ case B_TRANS_IMAGE:
+ image_editvertex_buts(NULL);
+ break;
+
+ case B_TWINANIM:
+ {
+ Image *ima;
+ int nr;
+
+ ima = G.sima->image;
+ if (ima) {
+ if(ima->flag & IMA_TWINANIM) {
+ nr= ima->xrep*ima->yrep;
+ if(ima->twsta>=nr) ima->twsta= 1;
+ if(ima->twend>=nr) ima->twend= nr-1;
+ if(ima->twsta>ima->twend) ima->twsta= 1;
+ allqueue(REDRAWIMAGE, 0);
+ }
+ }
+ break;
+ }
+ case B_SIMACLONEBROWSE:
+ if (settings->imapaint.brush)
+ if (brush_clone_image_set_nr(settings->imapaint.brush, G.sima->menunr))
+ allqueue(REDRAWIMAGE, 0);
+ break;
+
+ case B_SIMACLONEDELETE:
+ if (settings->imapaint.brush)
+ if (brush_clone_image_delete(settings->imapaint.brush))
+ allqueue(REDRAWIMAGE, 0);
+ break;
+
+ case B_SIMABRUSHCHANGE:
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+
+ case B_SIMACURVES:
+ curvemapping_do_ibuf(G.sima->cumap, BKE_image_get_ibuf(G.sima->image, &G.sima->iuser));
+ allqueue(REDRAWIMAGE, 0);
+ break;
+
+ case B_SIMARANGE:
+ curvemapping_set_black_white(G.sima->cumap, NULL, NULL);
+ curvemapping_do_ibuf(G.sima->cumap, BKE_image_get_ibuf(G.sima->image, &G.sima->iuser));
+ allqueue(REDRAWIMAGE, 0);
+ break;
+
+ case B_SIMABRUSHBROWSE:
+ if(G.sima->menunr==-2) {
+ activate_databrowse((ID*)settings->imapaint.brush, ID_BR, 0, B_SIMABRUSHBROWSE, &G.sima->menunr, do_global_buttons);
+ break;
+ }
+ else if(G.sima->menunr < 0) break;
+
+ if(brush_set_nr(&settings->imapaint.brush, G.sima->menunr)) {
+ BIF_undo_push("Browse Brush");
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWIMAGE, 0);
+ }
+ break;
+ case B_SIMABRUSHDELETE:
+ if(brush_delete(&settings->imapaint.brush)) {
+ BIF_undo_push("Unlink Brush");
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ break;
+ case B_KEEPDATA:
+ brush_toggle_fake_user(settings->imapaint.brush);
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+ case B_SIMABRUSHLOCAL:
+ if(settings->imapaint.brush && settings->imapaint.brush->id.lib) {
+ if(okee("Make local")) {
+ make_local_brush(settings->imapaint.brush);
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ }
+ break;
+ case B_SIMABTEXBROWSE:
+ if(settings->imapaint.brush) {
+ Brush *brush= settings->imapaint.brush;
+
+ if(G.sima->menunr==-2) {
+ MTex *mtex= brush->mtex[brush->texact];
+ ID *id= (ID*)((mtex)? mtex->tex: NULL);
+ activate_databrowse(id, ID_TE, 0, B_SIMABTEXBROWSE, &G.sima->menunr, do_global_buttons);
+ break;
+ }
+ else if(G.sima->menunr < 0) break;
+
+ if(brush_texture_set_nr(brush, G.sima->menunr)) {
+ BIF_undo_push("Browse Brush Texture");
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWIMAGE, 0);
+ }
+ }
+ break;
+ case B_SIMABTEXDELETE:
+ if(settings->imapaint.brush) {
+ if (brush_texture_delete(settings->imapaint.brush)) {
+ BIF_undo_push("Unlink Brush Texture");
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWIMAGE, 0);
+ }
+ }
+ break;
+ case B_SIMA_PLAY:
+ play_anim(0);
+ break;
+ case B_SIMA_RECORD:
+ imagespace_composite_flipbook(curarea);
+ break;
}
}
@@ -498,11 +672,19 @@ static void do_image_imagemenu(void *arg, int event)
case 8:
save_image_sima();
break;
+ case 9:
+ save_image_sequence_sima();
+ break;
+ case 10:
+ BKE_image_memorypack(G.sima->image);
+ allqueue(REDRAWIMAGE, 0);
+ break;
}
}
static uiBlock *image_imagemenu(void *arg_unused)
{
+ ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
uiBlock *block;
short yco= 0, menuwidth=150;
BPyMenu *pym;
@@ -519,8 +701,10 @@ static uiBlock *image_imagemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reload|Alt R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save As...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+ if(G.sima->image->source==IMA_SRC_SEQUENCE)
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Changed Images", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
if (G.sima->image->packedfile) {
@@ -528,7 +712,13 @@ static uiBlock *image_imagemenu(void *arg_unused)
} else {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Image", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
}
-
+
+ /* only for dirty && specific image types */
+ if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+ if( ELEM(G.sima->image->source, IMA_SRC_FILE, IMA_SRC_GENERATED))
+ if(G.sima->image->type!=IMA_TYPE_MULTILAYER)
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Image as PNG", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=7, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
if(G.sima->flag & SI_DRAWTOOL) {
@@ -877,12 +1067,13 @@ static uiBlock *image_uvsmenu(void *arg_unused)
void image_buttons(void)
{
+ Image *ima= G.sima->image;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
uiBlock *block;
short xco, xmax;
char naam[256], *menuname;
/* This should not be a static var */
static int headerbuttons_packdummy;
- Image *ima= G.sima->image;
headerbuttons_packdummy = 0;
@@ -914,6 +1105,7 @@ void image_buttons(void)
xco+=XIC;
if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
+
/* pull down menus */
uiBlockSetEmboss(block, UI_EMBOSSP);
@@ -927,7 +1119,7 @@ void image_buttons(void)
xco+= xmax;
}
- if (ima && ima->ibuf && (ima->ibuf->userflags & IB_BITMAPDIRTY))
+ if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
menuname= "Image*";
else
menuname= "Image";
@@ -948,29 +1140,57 @@ void image_buttons(void)
xco= std_libbuttons(block, xco, 0, 0, NULL, B_SIMABROWSE, ID_IM, 0, (ID *)ima, 0, &(G.sima->imanr), 0, 0, B_IMAGEDELETE, 0, 0);
if (ima) {
+ RenderResult *rr= BKE_image_get_renderresult(ima);
+
xco+= 8;
- if (ima->packedfile) {
- headerbuttons_packdummy = 1;
+ if(rr) {
+ uiBlockBeginAlign(block);
+ uiblock_layer_pass_buttons(block, rr, &G.sima->iuser, B_REDR, xco, 0, 160);
+ uiBlockEndAlign(block);
+ xco+= 166;
}
- uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
- xco+= XIC+8;
+ if( !ELEM3(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_VIEWER) && ima->ok) {
+ if (ima->packedfile) {
+ headerbuttons_packdummy = 1;
+ }
+ if (ima->packedfile && (ibuf->userflags & IB_BITMAPDIRTY))
+ uiDefIconButBitI(block, TOG, 1, B_SIMA_REPACK, ICON_UGLYPACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Re-Pack this image as PNG");
+ else
+ uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
+
+ xco+= XIC+8;
+ }
+
uiDefIconButBitI(block, TOG, SI_DRAWTOOL, B_SIMAGEPAINTTOOL, ICON_TPAINT_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Enables painting textures on the image with left mouse button");
xco+= XIC+8;
uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOG, SI_USE_ALPHA, B_SIMA_USE_ALPHA, ICON_TRANSP_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws image with alpha");
- xco+= XIC;
- uiDefIconButBitI(block, TOG, SI_SHOW_ALPHA, B_SIMA_SHOW_ALPHA, ICON_DOT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws only alpha");
- xco+= XIC;
- if(ima->ibuf) {
- if(ima->ibuf->zbuf || ima->ibuf->zbuf_float) {
+ if(ibuf==NULL || ibuf->channels==4) {
+ uiDefIconButBitI(block, TOG, SI_USE_ALPHA, B_SIMA_USE_ALPHA, ICON_TRANSP_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws image with alpha");
+ xco+= XIC;
+ uiDefIconButBitI(block, TOG, SI_SHOW_ALPHA, B_SIMA_SHOW_ALPHA, ICON_DOT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws only alpha");
+ xco+= XIC;
+ }
+ if(ibuf) {
+ if(ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels==1)) {
uiDefIconButBitI(block, TOG, SI_SHOW_ZBUF, B_SIMA_SHOW_ZBUF, ICON_SOLID, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws zbuffer values");
xco+= XIC;
}
else G.sima->flag &= ~SI_SHOW_ZBUF; /* no confusing display for non-zbuf images */
}
+ xco+= 8;
+
+ uiBlockBeginAlign(block);
+ if(ima->type==IMA_TYPE_COMPOSITE) {
+ uiDefIconBut(block, BUT, B_SIMA_RECORD, ICON_REC, xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Record Composite");
+ xco+= XIC;
+ }
+ if((ima->type==IMA_TYPE_COMPOSITE) || ELEM(G.sima->image->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ uiDefIconBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Play");
+ xco+= XIC;
+ }
uiBlockEndAlign(block);
xco+= 8;
}
diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c
index d6c217534bb..03eed300520 100644
--- a/source/blender/src/header_info.c
+++ b/source/blender/src/header_info.c
@@ -529,15 +529,16 @@ static void check_packAll()
// first check for dirty images
Image *ima;
- ima = G.main->image.first;
- while (ima) {
- if (ima->ibuf && (ima->ibuf->userflags &= IB_BITMAPDIRTY)) {
- break;
- }
- ima= ima->id.next;
+ for(ima = G.main->image.first; ima; ima= ima->id.next) {
+ if (ima->ibufs.first) { /* XXX FIX */
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ if (ibuf && (ibuf->userflags &= IB_BITMAPDIRTY))
+ break;
}
+ }
- if (ima == 0 || okee("Some images are painted on. These changes will be lost. Continue ?")) {
+ if (ima == NULL || okee("Some images are painted on. These changes will be lost. Continue ?")) {
packAll();
G.fileflags |= G_AUTOPACK;
}
@@ -852,7 +853,7 @@ static void do_info_filemenu(void *arg, int event)
}
break;
case 6: /* save image */
- BIF_save_rendered_image_fs(0);
+ BIF_save_rendered_image_fs();
break;
case 22: /* save runtime */
activate_fileselect(FILE_SPECIAL, "Save Runtime", "", write_runtime_check);
diff --git a/source/blender/src/header_node.c b/source/blender/src/header_node.c
index a873f779b34..f32dbf0e760 100644
--- a/source/blender/src/header_node.c
+++ b/source/blender/src/header_node.c
@@ -490,6 +490,9 @@ static void do_node_nodemenu(void *arg, int event)
case 9: /* show cyclic */
ntreeSolveOrder(snode->edittree);
break;
+ case 10: /* execute */
+ addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
+ break;
}
if(fromlib==-1) error("Can't edit Library Data");
@@ -525,8 +528,10 @@ static uiBlock *node_nodemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- if(snode->treetype==NTREE_COMPOSIT)
+ if(snode->treetype==NTREE_COMPOSIT) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Execute Composite|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Read Saved Render Results|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+ }
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Cyclic Dependencies|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
if(curarea->headertype==HEADERTOP) {
diff --git a/source/blender/src/header_time.c b/source/blender/src/header_time.c
index c018812e38b..968a34d1dbc 100644
--- a/source/blender/src/header_time.c
+++ b/source/blender/src/header_time.c
@@ -154,6 +154,10 @@ static uiBlock *time_redrawmenu(void *arg_unused)
else icon= ICON_CHECKBOX_DEHLT;
uiDefIconTextBut(block, BUTM, 1, icon, "Buttons Windows", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_ALL_BUTS_WIN, "");
+ if(stime->redraws & TIME_ALL_IMAGE_WIN) icon= ICON_CHECKBOX_HLT;
+ else icon= ICON_CHECKBOX_DEHLT;
+ uiDefIconTextBut(block, BUTM, 1, icon, "Image Windows", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_ALL_IMAGE_WIN, "");
+
/* Add sequencer only redraw*/
if(stime->redraws & TIME_SEQ) icon= ICON_CHECKBOX_HLT;
else icon= ICON_CHECKBOX_DEHLT;
diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c
index 1837ae2e384..7b283427492 100644
--- a/source/blender/src/headerbuttons.c
+++ b/source/blender/src/headerbuttons.c
@@ -279,6 +279,8 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
if (lb) {
if( id_code==ID_IP)
IPOnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin, G.sipo->blocktype);
+ else if(browse!=B_SIMABROWSE && id_code==ID_IM )
+ IMAnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin);
else
IDnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin);
}
@@ -411,9 +413,12 @@ static void do_update_for_newframe(int mute, int events)
/* this function applies the changes too */
scene_update_for_newframe(G.scene, screen_view3d_layers()); /* BKE_scene.h */
- if ( (CFRA>1) && (!mute) && (G.scene->audio.flag & AUDIO_SCRUB)) audiostream_scrub( CFRA );
+ if ( (CFRA>1) && (!mute) && (G.scene->audio.flag & AUDIO_SCRUB))
+ audiostream_scrub( CFRA );
+
BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
+ BIF_image_update_frame();
}
void update_for_newframe(void)
@@ -573,7 +578,7 @@ void do_global_buttons(unsigned short event)
ScrArea *sa;
Brush *br;
int nr= 1;
- char buf[FILE_MAXDIR+FILE_MAXFILE];
+ char buf[FILE_MAX];
ob= OBACT;
@@ -1518,8 +1523,8 @@ void do_global_buttons(unsigned short event)
allqueue(REDRAWNLA, 1);
/* name scene also in set PUPmenu */
allqueue(REDRAWBUTSALL, 0);
+ allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWHEADERS, 0);
-
break;
case B_KEEPDATA:
diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c
index 21573ba0a11..3724aaf43a0 100644
--- a/source/blender/src/imagepaint.c
+++ b/source/blender/src/imagepaint.c
@@ -56,6 +56,7 @@
#include "DNA_image_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -65,7 +66,9 @@
#include "BKE_brush.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_mesh.h"
+#include "BKE_node.h"
#include "BKE_utildefines.h"
#include "BIF_mywindow.h"
@@ -74,6 +77,7 @@
#include "BIF_toolbox.h"
#include "BSE_drawipo.h"
+#include "BSE_node.h"
#include "BSE_trans_types.h"
#include "BSE_view.h"
@@ -84,6 +88,7 @@
#include "GHOST_Types.h"
#include "blendef.h"
+#include "butspace.h"
#include "mydevice.h"
/* Defines and Structs */
@@ -109,6 +114,7 @@ typedef struct ImagePaintState {
ImBuf *clonecanvas;
short clonefreefloat;
char *warnpackedfile;
+ char *warnmultifile;
/* texture paint only */
Object *ob;
@@ -132,21 +138,21 @@ typedef struct ImagePaintPartialRedraw {
static ImagePaintUndo imapaintundo = {NULL, NULL, NULL, 0, 0};
static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
-static void init_imagapaint_undo(Image *ima)
+static void init_imagapaint_undo(Image *ima, ImBuf *ibuf)
{
int xt, yt;
imapaintundo.image = ima;
- imapaintundo.xtiles = xt = IMAPAINT_TILE_NUMBER(ima->ibuf->x);
- imapaintundo.ytiles = yt = IMAPAINT_TILE_NUMBER(ima->ibuf->y);
+ imapaintundo.xtiles = xt = IMAPAINT_TILE_NUMBER(ibuf->x);
+ imapaintundo.ytiles = yt = IMAPAINT_TILE_NUMBER(ibuf->y);
imapaintundo.tiles = MEM_callocN(sizeof(void*)*xt*yt, "ImagePaintUndoTiles");
imapaintundo.tilebuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE,
- ima->ibuf->depth, (ima->ibuf->rect_float)? IB_rectfloat: IB_rect, 0);
+ ibuf->depth, (ibuf->rect_float)? IB_rectfloat: IB_rect, 0);
}
-static void imapaint_copy_tile(Image *ima, int tile, int x, int y, int swapundo)
+static void imapaint_copy_tile(ImBuf *ibuf, int tile, int x, int y, int swapundo)
{
- IMB_rectcpy(imapaintundo.tilebuf, ima->ibuf, 0, 0, x*IMAPAINT_TILE_SIZE,
+ IMB_rectcpy(imapaintundo.tilebuf, ibuf, 0, 0, x*IMAPAINT_TILE_SIZE,
y*IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
if (imapaintundo.tilebuf->rect_float)
@@ -155,7 +161,7 @@ static void imapaint_copy_tile(Image *ima, int tile, int x, int y, int swapundo)
SWAP(void*, imapaintundo.tilebuf->rect, imapaintundo.tiles[tile])
if (swapundo)
- IMB_rectcpy(ima->ibuf, imapaintundo.tilebuf, x*IMAPAINT_TILE_SIZE,
+ IMB_rectcpy(ibuf, imapaintundo.tilebuf, x*IMAPAINT_TILE_SIZE,
y*IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
}
@@ -164,11 +170,11 @@ static void imapaint_clear_partial_redraw()
memset(&imapaintpartial, 0, sizeof(imapaintpartial));
}
-static void imapaint_dirty_region(Image *ima, int x, int y, int w, int h)
+static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
{
int srcx= 0, srcy= 0, origx, tile, allocsize;
- IMB_rectclip(ima->ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
+ IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
if (w == 0 || h == 0)
return;
@@ -196,27 +202,29 @@ static void imapaint_dirty_region(Image *ima, int x, int y, int w, int h)
for (x=origx; x <= w; x++) {
if (ima != imapaintundo.image) {
free_imagepaint();
- init_imagapaint_undo(ima);
+ init_imagapaint_undo(ima, ibuf);
}
tile = y*imapaintundo.xtiles + x;
if (!imapaintundo.tiles[tile]) {
- allocsize= (ima->ibuf->rect_float)? sizeof(float): sizeof(char);
+ allocsize= (ibuf->rect_float)? sizeof(float): sizeof(char);
imapaintundo.tiles[tile]= MEM_mapallocN(allocsize*4*
IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE, "ImagePaintUndoTile");
- imapaint_copy_tile(ima, tile, x, y, 0);
+ imapaint_copy_tile(ibuf, tile, x, y, 0);
}
}
}
- ima->ibuf->userflags |= IB_BITMAPDIRTY;
+ ibuf->userflags |= IB_BITMAPDIRTY;
}
-static void imapaint_image_update(Image *image, short texpaint)
+static void imapaint_image_update(Image *image, ImBuf *ibuf, short texpaint)
{
- if(image->ibuf->rect_float)
- imb_freerectImBuf(image->ibuf); /* force recreate of char rect */
-
+ if(ibuf->rect_float)
+ imb_freerectImBuf(ibuf); /* force recreate of char rect */
+ if(ibuf->mipmap[0])
+ imb_freemipmapImBuf(ibuf);
+
/* todo: should set_tpage create ->rect? */
if(texpaint || G.sima->lock) {
int w = imapaintpartial.x2 - imapaintpartial.x1;
@@ -236,6 +244,24 @@ static void imapaint_redraw(int final, int texpaint, Image *image)
allqueue(REDRAWVIEW3D, 0);
}
allqueue(REDRAWHEADERS, 0);
+
+ /* after paint, tag Image or RenderResult nodes changed */
+ if(G.scene->nodetree) {
+ imagepaint_composite_tags(G.scene->nodetree, image, &G.sima->iuser);
+ }
+ /* signal composite (hurmf, need an allqueue?) */
+ if(G.sima->lock) {
+ ScrArea *sa;
+ for(sa=G.curscreen->areabase.first; sa; sa= sa->next) {
+ if(sa->spacetype==SPACE_NODE) {
+ if(((SpaceNode *)sa->spacedata.first)->treetype==NTREE_COMPOSIT) {
+ addqueue(sa->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
+ break;
+ }
+ }
+ }
+ }
+
}
else if(!texpaint && G.sima->lock)
force_draw_plus(SPACE_VIEW3D, 0);
@@ -245,20 +271,21 @@ static void imapaint_redraw(int final, int texpaint, Image *image)
void imagepaint_undo()
{
- int x, y, tile;
Image *ima= imapaintundo.image;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+ int x, y, tile;
- if (!ima || !ima->ibuf || !(ima->ibuf->rect || ima->ibuf->rect_float))
+ if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
return;
for (tile = 0, y = 0; y < imapaintundo.ytiles; y++)
for (x = 0; x < imapaintundo.xtiles; x++, tile++)
if (imapaintundo.tiles[tile])
- imapaint_copy_tile(ima, tile, x, y, 1);
+ imapaint_copy_tile(ibuf, tile, x, y, 1);
free_realtime_image(ima); /* force OpenGL reload */
- if(ima->ibuf->rect_float)
- imb_freerectImBuf(ima->ibuf); /* force recreate of char rect */
+ if(ibuf->rect_float)
+ imb_freerectImBuf(ibuf); /* force recreate of char rect */
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
@@ -435,7 +462,7 @@ static int imapaint_paint_op(void *state, ImBuf *ibufb, float *lastpos, float *p
clonebuf= imapaint_lift_clone(s->clonecanvas, ibufb, bliftpos);
}
- imapaint_dirty_region(s->image, bpos[0], bpos[1], ibufb->x, ibufb->y);
+ imapaint_dirty_region(s->image, s->canvas, bpos[0], bpos[1], ibufb->x, ibufb->y);
/* blend into canvas */
if(torus)
@@ -479,26 +506,32 @@ static int texpaint_break_stroke(float *prevuv, float *fwuv, float *bkuv, float
static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
{
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+
/* verify that we can paint and set canvas */
- if(ima->packedfile) {
+ if(ima->packedfile && ima->rr) {
s->warnpackedfile = ima->id.name + 2;
return 0;
- }
- else if(!ima || !ima->ibuf || !(ima->ibuf->rect || ima->ibuf->rect_float))
+ }
+ else if(ibuf && ibuf->channels!=4) {
+ s->warnmultifile = ima->id.name + 2;
return 0;
- else if(ima->packedfile)
+ }
+ else if(!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
return 0;
s->image= ima;
- s->canvas= ima->ibuf;
+ s->canvas= ibuf;
/* set clone canvas */
if(s->tool == PAINT_TOOL_CLONE) {
ima= s->brush->clone.image;
- if(!ima || !ima->ibuf || !(ima->ibuf->rect || ima->ibuf->rect_float))
+ ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+
+ if(!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
return 0;
- s->clonecanvas= ima->ibuf;
+ s->clonecanvas= ibuf;
if(s->canvas->rect_float && !s->clonecanvas->rect_float) {
/* temporarily add float rect for cloning */
@@ -520,16 +553,17 @@ static void imapaint_canvas_free(ImagePaintState *s)
static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
{
+ ImBuf *ibuf= BKE_image_get_ibuf(image, &G.sima->iuser);
float pos[2];
- pos[0] = uv[0]*image->ibuf->x;
- pos[1] = uv[1]*image->ibuf->y;
+ pos[0] = uv[0]*ibuf->x;
+ pos[1] = uv[1]*ibuf->y;
- brush_painter_require_imbuf(painter, ((image->ibuf->rect_float)? 1: 0), 0, 0);
+ brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s)) {
if (update)
- imapaint_image_update(image, texpaint);
+ imapaint_image_update(image, ibuf, texpaint);
return 1;
}
else return 0;
@@ -546,8 +580,12 @@ static void imapaint_paint_stroke(ImagePaintState *s, BrushPainter *painter, sho
/* pick new face and image */
if (facesel_face_pick(s->me, mval, &newfaceindex, 0)) {
+ ImBuf *ibuf;
+
newimage = (Image*)((s->me->mtface+newfaceindex)->tpage);
- if(newimage && newimage->ibuf && newimage->ibuf->rect)
+ ibuf= BKE_image_get_ibuf(newimage, &G.sima->iuser);
+
+ if(ibuf && ibuf->rect)
texpaint_pick_uv(s->ob, s->me, newfaceindex, mval, newuv);
else
newimage = NULL;
@@ -641,8 +679,10 @@ void imagepaint_paint(short mousebutton, short texpaint)
s.image = G.sima->image;
if(!imapaint_canvas_set(&s, G.sima->image)) {
+ if(s.warnmultifile)
+ error("Image requires 4 color channels to paint");
if(s.warnpackedfile)
- error("Painting in packed images not supported");
+ error("Packed MultiLayer files cannot be painted");
return;
}
}
@@ -694,9 +734,12 @@ void imagepaint_paint(short mousebutton, short texpaint)
imapaint_redraw(1, texpaint, s.image);
+
if (texpaint) {
- if (s.warnpackedfile)
- error("Painting in packed images is not supported: %s", s.warnpackedfile);
+ if (s.warnmultifile)
+ error("Image requires 4 color channels to paint: %s", s.warnmultifile);
+ if(s.warnpackedfile)
+ error("Packed MultiLayer files cannot be painted %s", s.warnpackedfile);
persp(PERSP_WIN);
}
@@ -708,7 +751,7 @@ void imagepaint_pick(short mousebutton)
Brush *brush= settings->imapaint.brush;
if(brush && (settings->imapaint.tool == PAINT_TOOL_CLONE)) {
- if(brush->clone.image && brush->clone.image->ibuf) {
+ if(brush->clone.image) {
short prevmval[2], mval[2];
float lastmousepos[2], mousepos[2];
diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c
index 13b72739d0d..9eb68578968 100644
--- a/source/blender/src/interface.c
+++ b/source/blender/src/interface.c
@@ -118,8 +118,10 @@
float UIwinmat[4][4];
static int UIlock= 0, UIafterval;
static char *UIlockstr=NULL;
-static void (*UIafterfunc)(void *arg, int event);
-static void *UIafterfunc_arg;
+
+static void (*UIafterfunc_butm)(void *arg, int event);
+static void (*UIafterfunc_but)(void *arg1, void *arg2);
+static void *UIafterfunc_arg1, *UIafterfunc_arg2;
static uiFont UIfont[UI_ARRAY]; // no init needed
uiBut *UIbuttip;
@@ -1481,7 +1483,10 @@ static int ui_do_but_BUT(uiBut *but)
activated= (but->flag & UI_SELECT);
if(activated) {
- uibut_do_func(but);
+ UIafterfunc_but= but->func;
+ UIafterfunc_arg1= but->func_arg1;
+ UIafterfunc_arg2= but->func_arg2;
+ /* no more uibut_do_func(but); this button calls fileselecting windows */
}
but->flag &= ~UI_SELECT;
@@ -2649,8 +2654,8 @@ static int ui_do_but_BUTM(uiBut *but)
{
ui_set_but_val(but, but->min);
- UIafterfunc= but->butm_func;
- UIafterfunc_arg= but->butm_func_arg;
+ UIafterfunc_butm= but->butm_func;
+ UIafterfunc_arg1= but->butm_func_arg;
UIafterval= but->a2;
return but->retval;
@@ -4899,7 +4904,9 @@ int uiDoBlocks(ListBase *lb, int event)
if(event==MOUSEX) return UI_NOTHING;
UIbuttip= NULL;
- UIafterfunc= NULL; /* to prevent infinite loops, this shouldnt be a global! */
+ UIafterfunc_butm= NULL; /* to prevent infinite loops, this shouldnt be a global! */
+ UIafterfunc_but= NULL; /* to prevent infinite loops, this shouldnt be a global! */
+ UIafterfunc_arg1= UIafterfunc_arg2= NULL;
uevent.qual= G.qual;
uevent.event= event;
@@ -5016,11 +5023,16 @@ int uiDoBlocks(ListBase *lb, int event)
/* afterfunc is used for fileloading too, so after this call, the blocks pointers are invalid */
if(retval & UI_RETURN_OK) {
- if(UIafterfunc) {
+ if(UIafterfunc_butm) {
+ mywinset(curarea->win);
+ UIafterfunc_butm(UIafterfunc_arg1, UIafterval);
+ UIafterfunc_butm= NULL;
+ }
+ if(UIafterfunc_but) {
mywinset(curarea->win);
- UIafterfunc(UIafterfunc_arg, UIafterval);
+ UIafterfunc_but(UIafterfunc_arg1, UIafterfunc_arg2);
+ UIafterfunc_but= NULL;
}
- UIafterfunc= NULL;
}
/* tooltip */
diff --git a/source/blender/src/interface_icons.c b/source/blender/src/interface_icons.c
index 3fb6caf15b5..568907c77e7 100644
--- a/source/blender/src/interface_icons.c
+++ b/source/blender/src/interface_icons.c
@@ -699,10 +699,12 @@ static void icon_from_image(Image *img, RenderInfo *ri)
/* new rule: never read images, so icons get created while user works,
not always on first use of a menu */
if(!img->preview) {
- if(img->ibuf==NULL || img->ibuf->rect==NULL) {
+ ImBuf *ibuf;
+ if(img->ok!=IMA_OK_LOADED) {
return;
}
- icon_copy_rect(img->ibuf, ri);
+ ibuf= BKE_image_get_ibuf(img, NULL);
+ icon_copy_rect(ibuf, ri);
/* now copy the created preview to the DNA struct to be saved in file */
img->preview = MEM_callocN(sizeof(PreviewImage), "img_prv");
diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c
index 1a97a3d594f..2d2ea2c8e0c 100644
--- a/source/blender/src/meshtools.c
+++ b/source/blender/src/meshtools.c
@@ -70,6 +70,7 @@ void sort_faces(void);
#include "BKE_depsgraph.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -850,10 +851,13 @@ void objects_bake_render(void)
else {
Image *ima;
/* force OpenGL reload */
- for(ima= G.main->image.first; ima; ima= ima->id.next)
- if(ima->ibuf)
- if(ima->ibuf->userflags & IB_BITMAPDIRTY)
+ for(ima= G.main->image.first; ima; ima= ima->id.next) {
+ if(ima->ok==IMA_OK_LOADED) {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
free_realtime_image(ima);
+ }
+ }
}
allqueue(REDRAWIMAGE, 0);
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c
index a6e0d2ef27e..5113e261fa5 100644
--- a/source/blender/src/previewrender.c
+++ b/source/blender/src/previewrender.c
@@ -269,6 +269,8 @@ static Scene *preview_prepare_scene(RenderInfo *ri, int id_type, ID *id, int pr_
/* set world always back, is used now */
sce->world= pr_main->world.first;
+ sce->r.cfra= G.scene->r.cfra;
+
if(id_type==ID_MA) {
Material *mat= (Material *)id;
diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c
index f6bd1d76524..bba8a9ebb45 100644
--- a/source/blender/src/renderwin.c
+++ b/source/blender/src/renderwin.c
@@ -599,7 +599,7 @@ static void renderwin_handler(Window *win, void *user_data, short evt, short val
mainwindow_make_active();
rw->active= 0;
areawinset(find_biggest_area()->win);
- BIF_save_rendered_image_fs(0);
+ BIF_save_rendered_image_fs();
}
}
else if (evt==F11KEY) {
@@ -1115,17 +1115,20 @@ static void do_render(int anim)
waitcursor(0);
}
+/* called before render, store old render in spare buffer */
static void renderwin_store_spare(void)
{
RenderResult rres;
if(render_win==0 || render_win->storespare==0)
return;
-
- if(render_win->showspare) {
- render_win->showspare= 0;
- window_set_title(render_win->win, renderwin_get_title(1));
- }
+
+ /* only store when it does not show spare */
+ if(render_win->showspare==0)
+ return;
+
+ render_win->showspare= 0;
+ window_set_title(render_win->win, renderwin_get_title(1));
BLI_strncpy(render_win->render_text_spare, render_win->render_text, RW_MAXTEXT);
@@ -1197,6 +1200,14 @@ void BIF_end_render_callbacks(void)
}
}
+void BIF_store_spare(void)
+{
+ if(render_win)
+ renderwin_store_spare();
+ else
+ imagewin_store_spare();
+}
+
/* set up display, render an image or scene */
void BIF_do_render(int anim)
{
@@ -1210,8 +1221,7 @@ void BIF_do_render(int anim)
}
}
- if(render_win && render_win->showspare)
- renderwin_store_spare();
+ BIF_store_spare();
do_render(anim);
@@ -1327,12 +1337,7 @@ void BIF_redraw_render_rect(void)
renderwin_queue_redraw(render_win);
}
else {
- Image *ima = (Image *)find_id("IM", "Render Result");
- if(ima && ima->ibuf) {
- IMB_freeImBuf(ima->ibuf);
- ima->ibuf= NULL;
- allqueue(REDRAWIMAGE, 0);
- }
+ allqueue(REDRAWIMAGE, 0);
}
}
@@ -1340,22 +1345,26 @@ void BIF_swap_render_rects(void)
{
RenderResult rres;
- if (render_win==NULL) return;
-
- render_win->storespare= 1;
- render_win->showspare ^= 1;
+ if(G.displaymode!=R_DISPLAYWIN) {
+ imagewindow_swap_render_rects();
+ }
+ else {
- RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+ render_win->storespare= 1;
+ render_win->showspare ^= 1;
+
+ RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+
+ if(render_win->sparex!=rres.rectx || render_win->sparey!=rres.recty) {
+ if(render_win->rectspare) MEM_freeN(render_win->rectspare);
+ render_win->rectspare= NULL;
+ if(render_win->rectsparef) MEM_freeN(render_win->rectsparef);
+ render_win->rectsparef= NULL;
+ }
- if(render_win->sparex!=rres.rectx || render_win->sparey!=rres.recty) {
- if(render_win->rectspare) MEM_freeN(render_win->rectspare);
- render_win->rectspare= NULL;
- if(render_win->rectsparef) MEM_freeN(render_win->rectsparef);
- render_win->rectsparef= NULL;
+ window_set_title(render_win->win, renderwin_get_title(1));
}
- window_set_title(render_win->win, renderwin_get_title(1));
-
/* redraw */
BIF_redraw_render_rect();
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index af6a5043244..a9de9e01ea8 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -4347,7 +4347,7 @@ static void init_imaselspace(ScrArea *sa)
simasel->firstdir = 0;
simasel->firstfile = 0;
simasel->cmap = 0;
- simasel->returnfunc = 0;
+ simasel->returnfunc = NULL;
simasel->title[0] = 0;
@@ -4589,7 +4589,7 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
/* Events handled always (whether the draw tool is active or not) */
switch (event) {
case UI_BUT_EVENT:
- do_imagebuts(val); /* drawimage.c */
+ do_image_buttons(val); /* header_image.c */
break;
case MIDDLEMOUSE:
if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
@@ -4665,6 +4665,10 @@ static void init_imagespace(ScrArea *sa)
sima->zoom= 1;
sima->blockscale= 0.7;
sima->flag = SI_LOCALSTICKY;
+
+ sima->iuser.ok= 1;
+ sima->iuser.fie_ima= 2;
+ sima->iuser.frames= 100;
}
@@ -5216,14 +5220,14 @@ void newspace(ScrArea *sa, int type)
sfile->type= FILE_UNIX;
}
- sfile->returnfunc= 0;
+ sfile->returnfunc= NULL;
sfile->title[0]= 0;
if(sfile->filelist) test_flags_file(sfile);
}
/* exception: imasel space */
else if(sa->spacetype==SPACE_IMASEL) {
SpaceImaSel *simasel= sa->spacedata.first;
- simasel->returnfunc= 0;
+ simasel->returnfunc= NULL;
simasel->title[0]= 0;
}
else if(sa->spacetype==SPACE_OOPS) {
@@ -5248,6 +5252,8 @@ void freespacelist(ScrArea *sa)
BLO_blendhandle_close(sfile->libfiledata);
if(sfile->filelist)
freefilelist(sfile);
+ if(sfile->pupmenu)
+ MEM_freeN(sfile->pupmenu);
}
else if(sl->spacetype==SPACE_BUTS) {
SpaceButs *buts= (SpaceButs*) sl;
@@ -5266,7 +5272,6 @@ void freespacelist(ScrArea *sa)
else if(sl->spacetype==SPACE_VIEW3D) {
View3D *vd= (View3D*) sl;
if(vd->bgpic) {
- if(vd->bgpic->rect) MEM_freeN(vd->bgpic->rect);
if(vd->bgpic->ima) vd->bgpic->ima->id.us--;
MEM_freeN(vd->bgpic);
}
@@ -5312,6 +5317,10 @@ void freespacelist(ScrArea *sa)
curvemapping_free(sima->cumap);
if(sima->info_str)
MEM_freeN(sima->info_str);
+ if(sima->info_spare)
+ MEM_freeN(sima->info_spare);
+ if(sima->spare)
+ IMB_freeImBuf(sima->spare);
}
else if(sl->spacetype==SPACE_NODE) {
/* SpaceNode *snode= (SpaceNode *)sl; */
@@ -5321,6 +5330,7 @@ void freespacelist(ScrArea *sa)
BLI_freelistN(&sa->spacedata);
}
+/* can be called for area-full, so it should keep interesting stuff */
void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
{
SpaceLink *sl;
@@ -5333,8 +5343,10 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
while(sl) {
if(sl->spacetype==SPACE_FILE) {
SpaceFile *sfile= (SpaceFile*) sl;
- sfile->libfiledata= 0;
- sfile->filelist= 0;
+ sfile->libfiledata= NULL;
+ sfile->filelist= NULL;
+ sfile->pupmenu= NULL;
+ sfile->menup= NULL;
}
else if(sl->spacetype==SPACE_VIEW3D) {
View3D *v3d= (View3D*)sl;
@@ -5351,6 +5363,10 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
else if(sl->spacetype==SPACE_IMASEL) {
check_imasel_copy((SpaceImaSel *) sl);
}
+ else if(sl->spacetype==SPACE_IMAGE) {
+ SpaceImage *sima= (SpaceImage *)sl;
+ sima->spare= NULL;
+ }
else if(sl->spacetype==SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl;
snode->nodetree= NULL;
@@ -5359,6 +5375,8 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
sl= sl->next;
}
+ /* but some things we copy */
+
sl= lb1->first;
while(sl) {
sl->area= newarea;
@@ -5367,6 +5385,10 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
SpaceButs *buts= (SpaceButs *)sl;
buts->ri= NULL;
}
+ else if(sl->spacetype==SPACE_FILE) {
+ SpaceFile *sfile= (SpaceFile*) sl;
+ sfile->menup= NULL;
+ }
else if(sl->spacetype==SPACE_IPO) {
SpaceIpo *si= (SpaceIpo *)sl;
si->editipo= NULL;
@@ -5376,7 +5398,6 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
View3D *vd= (View3D *)sl;
if(vd->bgpic) {
vd->bgpic= MEM_dupallocN(vd->bgpic);
- vd->bgpic->rect= NULL;
if(vd->bgpic->ima) vd->bgpic->ima->id.us++;
}
vd->clipbb= MEM_dupallocN(vd->clipbb);
@@ -5389,6 +5410,8 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
sima->cumap= curvemapping_copy(sima->cumap);
if(sima->info_str)
sima->info_str= MEM_dupallocN(sima->info_str);
+ if(sima->info_spare)
+ sima->info_spare= MEM_dupallocN(sima->info_spare);
}
sl= sl->next;
}
diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c
index f5b9ccf3f81..51c54cf6661 100644
--- a/source/blender/src/toets.c
+++ b/source/blender/src/toets.c
@@ -456,15 +456,12 @@ int blenderqread(unsigned short event, short val)
break;
case F3KEY:
if(G.qual==0) {
- BIF_save_rendered_image_fs(0);
+ BIF_save_rendered_image_fs();
return 0;
}
else if(G.qual & LR_CTRLKEY) {
BIF_screendump(0);
}
- else if(G.qual & LR_SHIFTKEY) {
- BIF_save_rendered_image_fs(1);
- }
break;
case F4KEY:
if(G.qual==LR_SHIFTKEY) {
@@ -473,7 +470,7 @@ int blenderqread(unsigned short event, short val)
ob= OBACT;
if(ob) strcpy(str, ob->id.name);
- activate_fileselect(FILE_MAIN, "Data Select", str, 0);
+ activate_fileselect(FILE_MAIN, "Data Select", str, NULL);
return 0;
}
else if(G.qual==0) {
diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c
index 4601fa77b3a..c9fced04a00 100644
--- a/source/blender/src/toolbox.c
+++ b/source/blender/src/toolbox.c
@@ -74,6 +74,7 @@
#include "BKE_displist.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
@@ -709,9 +710,7 @@ void replace_names_but(void)
strcat(temp, ima->name+len);
BLI_strncpy(ima->name, temp, sizeof(ima->name));
- if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
- ima->ibuf= 0;
- ima->ok= 1;
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
tot++;
}
diff --git a/source/blender/src/verse_object.c b/source/blender/src/verse_object.c
index 2a285d828b9..572849b5a92 100644
--- a/source/blender/src/verse_object.c
+++ b/source/blender/src/verse_object.c
@@ -289,7 +289,7 @@ void b_verse_pop_node(VNode *vnode)
return;
}
- vbitmap->image = (void*)new_image(
+ vbitmap->image = (void*)BKE_add_image_size(
vbitmap->width,
vbitmap->height,
vnode->name,
diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c
index 6d167d858ff..530d0535baa 100644
--- a/source/blender/src/writeimage.c
+++ b/source/blender/src/writeimage.c
@@ -66,17 +66,17 @@ void BIF_save_envmap(EnvMap *env, char *str)
int dx;
/* all interactive stuff is handled in buttons.c */
- if(env->cube[0]==NULL || env->cube[0]->ibuf==NULL) return;
+ if(env->cube[0]==NULL) return;
- dx= env->cube[0]->ibuf->x;
+ dx= env->cube[0]->x;
ibuf= IMB_allocImBuf(3*dx, 2*dx, 24, IB_rect, 0);
- IMB_rectcpy(ibuf, env->cube[0]->ibuf, 0, 0, 0, 0, dx, dx);
- IMB_rectcpy(ibuf, env->cube[1]->ibuf, dx, 0, 0, 0, dx, dx);
- IMB_rectcpy(ibuf, env->cube[2]->ibuf, 2*dx, 0, 0, 0, dx, dx);
- IMB_rectcpy(ibuf, env->cube[3]->ibuf, 0, dx, 0, 0, dx, dx);
- IMB_rectcpy(ibuf, env->cube[4]->ibuf, dx, dx, 0, 0, dx, dx);
- IMB_rectcpy(ibuf, env->cube[5]->ibuf, 2*dx, dx, 0, 0, dx, dx);
+ IMB_rectcpy(ibuf, env->cube[0], 0, 0, 0, 0, dx, dx);
+ IMB_rectcpy(ibuf, env->cube[1], dx, 0, 0, 0, dx, dx);
+ IMB_rectcpy(ibuf, env->cube[2], 2*dx, 0, 0, 0, dx, dx);
+ IMB_rectcpy(ibuf, env->cube[3], 0, dx, 0, 0, dx, dx);
+ IMB_rectcpy(ibuf, env->cube[4], dx, dx, 0, 0, dx, dx);
+ IMB_rectcpy(ibuf, env->cube[5], 2*dx, dx, 0, 0, dx, dx);
BKE_write_ibuf(ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality);
IMB_freeImBuf(ibuf);
@@ -86,12 +86,10 @@ void BIF_save_envmap(EnvMap *env, char *str)
#define FTOCHAR(val) val<=0.0f?255: 255-(val>=255.0f?255: (char)(val))
/* callback for fileselect to save rendered image, renderresult was checked to exist */
-void save_rendered_image_cb_real(char *name, int zbuf, int confirm)
+static void save_rendered_image_cb_real(char *name, int confirm)
{
char str[FILE_MAXDIR+FILE_MAXFILE];
- int pixel, end, overwrite;
- float *pixf = 0;
- char *pixc = 0;
+ int overwrite;
if(BLI_testextensie(name,".blend")) {
error("Wrong filename");
@@ -112,54 +110,37 @@ void save_rendered_image_cb_real(char *name, int zbuf, int confirm)
overwrite = 1;
if(overwrite) {
- RenderResult rres;
- ImBuf *ibuf;
-
- RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
-
- waitcursor(1); /* from screen.c */
-
- ibuf= IMB_allocImBuf(rres.rectx, rres.recty, G.scene->r.planes, 0, 0);
- if (zbuf == 1) {
- if (ibuf->rect ==NULL) imb_addrectImBuf(ibuf);
- if (ibuf->rect_float==NULL) imb_addrectfloatImBuf(ibuf);
-
- ibuf->zbuf_float= rres.rectz;
+ if(G.scene->r.imtype==R_MULTILAYER) {
+ RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name));
+ if(rr)
+ RE_WriteRenderResult(rr, str);
+ }
+ else {
+ RenderResult rres;
+ ImBuf *ibuf;
+
+ RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
- pixc = (char *)ibuf->rect;
- pixf = (float *)ibuf->rect_float;
+ waitcursor(1); /* from screen.c */
- end = ibuf->x * ibuf->y;
- for(pixel = 0; pixel < end; pixel++, pixf+=4, pixc+=4) {
- pixf[0] = pixf[1] = pixf[2] = pixf[3] = 1-rres.rectz[pixel]/100000000000.0;
- pixc[0] = pixc[1] = pixc[2] = pixc[3] = FTOCHAR(rres.rectz[pixel]);
- }
- ibuf->zbuf_float= rres.rectz;
- } else {
+ ibuf= IMB_allocImBuf(rres.rectx, rres.recty, G.scene->r.planes, 0, 0);
ibuf->rect= rres.rect32;
ibuf->rect_float= rres.rectf;
ibuf->zbuf_float= rres.rectz;
+
+ /* float factor for random dither, imbuf takes care of it */
+ ibuf->dither= G.scene->r.dither_intensity;
+
+ BKE_write_ibuf(ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality);
+ IMB_freeImBuf(ibuf); /* imbuf knows rects are not part of ibuf */
}
- /* float factor for random dither, imbuf takes care of it */
- ibuf->dither= G.scene->r.dither_intensity;
-
- BKE_write_ibuf(ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality);
- IMB_freeImBuf(ibuf); /* imbuf knows rects are not part of ibuf */
-
strcpy(G.ima, name);
waitcursor(0);
}
}
-static void save_rendered_image_cb(char *name) {
- save_rendered_image_cb_real(name,0,1);
-}
-
-static void save_rendered_image_zbuf_cb(char *name) {
- save_rendered_image_cb_real(name,1,1);
-}
void save_image_filesel_str(char *str)
{
@@ -203,7 +184,9 @@ void save_image_filesel_str(char *str)
case R_TARGA:
strcpy(str, "Save Targa");
break;
-
+ case R_MULTILAYER:
+ strcpy(str, "Save Multi Layer EXR");
+ break;
/* default we save jpeg, also for all movie formats */
case R_JPEG90:
case R_MOVIE:
@@ -216,8 +199,19 @@ void save_image_filesel_str(char *str)
}
}
-/* calls fileselect if zbuf is set we are rendering the zbuffer */
-void BIF_save_rendered_image_fs(int zbuf)
+static void save_rendered_image_cb(char *name)
+{
+ save_rendered_image_cb_real(name, 1);
+}
+
+/* no fileselect, no confirm */
+void BIF_save_rendered_image(char *name)
+{
+ save_rendered_image_cb_real(name, 0);
+}
+
+/* calls fileselect */
+void BIF_save_rendered_image_fs(void)
{
RenderResult rres;
@@ -225,7 +219,8 @@ void BIF_save_rendered_image_fs(int zbuf)
if(!rres.rectf && !rres.rect32) {
error("No image rendered");
- } else {
+ }
+ else {
char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
if(G.ima[0]==0) {
@@ -235,10 +230,6 @@ void BIF_save_rendered_image_fs(int zbuf)
}
save_image_filesel_str(str);
- if (zbuf) {
- activate_fileselect(FILE_SPECIAL, str, G.ima, save_rendered_image_zbuf_cb);
- return;
- }
activate_fileselect(FILE_SPECIAL, str, G.ima, save_rendered_image_cb);
}
}
diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h
index fa7afdbcbd9..0d794b6755d 100644
--- a/source/blender/yafray/intern/yafray_Render.h
+++ b/source/blender/yafray/intern/yafray_Render.h
@@ -22,7 +22,6 @@ extern "C" {
#include "DNA_world_types.h"
#include "BKE_global.h"
-#include "BKE_image.h"
#include "render_types.h"
/* display_draw() needs render layer info */