Memory saving for large renders:
authorTon Roosendaal <ton@blender.org>
Tue, 14 Mar 2006 21:29:42 +0000 (21:29 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 14 Mar 2006 21:29:42 +0000 (21:29 +0000)
New option "Save Buffers", in first Output panel of renderbuttons, will not
allocate all render buffers, but instead save the rendered tiles to exr.
For each scene rendered, a single exr file then is created.
After rendering, the files get read, and only then the memory allocation is
done.

The exr files are saved in the temp dir (from user settings), and have
names derived from the filename+scene name. That way these buffers remain
relatively unique, and can be re-used later too.

Saving all render-layers and passes in a single file (as F3 command) will
be done later. Also reading back the current muli-layer exr files is not
supported yet (will read black). The purpose is that these files then can
be used as input for the Compositor.

One fun thing I added; after rendering once with this option, close
Blender, and restart it. If you have a Composite set up press 'R' on an
active RenderResult node. This will refresh the node(s) and load the exr,
so you can composite again without a re-render.

source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/makesdna/DNA_scene_types.h
source/blender/render/intern/source/pipeline.c
source/blender/src/buttons_scene.c
source/blender/src/editnode.c

index 4b5cf64cd49effd9e4d46180314bcc4b47c3bd84..6883cc4051db03c37387c8955412fd353fd7bfde 100644 (file)
@@ -429,18 +429,20 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
 {
        ExrHandle *data= (ExrHandle *)handle;
        
-       data->ifile = new InputFile(filename);
-       if(data->ifile) {
-               Box2i dw = data->ifile->header().dataWindow();
-               data->width= *width  = dw.max.x - dw.min.x + 1;
-               data->height= *height = dw.max.y - dw.min.y + 1;
-               
-               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());
-               
-               return 1;
+       if(BLI_exists(filename)) {
+               data->ifile = new InputFile(filename);
+               if(data->ifile) {
+                       Box2i dw = data->ifile->header().dataWindow();
+                       data->width= *width  = dw.max.x - dw.min.x + 1;
+                       data->height= *height = dw.max.y - dw.min.y + 1;
+                       
+                       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());
+                       
+                       return 1;
+               }
        }
        return 0;
 }
index 035dab4a683be9d1b855b87cd98f0c929c8d8cf9..1a9d10c37b41449677a85c2df0a797b274e259e8 100644 (file)
@@ -446,6 +446,8 @@ typedef struct Scene {
 #define R_COMP_CROP                    0x0080
 #define R_FREE_IMAGE           0x0100
 #define R_SINGLE_LAYER         0x0200
+#define R_EXR_TILE_FILE                0x0400
+
 
 /* alphamode */
 #define R_ADDSKY               0
index 14d1321bfa22614af2e2041093f73cc4b973e465..846aa4117aa2945322c9fc29a71b9318f7ebe1bd 100644 (file)
@@ -1224,7 +1224,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
        
        sce->r.cfra= cfra;
        
-       if(G.rt)
+       if(R_EXR_TILE_FILE)
                resc->flag |= R_FILEBUFFER;
        
        /* makes render result etc */
@@ -1464,7 +1464,7 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
                disprect.ymax= winy;
        }
        
-       if(G.rt) {
+       if(R_EXR_TILE_FILE) {
                int partx= winx/scene->r.xparts, party= winy/scene->r.yparts;
                /* stupid exr tiles dont like different sizes */
                if(winx != partx*scene->r.xparts || winy != party*scene->r.xparts) {
index 3de232c69efd7d67c3aee7b5fc307e818619d4ae..8a6dc80068b7f498dbd74f7987bfe3f2402534e6 100644 (file)
@@ -1249,6 +1249,8 @@ static void render_panel_output(void)
                        uiDefButBitS(block, TOG, 1<<(3*b+a), 800,"",    (short)(10+18*a),(short)(10+14*b),16,12, &G.winpos, 0, 0, 0, 0, "Render window placement on screen");
        uiBlockEndAlign(block);
 
+       uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_NOP, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save the tiles for all RenderLayers and used SceneNodes to files, to save memory");
+       
        uiBlockBeginAlign(block);
        uiDefButS(block, ROW, B_REDR, "DispWin",        72, 10, 60, 20, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output to display in a seperate window");
        uiDefButS(block, ROW, B_REDR, "DispView",       134, 10, 60, 20, &G.displaymode, 0.0, (float)R_DISPLAYVIEW, 0, 0, "Sets render output to display in 3D view");
@@ -1264,7 +1266,7 @@ static void render_panel_output(void)
        uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge",   100, 94, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon edge shading");
        uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 170, 94, 140, 20, "Display edge settings");
        uiBlockEndAlign(block);
-
+       
        uiDefButBitS(block, TOG, R_FREE_IMAGE, B_NOP, "Free Tex Images", 170, 68, 140, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Frees all Images used by Textures after each render");
 }
 
index 8cd6a3ac75d6c48337ec91c8111a69877f6bb898..1f363f8b4281ea72315bb83b408c70a5f4bb979c 100644 (file)
@@ -1864,9 +1864,9 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                {
                        bNode *node= editnode_get_active(snode->edittree);
                        if(node && node->type==CMP_NODE_R_RESULT) {
-                               //RE_ReadRenderResult(G.scene, (Scene *)node->id);
-                               //ntreeCompositTagRender(snode->edittree);
-                               //snode_handle_recalc(snode);
+                               RE_ReadRenderResult(G.scene, (Scene *)node->id);
+                               ntreeCompositTagRender(snode->edittree);
+                               snode_handle_recalc(snode);
                        }
                }
                        break;