OpenEXR: Support reading multipart files with full channel names

The reading code currently assumes that the part name may be for example
"ViewLayer.Combined" and then the channel within the part may be "R". For
example Houdini writes files like this.

However according to the docs the part name should be ignored and the
channel name in each part should be complete like "ViewLayer.Combined.R".
https://openexr.com/en/latest/MultiViewOpenEXR.html

To support both cases we now only prepend the part name if it's not already
there.

Pull Request: https://projects.blender.org/blender/blender/pulls/146650
This commit is contained in:
Brecht Van Lommel
2025-09-22 13:10:39 +02:00
parent 08d95785c5
commit 662dc95a50

View File

@@ -1598,15 +1598,23 @@ static std::vector<MultiViewChannelName> exr_channels_in_multi_part_file(
for (int p = 0; p < file.parts(); p++) {
const ChannelList &c = file.header(p).channels();
std::string part_view;
blender::StringRef part_view;
if (file.header(p).hasView()) {
part_view = file.header(p).view();
}
std::string part_name;
blender::StringRef part_name;
if (file.header(p).hasName()) {
part_name = file.header(p).name();
}
/* Strip part suffix from name. */
if (part_name.endswith("." + part_view)) {
part_name = part_name.drop_known_suffix("." + part_view);
}
else if (part_name.endswith("-" + part_view)) {
part_name = part_name.drop_known_suffix("-" + part_view);
}
for (ChannelList::ConstIterator i = c.begin(); i != c.end(); i++) {
MultiViewChannelName m;
m.name = std::string(i.name());
@@ -1620,8 +1628,9 @@ static std::vector<MultiViewChannelName> exr_channels_in_multi_part_file(
m.view = part_view;
}
/* Prepend part name as potential layer or pass name. */
if (!part_name.empty()) {
/* Prepend part name as potential layer or pass name. According to OpenEXR docs
* this should not be needed, but Houdini writes files like this. */
if (!part_name.is_empty() && !blender::StringRef(m.name).startswith(part_name + ".")) {
m.name = part_name + "." + m.name;
}