Index: release/scripts/ui/properties_render.py =================================================================== --- release/scripts/ui/properties_render.py (révision 28498) +++ release/scripts/ui/properties_render.py (copie de travail) @@ -314,7 +314,16 @@ if rd.file_format in ('AVI_JPEG', 'JPEG'): split = layout.split() split.prop(rd, "file_quality", slider=True) + + elif rd.file_format == 'MULTILAYER': + split = layout.split() + col = split.column() + col.label(text="Codec:") + col.prop(rd, "exr_codec", text="") + if wide_ui: + col = split.column() + elif rd.file_format == 'OPEN_EXR': split = layout.split() Index: source/blender/render/intern/source/pipeline.c =================================================================== --- source/blender/render/intern/source/pipeline.c (révision 28498) +++ source/blender/render/intern/source/pipeline.c (copie de travail) @@ -730,13 +730,13 @@ else { offs= 0; } - + /* combined */ if(rlp->rectf) { int a, xstride= 4; for(a=0; aexrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs); + xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs); } /* passes are allocated in sync */ Index: source/blender/imbuf/intern/openexr/openexr_api.cpp =================================================================== --- source/blender/imbuf/intern/openexr/openexr_api.cpp (révision 28498) +++ source/blender/imbuf/intern/openexr/openexr_api.cpp (copie de travail) @@ -449,18 +449,31 @@ openexr_header_compression(&header, compress); /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */ + + header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.52.5")); - header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43 and newer")); - data->ofile = new OutputFile(filename, header); } void IMB_exrtile_begin_write(void *handle, char *filename, int mipmap, int width, int height, int tilex, int tiley) { ExrHandle *data= (ExrHandle *)handle; - Header header (width, height); + Header *header; ExrChannel *echan; + /* open exr specify tiles must allign with top left frame coord but blender + render with tiles alligned to the bottom left. We work around this by saving + the whole area covered by the tyles (the data window) and defining a display + window that cover only the rendered area */ + + int ntx = ceil((float)width/tilex); + int nty = ceil((float)height/tiley); + Box2i dispw(V2i(0,0), V2i(width-1, height-1)); + Box2i dataw(V2i( width -(ntx*tilex) , height -(nty*tiley) ), V2i(ntx*tilex-1, height-1)); + V2f swc( 0, 0); + header = new Header(dispw, dataw, 1.0, swc, 1, RANDOM_Y, RLE_COMPRESSION); + + data->tilex= tilex; data->tiley= tiley; data->width= width; @@ -468,15 +481,17 @@ data->mipmap= mipmap; for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) - header.channels().insert (echan->name, Channel (FLOAT)); + header->channels().insert (echan->name, Channel (FLOAT)); - header.setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL)); - header.lineOrder() = RANDOM_Y; - header.compression() = RLE_COMPRESSION; + header->setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL)); + header->lineOrder() = RANDOM_Y; + header->compression() = RLE_COMPRESSION; - header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43")); - - data->tofile = new TiledOutputFile(filename, header); + header->insert ("BlenderMultiChannel", StringAttribute ("Blender V2.52.5")); + + data->tofile = new TiledOutputFile(filename, *header); + + delete header; } /* read from file */ @@ -487,7 +502,7 @@ if(BLI_exists(filename) && BLI_filepathsize(filename)>32) { /* 32 is arbitrary, but zero length files crashes exr */ data->ifile = new InputFile(filename); if(data->ifile) { - Box2i dw = data->ifile->header().dataWindow(); + Box2i dw = data->ifile->header().displayWindow(); data->width= *width = dw.max.x - dw.min.x + 1; data->height= *height = dw.max.y - dw.min.y + 1; @@ -544,19 +559,32 @@ ExrHandle *data= (ExrHandle *)handle; FrameBuffer frameBuffer; ExrChannel *echan; + float *rect; + int xs, ys; + int x, y; for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { - float *rect= echan->rect - echan->xstride*partx - echan->ystride*party; + /* coordinates for relative tile coordinates, starting from top of tile, + striding left->right, top->bottom */ + rect= echan->rect + (data->tiley-1)*echan->ystride; + xs = echan->xstride*sizeof(float); + ys = -echan->ystride*sizeof(float); + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + xs, ys, //xStride, yStride + 1, 1, 0.0, // xSampling, ySampling, fillValue + true, true) ); // xTileCoords, yTileCoords (use relative tile coords) } data->tofile->setFrameBuffer (frameBuffer); + x = partx/data->tilex; + /* flip tile grid vertically to conform to EXR coordinate system */ + y = ceil((float)data->height/data->tiley) - (party/data->tiley) - 1; + try { - // printf("write tile %d %d\n", partx/data->tilex, party/data->tiley); - data->tofile->writeTile (partx/data->tilex, party/data->tiley, level); + data->tofile->writeTile (x, y, level); } catch (const std::exception &exc) { std::cerr << "OpenEXR-writeTile: ERROR: " << exc.what() << std::endl; @@ -570,9 +598,12 @@ ExrChannel *echan; if(data->channels.first) { - for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) - frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { + float *rect = echan->rect + echan->xstride*(data->height-1)*data->width; + + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)rect, + echan->xstride*sizeof(float), -echan->ystride*sizeof(float))); + } data->ofile->setFrameBuffer (frameBuffer); data->ofile->writePixels (data->height); @@ -587,12 +618,32 @@ ExrHandle *data= (ExrHandle *)handle; FrameBuffer frameBuffer; ExrChannel *echan; + short flip = 0; + /* check if exr was save with previous version of blender which flipped images */ + for (Header::ConstIterator i = data->ifile->header().begin(); i != data->ifile->header().end(); ++i) { + + const Attribute *a = &i.attribute(); + if ( strcmp(i.name(), "BlenderMultiChannel")==0 ) { + + const StringAttribute *ta = dynamic_cast (a); + std::basic_string av = ta->value(); + if ( strcmp(av.c_str(), "Blender V2.43")==0 || strcmp(av.c_str(), "Blender V2.43 and newer")==0 ) + flip = 1; + } + } + + for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { /* no datawindow correction needed */ - if(echan->rect) - frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, + if(echan->rect) { + if(flip) + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + else + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)(echan->rect + echan->xstride*(data->height-1)*data->width), + echan->xstride*sizeof(float), -echan->ystride*sizeof(float))); + } else printf("warning, channel with no rect set %s\n", echan->name); } Index: tools/Blender.py =================================================================== --- tools/Blender.py (révision 28498) +++ tools/Blender.py (copie de travail) @@ -137,7 +137,7 @@ if lenv['WITH_BF_SDL']: libincs += Split(lenv['BF_SDL_LIBPATH']) if lenv['WITH_BF_FFMPEG']: - libincs += Split(lenv['BF_FFMPEG_LIBPATH']) + libincs = Split(lenv['BF_FFMPEG_LIBPATH']) + libincs if lenv['WITH_BF_JACK']: libincs += Split(lenv['BF_JACK_LIBPATH']) if lenv['WITH_BF_SNDFILE']: