Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/alembic/module/Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
list(APPEND VTKExtensionsPluginAlembic_list
TestF3DAlembicReader.cxx
TestF3DAlembicReaderRequestInformation.cxx
)

if(VTK_VERSION VERSION_GREATER_EQUAL 9.5.20251210)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <vtkAlgorithm.h>
#include <vtkInformation.h>
#include <vtkInformationVector.h>
#include <vtkNew.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include <vtkTestUtilities.h>

#include "vtkF3DAlembicReader.h"

#include <iostream>

int TestF3DAlembicReaderRequestInformation(int vtkNotUsed(argc), char* argv[])
{
static int NUMBER_OF_TIME_STEPS = 90;
static const double expectedTimeSteps[] = { 0.000000, 0.033333, 0.066667, 0.100000, 0.133333,
0.166667, 0.200000, 0.233333, 0.266667, 0.300000, 0.333333, 0.366667, 0.400000, 0.433333,
0.466667, 0.500000, 0.533333, 0.566667, 0.600000, 0.633333, 0.666667, 0.700000, 0.733333,
0.766667, 0.800000, 0.833333, 0.866667, 0.900000, 0.933333, 0.966667, 1.000000, 1.033333,
1.066667, 1.100000, 1.133333, 1.166667, 1.200000, 1.233333, 1.266667, 1.300000, 1.333333,
1.366667, 1.400000, 1.433333, 1.466667, 1.500000, 1.533333, 1.566667, 1.600000, 1.633333,
1.666667, 1.700000, 1.733333, 1.766667, 1.800000, 1.833333, 1.866667, 1.900000, 1.933333,
1.966667, 2.000000, 2.033333, 2.066667, 2.100000, 2.133333, 2.166667, 2.200000, 2.233333,
2.266667, 2.300000, 2.333333, 2.366667, 2.400000, 2.433333, 2.466667, 2.500000, 2.533333,
2.566667, 2.600000, 2.633333, 2.666667, 2.700000, 2.733333, 2.766667, 2.800000, 2.833333,
2.866667, 2.900000, 2.933333, 2.966667 };
static const double expectedTimeRange[] = { 0.000000, 2.966667 };

std::string filename = std::string(argv[1]) + "data/drop.abc";
vtkNew<vtkF3DAlembicReader> reader;
reader->SetFileName(filename);
reader->UpdateInformation();
vtkInformation* readerInfo = reader->GetOutputInformation(0);
double* readerTimeSteps = nullptr;
if (readerInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
{
readerTimeSteps = readerInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
Comment thread
LuTheDog marked this conversation as resolved.
}
else
{
return EXIT_FAILURE;
}
double* readerTimeRange = nullptr;
if (readerInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE()))
{
readerTimeRange = readerInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_RANGE());
}
else
{
return EXIT_FAILURE;
}

for (int i = 0; i < 2; i++)
{
if (fabs(readerTimeRange[i] - expectedTimeRange[i]) > 1e-6)
{
return EXIT_FAILURE;
}
}

for (int i = 0; i < NUMBER_OF_TIME_STEPS; i++)
{
if (fabs(readerTimeSteps[i] - expectedTimeSteps[i]) > 1e-6)
{
return EXIT_FAILURE;
}
}

return EXIT_SUCCESS;
}
37 changes: 20 additions & 17 deletions plugins/alembic/module/vtkF3DAlembicReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,12 @@ class vtkF3DAlembicReader::vtkInternals
}
}

void ExtendTimeRange(double& start, double& end)
void ComputeTimeRangeAndSteps(double& start, double& end, std::vector<double>& timeSteps)
{
Alembic::Abc::IObject top = this->Archive.getTop();

// Using std::set since we need time steps to be unique and ordered
std::set<double> timeStepSet;
std::stack<std::pair<const Alembic::Abc::IObject, const Alembic::Abc::ObjectHeader>> objects;

for (size_t i = 0; i < top.getNumChildren(); ++i)
Expand All @@ -619,28 +621,24 @@ class vtkF3DAlembicReader::vtkInternals
{
const auto& [parent, ohead] = objects.top();
const Alembic::AbcGeom::IObject obj(parent, ohead.getName());
int numSamples = 0;
Alembic::Abc::TimeSamplingPtr ts;
if (Alembic::AbcGeom::IXform::matches(ohead))
{
const Alembic::AbcGeom::IXform xForm(parent, ohead.getName());
const Alembic::AbcGeom::IXformSchema& schema = xForm.getSchema();
ts = schema.getTimeSampling();
numSamples = static_cast<int>(schema.getNumSamples());
}
else if (Alembic::AbcGeom::IPolyMesh::matches(ohead))
{
const Alembic::AbcGeom::IPolyMesh polymesh(parent, ohead.getName());
const Alembic::AbcGeom::IPolyMeshSchema& schema = polymesh.getSchema();
ts = schema.getTimeSampling();
numSamples = static_cast<int>(schema.getNumSamples());
}
else if (Alembic::AbcGeom::ICurves::matches(ohead))
{
const Alembic::AbcGeom::ICurves curves(parent, ohead.getName());
const Alembic::AbcGeom::ICurvesSchema& schema = curves.getSchema();
ts = schema.getTimeSampling();
numSamples = static_cast<int>(schema.getNumSamples());
}

objects.pop();
Expand All @@ -654,20 +652,19 @@ class vtkF3DAlembicReader::vtkInternals
continue;
}

if (ts->getTimeSamplingType().isUniform())
// Collecting all time steps
const auto& times = ts->getStoredTimes();
for (auto& timeStep : times)
{
double min = ts->getSampleTime(0);
double max = min + (numSamples - 1) * ts->getTimeSamplingType().getTimePerCycle();
start = std::min(start, min);
end = std::max(end, max);
}
else if (ts->getTimeSamplingType().isCyclic())
{
const auto& times = ts->getStoredTimes();
start = std::min(start, times.front());
end = std::max(end, times.back());
timeStepSet.insert(timeStep);
}
}
if (timeStepSet.size() > 0)
{
start = *timeStepSet.begin();
end = *timeStepSet.rbegin();
timeSteps = std::vector<double>(timeStepSet.begin(), timeStepSet.end());
}
}

bool ReadArchive(
Expand Down Expand Up @@ -738,13 +735,19 @@ int vtkF3DAlembicReader::RequestInformation(vtkInformation* vtkNotUsed(request),

double timeRange[2] = { std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity() };
this->Internals->ExtendTimeRange(timeRange[0], timeRange[1]);
std::vector<double> timeSteps{ 0 };
this->Internals->ComputeTimeRangeAndSteps(timeRange[0], timeRange[1], timeSteps);

vtkInformation* outInfo = outputVector->GetInformationObject(0);
if (timeRange[0] < timeRange[1])
{
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2);
}
if (timeSteps.size() > 0)
{
outInfo->Set(
vtkStreamingDemandDrivenPipeline::TIME_STEPS(), timeSteps.data(), timeSteps.size());
}

return 1;
}
Expand Down
Loading