Expand test_equal_images
The `test_equal_images` function has been expanded to supply the generated image in a `Canvas` or a `DataSet` in addition to a `View`. Much of the templating code has been removed from `test_equal_images` and most of the code has moved into the `vtkm_rendering_testing` library.
This commit is contained in:
parent
12e1164179
commit
0fe9300eed
@ -56,3 +56,10 @@ unexpected behavior when multiple versions of a supposed singleton static
|
||||
object exist. In particular, this was causing a failure when the static
|
||||
objects holding testing directories was created by the test translation
|
||||
unit but was then unavailable to `vtkm_rendering_testing`.
|
||||
|
||||
## Expand test_equal_images
|
||||
|
||||
The `test_equal_images` function has been expanded to supply the generated
|
||||
image in a `Canvas` or a `DataSet` in addition to a `View`. Much of the
|
||||
templating code has been removed from `test_equal_images` and most of the
|
||||
code has moved into the `vtkm_rendering_testing` library.
|
||||
|
@ -30,6 +30,7 @@ set(unit_tests
|
||||
|
||||
set(library_sources
|
||||
RenderTest.cxx
|
||||
Testing.cxx
|
||||
)
|
||||
|
||||
vtkm_library(
|
||||
|
166
vtkm/rendering/testing/Testing.cxx
Normal file
166
vtkm/rendering/testing/Testing.cxx
Normal file
@ -0,0 +1,166 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/rendering/testing/Testing.h>
|
||||
|
||||
TestEqualResult test_equal_images(vtkm::rendering::View& view,
|
||||
const std::vector<std::string>& fileNames,
|
||||
const vtkm::IdComponent& averageRadius,
|
||||
const vtkm::IdComponent& pixelShiftRadius,
|
||||
const vtkm::FloatDefault& allowedPixelErrorRatio,
|
||||
const vtkm::FloatDefault& threshold,
|
||||
const bool& writeDiff,
|
||||
const bool& returnOnPass)
|
||||
{
|
||||
view.Paint();
|
||||
return test_equal_images(view.GetCanvas(),
|
||||
fileNames,
|
||||
averageRadius,
|
||||
pixelShiftRadius,
|
||||
allowedPixelErrorRatio,
|
||||
threshold,
|
||||
writeDiff,
|
||||
returnOnPass);
|
||||
}
|
||||
|
||||
TestEqualResult test_equal_images(const vtkm::rendering::Canvas& canvas,
|
||||
const std::vector<std::string>& fileNames,
|
||||
const vtkm::IdComponent& averageRadius,
|
||||
const vtkm::IdComponent& pixelShiftRadius,
|
||||
const vtkm::FloatDefault& allowedPixelErrorRatio,
|
||||
const vtkm::FloatDefault& threshold,
|
||||
const bool& writeDiff,
|
||||
const bool& returnOnPass)
|
||||
{
|
||||
canvas.RefreshColorBuffer();
|
||||
return test_equal_images(canvas.GetDataSet(),
|
||||
fileNames,
|
||||
averageRadius,
|
||||
pixelShiftRadius,
|
||||
allowedPixelErrorRatio,
|
||||
threshold,
|
||||
writeDiff,
|
||||
returnOnPass);
|
||||
}
|
||||
|
||||
TestEqualResult test_equal_images(const vtkm::cont::DataSet& dataset,
|
||||
const std::vector<std::string>& fileNames,
|
||||
const vtkm::IdComponent& averageRadius,
|
||||
const vtkm::IdComponent& pixelShiftRadius,
|
||||
const vtkm::FloatDefault& allowedPixelErrorRatio,
|
||||
const vtkm::FloatDefault& threshold,
|
||||
const bool& writeDiff,
|
||||
const bool& returnOnPass)
|
||||
{
|
||||
vtkm::cont::ScopedRuntimeDeviceTracker runtime(vtkm::cont::DeviceAdapterTagAny{});
|
||||
TestEqualResult testResults;
|
||||
|
||||
if (fileNames.empty())
|
||||
{
|
||||
testResults.PushMessage("No valid image file names were provided");
|
||||
return testResults;
|
||||
}
|
||||
|
||||
const std::string testImageName = vtkm::cont::testing::Testing::WriteDirPath(
|
||||
vtkm::io::PrefixStringToFilename(fileNames[0], "test-"));
|
||||
vtkm::io::WriteImageFile(dataset, testImageName, dataset.GetField(0).GetName());
|
||||
|
||||
std::stringstream dartXML;
|
||||
|
||||
dartXML << "<DartMeasurementFile name=\"TestImage\" type=\"image/png\">";
|
||||
dartXML << testImageName;
|
||||
dartXML << "</DartMeasurementFile>\n";
|
||||
|
||||
for (const auto& fileName : fileNames)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "testing image file: " << fileName);
|
||||
TestEqualResult imageResult;
|
||||
vtkm::cont::DataSet imageDataSet;
|
||||
const std::string testImagePath = vtkm::cont::testing::Testing::RegressionImagePath(fileName);
|
||||
|
||||
try
|
||||
{
|
||||
imageDataSet = vtkm::io::ReadImageFile(testImagePath, "baseline-image");
|
||||
}
|
||||
catch (const vtkm::cont::ErrorExecution& error)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Error, error.GetMessage());
|
||||
imageResult.PushMessage(error.GetMessage());
|
||||
|
||||
const std::string outputImagePath = vtkm::cont::testing::Testing::WriteDirPath(fileName);
|
||||
vtkm::io::WriteImageFile(dataset, outputImagePath, dataset.GetField(0).GetName());
|
||||
|
||||
imageResult.PushMessage("File '" + fileName +
|
||||
"' did not exist but has been generated here: " + outputImagePath);
|
||||
testResults.PushMessage(imageResult.GetMergedMessage());
|
||||
continue;
|
||||
}
|
||||
catch (const vtkm::cont::ErrorBadValue& error)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Error, error.GetMessage());
|
||||
imageResult.PushMessage(error.GetMessage());
|
||||
imageResult.PushMessage("Unsupported file type for image: " + fileName);
|
||||
testResults.PushMessage(imageResult.GetMergedMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
dartXML << "<DartMeasurementFile name=\"BaselineImage\" type=\"image/png\">";
|
||||
dartXML << testImagePath;
|
||||
dartXML << "</DartMeasurementFile>\n";
|
||||
|
||||
imageDataSet.AddPointField("generated-image", dataset.GetField(0).GetData());
|
||||
vtkm::filter::ImageDifference filter;
|
||||
filter.SetPrimaryField("baseline-image");
|
||||
filter.SetSecondaryField("generated-image");
|
||||
filter.SetAverageRadius(averageRadius);
|
||||
filter.SetPixelShiftRadius(pixelShiftRadius);
|
||||
filter.SetAllowedPixelErrorRatio(allowedPixelErrorRatio);
|
||||
filter.SetPixelDiffThreshold(threshold);
|
||||
auto resultDataSet = filter.Execute(imageDataSet);
|
||||
|
||||
if (!filter.GetImageDiffWithinThreshold())
|
||||
{
|
||||
imageResult.PushMessage("Image Difference was not within the expected threshold for: " +
|
||||
fileName);
|
||||
}
|
||||
|
||||
if (writeDiff && resultDataSet.HasPointField("image-diff"))
|
||||
{
|
||||
const std::string diffName = vtkm::cont::testing::Testing::WriteDirPath(
|
||||
vtkm::io::PrefixStringToFilename(fileName, "diff-"));
|
||||
vtkm::io::WriteImageFile(resultDataSet, diffName, "image-diff");
|
||||
dartXML << "<DartMeasurementFile name=\"DifferenceImage\" type=\"image/png\">";
|
||||
dartXML << diffName;
|
||||
dartXML << "</DartMeasurementFile>\n";
|
||||
}
|
||||
|
||||
if (imageResult && returnOnPass)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Test passed for image " << fileName);
|
||||
if (!testResults)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Other image errors: " << testResults.GetMergedMessage());
|
||||
}
|
||||
return imageResult;
|
||||
}
|
||||
|
||||
testResults.PushMessage(imageResult.GetMergedMessage());
|
||||
}
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Test Results: " << testResults.GetMergedMessage());
|
||||
|
||||
if (!testResults)
|
||||
{
|
||||
std::cout << dartXML.str();
|
||||
}
|
||||
|
||||
return testResults;
|
||||
}
|
@ -22,11 +22,15 @@
|
||||
#include <vtkm/io/FileUtils.h>
|
||||
#include <vtkm/io/ImageUtils.h>
|
||||
|
||||
#include <vtkm/rendering/View.h>
|
||||
|
||||
#include <vtkm/rendering/testing/vtkm_rendering_testing_export.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
/// \brief Tests multiple image files against a provided view pointer for differences
|
||||
/// \brief Tests multiple image files against a provided view for differences.
|
||||
///
|
||||
/// This function tests multiple files provided via fileNames against the rendered
|
||||
/// canvas generated by the provided view using the ImageDifference filter. If one
|
||||
@ -37,128 +41,75 @@
|
||||
/// This function will generate an image if the provided file is missing. If a file is
|
||||
/// missing the image will be generated for that file and the test will continue.
|
||||
///
|
||||
template <typename ViewType>
|
||||
VTKM_RENDERING_TESTING_EXPORT TestEqualResult
|
||||
test_equal_images(vtkm::rendering::View& view,
|
||||
const std::vector<std::string>& fileNames,
|
||||
const vtkm::IdComponent& averageRadius = 0,
|
||||
const vtkm::IdComponent& pixelShiftRadius = 0,
|
||||
const vtkm::FloatDefault& allowedPixelErrorRatio = 0.00025f,
|
||||
const vtkm::FloatDefault& threshold = 0.05f,
|
||||
const bool& writeDiff = true,
|
||||
const bool& returnOnPass = true);
|
||||
|
||||
/// \brief Tests multiple image files against a provided canvas for differences.
|
||||
///
|
||||
/// This function tests multiple files provided via fileNames against the rendered
|
||||
/// canvas using the ImageDifference filter. If one of the provided images is within
|
||||
/// the error threshold for the image difference this function will return true.
|
||||
/// Otherwise the view is too different from the images and this will return false
|
||||
/// with corresponding error messages.
|
||||
///
|
||||
/// The canvas must already be rendered when this is called.
|
||||
///
|
||||
/// This function will generate an image if the provided file is missing. If a file is
|
||||
/// missing the image will be generated for that file and the test will continue.
|
||||
///
|
||||
VTKM_RENDERING_TESTING_EXPORT TestEqualResult
|
||||
test_equal_images(const vtkm::rendering::Canvas& canvas,
|
||||
const std::vector<std::string>& fileNames,
|
||||
const vtkm::IdComponent& averageRadius = 0,
|
||||
const vtkm::IdComponent& pixelShiftRadius = 0,
|
||||
const vtkm::FloatDefault& allowedPixelErrorRatio = 0.00025f,
|
||||
const vtkm::FloatDefault& threshold = 0.05f,
|
||||
const bool& writeDiff = true,
|
||||
const bool& returnOnPass = true);
|
||||
|
||||
/// \brief Tests multiple image files against a provided image for differences.
|
||||
///
|
||||
/// This function tests multiple files provided via fileNames against the provided
|
||||
/// rendered image using the ImageDifference filter. If one of the provided images
|
||||
/// is within the error threshold for the image difference this function will return
|
||||
/// true. Otherwise the view is too different from the images and this will return
|
||||
/// false with corresponding error messages.
|
||||
///
|
||||
/// The provided `DataSet` must contain a `CellSetStructured<2>` and its first field
|
||||
/// must be the colors to compare.
|
||||
///
|
||||
/// This function will generate an image if the provided file is missing. If a file is
|
||||
/// missing the image will be generated for that file and the test will continue.
|
||||
///
|
||||
VTKM_RENDERING_TESTING_EXPORT TestEqualResult
|
||||
test_equal_images(const vtkm::cont::DataSet& generatedImage,
|
||||
const std::vector<std::string>& fileNames,
|
||||
const vtkm::IdComponent& averageRadius = 0,
|
||||
const vtkm::IdComponent& pixelShiftRadius = 0,
|
||||
const vtkm::FloatDefault& allowedPixelErrorRatio = 0.00025f,
|
||||
const vtkm::FloatDefault& threshold = 0.05f,
|
||||
const bool& writeDiff = true,
|
||||
const bool& returnOnPass = true);
|
||||
|
||||
/// \brief Tests multiple image files against a provided image for differences.
|
||||
///
|
||||
/// This form of `test_equal_images` takes a single filename and searches for a list
|
||||
/// of files that match that name or that name with numbers appended to it. It then
|
||||
/// calls the equivalent `test_equal_images` with the list of files found.
|
||||
///
|
||||
/// The `ImageType` can be any type of object that other forms of `test_equal_images`
|
||||
/// accept such as a `View`, a `Canvas`, or a `DataSet` containing an image.
|
||||
///
|
||||
template <typename ImageType>
|
||||
inline TestEqualResult test_equal_images(
|
||||
ViewType& view,
|
||||
const std::vector<std::string>& fileNames,
|
||||
const vtkm::IdComponent& averageRadius = 0,
|
||||
const vtkm::IdComponent& pixelShiftRadius = 0,
|
||||
const vtkm::FloatDefault& allowedPixelErrorRatio = 0.00025f,
|
||||
const vtkm::FloatDefault& threshold = 0.05f,
|
||||
const bool& writeDiff = true,
|
||||
const bool& returnOnPass = true)
|
||||
{
|
||||
vtkm::cont::ScopedRuntimeDeviceTracker runtime(vtkm::cont::DeviceAdapterTagAny{});
|
||||
TestEqualResult testResults;
|
||||
|
||||
if (fileNames.empty())
|
||||
{
|
||||
testResults.PushMessage("No valid image file names were provided");
|
||||
return testResults;
|
||||
}
|
||||
|
||||
view.Paint();
|
||||
view.GetCanvas().RefreshColorBuffer();
|
||||
const std::string testImageName = vtkm::cont::testing::Testing::WriteDirPath(
|
||||
vtkm::io::PrefixStringToFilename(fileNames[0], "test-"));
|
||||
vtkm::io::WriteImageFile(view.GetCanvas().GetDataSet(), testImageName, "color");
|
||||
|
||||
std::stringstream dartXML;
|
||||
|
||||
dartXML << "<DartMeasurementFile name=\"TestImage\" type=\"image/png\">";
|
||||
dartXML << testImageName;
|
||||
dartXML << "</DartMeasurementFile>\n";
|
||||
|
||||
for (const auto& fileName : fileNames)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "testing image file: " << fileName);
|
||||
TestEqualResult imageResult;
|
||||
vtkm::cont::DataSet imageDataSet;
|
||||
const std::string testImagePath = vtkm::cont::testing::Testing::RegressionImagePath(fileName);
|
||||
|
||||
try
|
||||
{
|
||||
imageDataSet = vtkm::io::ReadImageFile(testImagePath, "baseline-image");
|
||||
}
|
||||
catch (const vtkm::cont::ErrorExecution& error)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Error, error.GetMessage());
|
||||
imageResult.PushMessage(error.GetMessage());
|
||||
|
||||
const std::string outputImagePath = vtkm::cont::testing::Testing::WriteDirPath(fileName);
|
||||
vtkm::io::WriteImageFile(view.GetCanvas().GetDataSet(), outputImagePath, "color");
|
||||
|
||||
imageResult.PushMessage("File '" + fileName +
|
||||
"' did not exist but has been generated here: " + outputImagePath);
|
||||
testResults.PushMessage(imageResult.GetMergedMessage());
|
||||
continue;
|
||||
}
|
||||
catch (const vtkm::cont::ErrorBadValue& error)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Error, error.GetMessage());
|
||||
imageResult.PushMessage(error.GetMessage());
|
||||
imageResult.PushMessage("Unsupported file type for image: " + fileName);
|
||||
testResults.PushMessage(imageResult.GetMergedMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
dartXML << "<DartMeasurementFile name=\"BaselineImage\" type=\"image/png\">";
|
||||
dartXML << testImagePath;
|
||||
dartXML << "</DartMeasurementFile>\n";
|
||||
|
||||
imageDataSet.AddPointField("generated-image", view.GetCanvas().GetColorBuffer());
|
||||
vtkm::filter::ImageDifference filter;
|
||||
filter.SetPrimaryField("baseline-image");
|
||||
filter.SetSecondaryField("generated-image");
|
||||
filter.SetAverageRadius(averageRadius);
|
||||
filter.SetPixelShiftRadius(pixelShiftRadius);
|
||||
filter.SetAllowedPixelErrorRatio(allowedPixelErrorRatio);
|
||||
filter.SetPixelDiffThreshold(threshold);
|
||||
auto resultDataSet = filter.Execute(imageDataSet);
|
||||
|
||||
if (!filter.GetImageDiffWithinThreshold())
|
||||
{
|
||||
imageResult.PushMessage("Image Difference was not within the expected threshold for: " +
|
||||
fileName);
|
||||
}
|
||||
|
||||
if (writeDiff && resultDataSet.HasPointField("image-diff"))
|
||||
{
|
||||
const std::string diffName = vtkm::cont::testing::Testing::WriteDirPath(
|
||||
vtkm::io::PrefixStringToFilename(fileName, "diff-"));
|
||||
vtkm::io::WriteImageFile(resultDataSet, diffName, "image-diff");
|
||||
dartXML << "<DartMeasurementFile name=\"DifferenceImage\" type=\"image/png\">";
|
||||
dartXML << diffName;
|
||||
dartXML << "</DartMeasurementFile>\n";
|
||||
}
|
||||
|
||||
if (imageResult && returnOnPass)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Test passed for image " << fileName);
|
||||
if (!testResults)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Other image errors: " << testResults.GetMergedMessage());
|
||||
}
|
||||
return imageResult;
|
||||
}
|
||||
|
||||
testResults.PushMessage(imageResult.GetMergedMessage());
|
||||
}
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Test Results: " << testResults.GetMergedMessage());
|
||||
|
||||
if (!testResults)
|
||||
{
|
||||
std::cout << dartXML.str();
|
||||
}
|
||||
|
||||
return testResults;
|
||||
}
|
||||
|
||||
template <typename ViewType>
|
||||
inline TestEqualResult test_equal_images(
|
||||
ViewType& view,
|
||||
ImageType&& image,
|
||||
const std::string& fileName,
|
||||
const vtkm::IdComponent& averageRadius = 0,
|
||||
const vtkm::IdComponent& pixelShiftRadius = 0,
|
||||
@ -202,8 +153,13 @@ inline TestEqualResult test_equal_images(
|
||||
fileNames.push_back(fileName);
|
||||
}
|
||||
|
||||
return test_equal_images(
|
||||
view, fileNames, averageRadius, pixelShiftRadius, allowedPixelErrorRatio, threshold, writeDiff);
|
||||
return test_equal_images(std::forward<ImageType>(image),
|
||||
fileNames,
|
||||
averageRadius,
|
||||
pixelShiftRadius,
|
||||
allowedPixelErrorRatio,
|
||||
threshold,
|
||||
writeDiff);
|
||||
}
|
||||
|
||||
#endif // vtk_m_rendering_testing_Testing_h
|
||||
|
Loading…
Reference in New Issue
Block a user