-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Save extra AOVs #1865
Save extra AOVs #1865
Conversation
Thanks for the PR! |
Thanks! Small remark: it's spelled AOV for Arbitrary Output Variables, not AVO. Could you fix the commit title please? |
Wooups, I know and still I made the mistake a lot |
31c4abe
to
e5463a4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR.
I am not sure about saving extra AOVs to PNGs and I think the way it is done is not the best one.
I prefer that we remove that and save them as float EXRs only as a first step.
Also, with the changes in the PR, extra AOVs are always saved when saving AOVs even if the user does not want them.
I think we should add a parameter to the frame to allow users to enable / disable saving of the extra AOVs. In most cases, users will not want to save them (by default, we should not save them).
const string extension = boost_file_path.extension().string(); | ||
|
||
// Extra AOVs | ||
for (size_t i = 0, e = aov_images().size(); i < e; ++i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fragment of code is repeated. Refactor into a function in an unnamed namespace if possible,
if not, refactor to a private method of the frame.
@@ -91,8 +91,8 @@ namespace | |||
{ | |||
if (m_params.m_diagnostics) | |||
{ | |||
m_variation_aov_index = frame.create_extra_aov_image("variation"); | |||
m_samples_aov_index = frame.create_extra_aov_image("samples"); | |||
m_variation_aov_index = frame.create_extra_aov_image("variation", PixelFormatHalf); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With these changes, the range and precision of the images used by the adaptive pixel renderer is much lower than before. This is going to affect the results of the adaptive sampling. I think we want to keep them as floats.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chanded the format because the tile_end maps values to colors.
size_t Frame::create_extra_aov_image(const char* name) const | ||
size_t Frame::create_extra_aov_image( | ||
const char* name, | ||
const PixelFormat pixel_format) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I prefer to undo this change and remove the option of saving extra aov images to pngs.
The images in the extra aov images are always non-color images and in my opinion, it doesn't make much sense to save them as pngs.
Thanks for the review @est77, I will commit asap :) |
@@ -646,6 +649,16 @@ namespace | |||
} | |||
else if (extension == ".png") | |||
{ | |||
// Test if the image contains appropriate data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this code anymore. You can remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I forgot that
@@ -720,7 +765,7 @@ bool Frame::write_aov_images(const char* file_path) const | |||
|
|||
bool success = true; | |||
|
|||
if (!aovs().empty()) | |||
if (!aovs().empty() || !aov_images().empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the !aov_images().empty() check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain me why ?
@@ -687,6 +700,38 @@ namespace | |||
|
|||
return true; | |||
} | |||
|
|||
bool write_extra_aovs( | |||
const ImageStack & images, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove space between the types and the '&' and align parameter names vertically.
Thanks for the changes. There is a problem that I missed yesterday. for (size_t i = 0, e = images.size(); i < e; ++i) but many AOVs also create images on the image stack. Maybe the easiest way to avoid saving some images twice is to keep a vector of the image indices created by Frame::create_extra_aov_image and in write_extra_aovs, write only those images. |
Thanks for the review, I will do that :) |
@@ -720,27 +763,34 @@ bool Frame::write_aov_images(const char* file_path) const | |||
|
|||
bool success = true; | |||
|
|||
if (!aovs().empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not check for the size anymore because if I do, I would have to check aovs().empty()
and aov_images().empty()
. Otherwise extra AOVs wouldn't be saved if there isn't any main AOV.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm wrong, there is always an AOV, beauty, right ? @est77
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
beauty is not an AOV in appleseed. There's an image in the frame to store it.
The idea of the check was to avoid computing the directory and other paths if there were no AOVs to save.
I think it is ok to do it outside of the loop now.
|
||
// Images. | ||
unique_ptr<Image> m_image; | ||
unique_ptr<ImageStack> m_aov_images; | ||
AOVContainer m_aovs; | ||
AOVContainer m_internal_aovs; | ||
DenoiserAOV* m_denoiser_aov; | ||
vector<size_t> m_extra_aovs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
align the type and the var member name with the previous lines.
@@ -280,9 +284,12 @@ const AOVContainer& Frame::internal_aovs() const | |||
|
|||
size_t Frame::create_extra_aov_image(const char* name) const | |||
{ | |||
const size_t index = aov_images().get_index(name); | |||
size_t index = aov_images().get_index(name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index can be const. We don't modify it in the method.
|
||
bool write_extra_aovs( | ||
const ImageStack& images, | ||
const vector<size_t>& aov_indices, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
align with the rest of the arguments.
|
||
for (size_t i = 0, e = aov_indices.size(); i < e; ++i) | ||
{ | ||
size_t image_index = aov_indices[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make const
Thanks for the changes! |
Thanks for the review, I'm really sorry for all these align issues. |
Very nice work @oktomus! Appreciated. |
@est77 When merging this, make sure to squash the PR into a single commit, and to remove the individual commit titles from the commit body (which GitHub fills automatically). |
if (!write_image(aov_file_path.c_str(), aov->get_image(), aov)) | ||
success = false; | ||
} | ||
if (impl->m_save_extra_aovs && !aov_images().empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why checking !aov_images().empty()
? Isn't this test redundant?
{ | ||
bool success = true; | ||
|
||
if (extension != ".exr") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is extension
guaranteed to always be a lower case?
const size_t image_index = impl->m_extra_aovs[i]; | ||
assert(image_index < aov_images().size()); | ||
|
||
const Image & image = aov_images().get_image(image_index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove space before &
.
Done! |
We are now able to:
Fix for #1858
I am not sure if you are ok regarding changes on
Frame::create_extra_aov_image
.I haven't been able to test futher with png because I have a linking issue (possible version mismatch) which cause that
pngptr
is null inPNGImageFileWriter::write
.I was also thinking of a different approach:
Create new AVO classes for data images and color images. Is this possible ?