Commit 87fabdd7 authored by hrchilds's avatar hrchilds
Browse files

Update from May 19, 2005

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@473 18c085ea-50e0-402c-830e-de6fd14e8384
parent e5cf5487
......@@ -362,14 +362,17 @@ avtSTMDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
bool fallBackToTimesFromFilename = false;
vector<int> cycles;
vector<double> times;
vector<bool> cycleIsAccurate;
vector<bool> timeIsAccurate;
for (i = 0 ; i < nTimesteps; i++)
{
int c = -INT_MAX;
double t = -DBL_MAX;
if (md->AreAllCyclesAccurateAndValid() != true && cyclesLookGood)
if (md->IsCycleAccurate(i) != true && cyclesLookGood)
{
if (forceReadAllCyclesTimes && !fallBackToCyclesFromFilename)
if (forceReadAllCyclesTimes && !fallBackToCyclesFromFilename &&
!canGetGoodCycleFromFilename)
{
c = timesteps[i]->FormatGetCycle();
......@@ -380,11 +383,17 @@ avtSTMDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
{
fallBackToCyclesFromFilename = true;
c = timesteps[i]->FormatGetCycleFromFilename(timesteps[i]->GetFilename());
cycleIsAccurate.push_back(false);
}
else
{
cycleIsAccurate.push_back(true);
}
}
else
{
c = timesteps[i]->FormatGetCycleFromFilename(timesteps[i]->GetFilename());
cycleIsAccurate.push_back(true);
}
cycles.push_back(c);
......@@ -392,10 +401,19 @@ avtSTMDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if ((c == -INT_MAX) || ((i != 0) && (cycles[i] <= cycles[i-1])))
cyclesLookGood = false;
}
else
{
if (cyclesLookGood)
{
cycles.push_back(md->GetCycles()[i]);
cycleIsAccurate.push_back(true);
}
}
if (md->AreAllTimesAccurateAndValid() != true && timesLookGood)
if (md->IsTimeAccurate(i) != true && timesLookGood)
{
if (forceReadAllCyclesTimes && !fallBackToTimesFromFilename)
if (forceReadAllCyclesTimes && !fallBackToTimesFromFilename &&
!canGetGoodTimeFromFilename)
{
t = timesteps[i]->FormatGetTime();
......@@ -406,12 +424,17 @@ avtSTMDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
{
fallBackToTimesFromFilename = true;
t = timesteps[i]->FormatGetTimeFromFilename(timesteps[i]->GetFilename());
timeIsAccurate.push_back(false);
}
else
{
timeIsAccurate.push_back(true);
}
}
else
{
t = timesteps[i]->FormatGetTimeFromFilename(timesteps[i]->GetFilename());
timeIsAccurate.push_back(true);
}
times.push_back(t);
......@@ -419,6 +442,14 @@ avtSTMDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if ((t == -DBL_MAX) || ((i != 0) && (times[i] <= times[i-1])))
timesLookGood = false;
}
else
{
if (timesLookGood)
{
times.push_back(md->GetTimes()[i]);
timeIsAccurate.push_back(true);
}
}
if (cyclesLookGood == false && timesLookGood == false)
break;
......@@ -432,9 +463,8 @@ avtSTMDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if (cyclesLookGood)
{
md->SetCycles(cycles);
md->SetCyclesAreAccurate(forceReadAllCyclesTimes &&
!fallBackToCyclesFromFilename ||
canGetGoodCycleFromFilename);
for (i = 0 ; i < nTimesteps; i++)
md->SetCycleIsAccurate(cycleIsAccurate[i],i);
}
else
{
......@@ -456,9 +486,8 @@ avtSTMDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if (timesLookGood)
{
md->SetTimes(times);
md->SetTimesAreAccurate(forceReadAllCyclesTimes &&
!fallBackToTimesFromFilename ||
canGetGoodTimeFromFilename);
for (i = 0 ; i < nTimesteps; i++)
md->SetTimeIsAccurate(timeIsAccurate[i],i);
md->SetTemporalExtents(times[0], times[times.size() - 1]);
}
else
......
......@@ -377,35 +377,51 @@ avtSTSDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
bool canGetGoodTimeFromFilename =
timesteps[0][0]->FormatGetTimeFromFilename("") != -DBL_MAX+1;
//
// We are going to obtain cycle information from Filenames or from
// the format itself depending on whether forceReadAllCyclesTimes is true.
// If we ever get two consecutive timesteps that are not in increasing order,
// either from the Filename or from the format itself, or if we get "invalid"
// values back from the plugin, we give up.
//
bool cyclesLookGood = true;
bool timesLookGood = true;
bool fallBackToCyclesFromFilename = false;
bool fallBackToTimesFromFilename = false;
vector<int> cycles;
vector<double> times;
vector<bool> cycleIsAccurate;
vector<bool> timeIsAccurate;
for (i = 0 ; i < nTimesteps; i++)
{
if (md->AreAllCyclesAccurateAndValid(nTimesteps) != true && cyclesLookGood)
if (md->IsCycleAccurate(i) != true && cyclesLookGood)
{
int c = -INT_MAX;
if (forceReadAllCyclesTimes && !fallBackToCyclesFromFilename)
if (forceReadAllCyclesTimes && !fallBackToCyclesFromFilename &&
!canGetGoodCycleFromFilename)
{
c = timesteps[i][0]->FormatGetCycle();
// If we get back -INT_MAX from FormatGetCycle, this indicates the
// format was unable to return a valid cycle. So, we fall back
// to using the filenames.
if (c == -INT_MAX)
if (c == -INT_MAX)
{
fallBackToCyclesFromFilename = true;
c = timesteps[i][0]->FormatGetCycleFromFilename(timesteps[i][0]->GetFilename());
cycleIsAccurate.push_back(false);
}
else
{
cycleIsAccurate.push_back(true);
}
}
else
{
c = timesteps[i][0]->FormatGetCycleFromFilename(timesteps[i][0]->GetFilename());
cycleIsAccurate.push_back(true);
}
cycles.push_back(c);
......@@ -413,13 +429,21 @@ avtSTSDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if ((c == -INT_MAX) || ((i != 0) && (cycles[i] <= cycles[i-1])))
cyclesLookGood = false;
}
else
{
if (cyclesLookGood)
{
cycles.push_back(md->GetCycles()[i]);
cycleIsAccurate.push_back(true);
}
}
if (md->AreAllTimesAccurateAndValid(nTimesteps) != true && timesLookGood)
if (md->IsTimeAccurate(i) != true && timesLookGood)
{
double t = -DBL_MAX;
if (forceReadAllCyclesTimes && !fallBackToTimesFromFilename)
if (forceReadAllCyclesTimes && !fallBackToTimesFromFilename &&
!canGetGoodTimeFromFilename)
{
t = timesteps[i][0]->FormatGetTime();
......@@ -430,12 +454,17 @@ avtSTSDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
{
fallBackToTimesFromFilename = true;
t = timesteps[i][0]->FormatGetTimeFromFilename(timesteps[i][0]->GetFilename());
timeIsAccurate.push_back(false);
}
else
{
timeIsAccurate.push_back(true);
}
}
else
{
t = timesteps[i][0]->FormatGetTimeFromFilename(timesteps[i][0]->GetFilename());
timeIsAccurate.push_back(true);
}
times.push_back(t);
......@@ -443,6 +472,14 @@ avtSTSDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if ((t == -DBL_MAX) || ((i != 0) && (times[i] <= times[i-1])))
timesLookGood = false;
}
else
{
if (timesLookGood)
{
times.push_back(md->GetTimes()[i]);
timeIsAccurate.push_back(true);
}
}
if (cyclesLookGood == false && timesLookGood == false)
break;
......@@ -456,9 +493,8 @@ avtSTSDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if (cyclesLookGood)
{
md->SetCycles(cycles);
md->SetCyclesAreAccurate(forceReadAllCyclesTimes &&
!fallBackToCyclesFromFilename ||
canGetGoodCycleFromFilename);
for (i = 0 ; i < nTimesteps; i++)
md->SetCycleIsAccurate(cycleIsAccurate[i],i);
}
else
{
......@@ -477,9 +513,8 @@ avtSTSDFileFormatInterface::SetDatabaseMetaData(avtDatabaseMetaData *md,
if (timesLookGood)
{
md->SetTimes(times);
md->SetTimesAreAccurate(forceReadAllCyclesTimes &&
!fallBackToTimesFromFilename ||
canGetGoodTimeFromFilename);
for (i = 0 ; i < nTimesteps; i++)
md->SetTimeIsAccurate(timeIsAccurate[i],i);
md->SetTemporalExtents(times[0], times[times.size() - 1]);
}
else
......
......@@ -211,29 +211,39 @@ avtExpressionFilter::PostExecute(void)
// Brad Whitlock, Tue Jul 20 17:08:42 PST 2004
// Added code to propagate units.
//
// Hank Childs, Thu May 19 13:43:47 PDT 2005
// Do not assume output variable name has been already set.
//
// ****************************************************************************
void
avtExpressionFilter::RefashionDataObjectInfo(void)
{
if (outputVariableName == NULL)
return;
avtDataAttributes &inputAtts = GetInput()->GetInfo().GetAttributes();
avtDataAttributes &outAtts = GetOutput()->GetInfo().GetAttributes();
if (inputAtts.ValidActiveVariable())
if (!outAtts.ValidVariable(outputVariableName))
{
//
// Expressions should really do some kind of transformation on
// the units. For example if you multiply a variable that has
// Newtons (N) times a variable that is in Meters (m), the resulting
// units for the output variable should be Nm (Newton meters).
// Since we don't have that kind of knowhow in the expressions code
// yet, preserve the units of the active variable even though that's
// not really the correct thing to do.
//
outAtts.AddVariable(outputVariableName, inputAtts.GetVariableUnits());
if (inputAtts.ValidActiveVariable())
{
//
// Expressions should really do some kind of transformation on
// the units. For example if you multiply a variable that has
// Newtons (N) times a variable that is in Meters (m), the resulting
// units for the output variable should be Nm (Newton meters).
// Since we don't have that kind of knowhow in the expressions code
// yet, preserve the units of the active variable even though that's
// not really the correct thing to do.
//
outAtts.AddVariable(outputVariableName,
inputAtts.GetVariableUnits());
}
else
outAtts.AddVariable(outputVariableName);
}
else
outAtts.AddVariable(outputVariableName);
outAtts.SetActiveVariable(outputVariableName);
outAtts.SetVariableDimension(GetVariableDimension());
outAtts.SetCentering(IsPointVariable()?AVT_NODECENT:AVT_ZONECENT);
......
......@@ -7,6 +7,7 @@
#include <vtkCellType.h>
#include <vtkDataSet.h>
#include <vtkFloatArray.h>
#include <vtkRectilinearGrid.h>
#include <verdict.h>
......@@ -50,3 +51,76 @@ double avtVMetricArea::Metric (double coords[][3], int type)
#endif
return -1;
}
// ****************************************************************************
// Method: avtVMetricArea::OperateDirectlyOnMesh
//
// Purpose:
// Determines if we want to speed up the operation by operating directly
// on the mesh.
//
// Programmer: Hank Childs
// Creation: May 19, 2005
//
// ****************************************************************************
bool
avtVMetricArea::OperateDirectlyOnMesh(vtkDataSet *ds)
{
if (ds->GetDataObjectType() == VTK_RECTILINEAR_GRID)
{
int dims[3];
((vtkRectilinearGrid *) ds)->GetDimensions(dims);
if (dims[0] > 1 && dims[1] > 1 && dims[2] == 1)
return true;
}
return false;
}
// ****************************************************************************
// Method: avtVMetricArea::MetricForWholeMesh
//
// Purpose:
// Determines the area for each cell in the mesh.
//
// Programmer: Hank Childs
// Creation: May 19, 2005
//
// ****************************************************************************
void
avtVMetricArea::MetricForWholeMesh(vtkDataSet *ds, vtkDataArray *rv)
{
int i, j;
if (ds->GetDataObjectType() != VTK_RECTILINEAR_GRID)
EXCEPTION0(ImproperUseException);
vtkRectilinearGrid *rg = (vtkRectilinearGrid *) ds;
vtkDataArray *X = rg->GetXCoordinates();
vtkDataArray *Y = rg->GetYCoordinates();
int dims[3];
rg->GetDimensions(dims);
float *Xdist = new float[dims[0]-1];
for (i = 0 ; i < dims[0]-1 ; i++)
Xdist[i] = X->GetTuple1(i+1) - X->GetTuple1(i);
float *Ydist = new float[dims[1]-1];
for (i = 0 ; i < dims[1]-1 ; i++)
Ydist[i] = Y->GetTuple1(i+1) - Y->GetTuple1(i);
for (j = 0 ; j < dims[1]-1 ; j++)
for (i = 0 ; i < dims[0]-1 ; i++)
{
int idx = j*(dims[0]-1) + i;
float area = Xdist[i]*Ydist[j];
rv->SetTuple1(idx, area);
}
delete [] Xdist;
delete [] Ydist;
}
// ************************************************************************* //
// avtVMetricArea.h //
// avtVMetricArea.h //
// ************************************************************************* //
#ifndef AVT_VMETRIC_AREA_H
#define AVT_VMETRIC_AREA_H
#include <expression_exports.h>
#include <avtVerdictFilter.h>
// ****************************************************************************
// Class: avtVMetricArea
//
......@@ -16,12 +19,22 @@
// Programmer: Akira Haddox
// Creation: June 13, 2002
//
// Modifications:
//
// Hank Childs, Thu May 19 10:55:30 PDT 2005
// Added support for operating on rectilinear meshes directly.
//
// ****************************************************************************
class EXPRESSION_API avtVMetricArea : public avtVerdictFilter
{
public:
double Metric(double coords[][3], int type);
public:
virtual double Metric(double coords[][3], int type);
virtual bool OperateDirectlyOnMesh(vtkDataSet *);
virtual void MetricForWholeMesh(vtkDataSet *, vtkDataArray *);
};
#endif
......@@ -7,6 +7,7 @@
#include <vtkCellType.h>
#include <vtkDataSet.h>
#include <vtkFloatArray.h>
#include <vtkRectilinearGrid.h>
#include <verdict.h>
......@@ -137,3 +138,71 @@ double avtVMetricVolume::Metric (double coords[][3], int type)
}
// ****************************************************************************
// Method: avtVMetricVolume::OperateDirectlyOnMesh
//
// Purpose:
// Determines if we want to speed up the operation by operating directly
// on the mesh.
//
// Programmer: Hank Childs
// Creation: May 19, 2005
//
// ****************************************************************************
bool
avtVMetricVolume::OperateDirectlyOnMesh(vtkDataSet *ds)
{
return (ds->GetDataObjectType() == VTK_RECTILINEAR_GRID);
}
// ****************************************************************************
// Method: avtVMetricVolume::MetricForWholeMesh
//
// Purpose:
// Determines the volume for each cell in the mesh.
//
// Programmer: Hank Childs
// Creation: May 19, 2005
//
// ****************************************************************************
void
avtVMetricVolume::MetricForWholeMesh(vtkDataSet *ds, vtkDataArray *rv)
{
int i, j, k;
if (ds->GetDataObjectType() != VTK_RECTILINEAR_GRID)
EXCEPTION0(ImproperUseException);
vtkRectilinearGrid *rg = (vtkRectilinearGrid *) ds;
vtkDataArray *X = rg->GetXCoordinates();
vtkDataArray *Y = rg->GetYCoordinates();
vtkDataArray *Z = rg->GetZCoordinates();
int dims[3];
rg->GetDimensions(dims);
float *Xdist = new float[dims[0]-1];
for (i = 0 ; i < dims[0]-1 ; i++)
Xdist[i] = X->GetTuple1(i+1) - X->GetTuple1(i);
float *Ydist = new float[dims[1]-1];
for (i = 0 ; i < dims[1]-1 ; i++)
Ydist[i] = Y->GetTuple1(i+1) - Y->GetTuple1(i);
float *Zdist = new float[dims[2]-1];
for (i = 0 ; i < dims[2]-1 ; i++)
Zdist[i] = Z->GetTuple1(i+1) - Z->GetTuple1(i);
for (k = 0 ; k < dims[2]-1 ; k++)
for (j = 0 ; j < dims[1]-1 ; j++)
for (i = 0 ; i < dims[0]-1 ; i++)
{
int idx = k*(dims[1]-1)*(dims[0]-1) + j*(dims[0]-1) + i;
float vol = Xdist[i]*Ydist[j]*Zdist[k];
rv->SetTuple1(idx, vol);
}
delete [] Xdist;
delete [] Ydist;
delete [] Zdist;
}
......@@ -23,6 +23,9 @@
// Hank Childs, Sat Aug 31 12:25:02 PDT 2002
// Added ability to only consider absolute values of volumes.
//
// Hank Childs, Thu May 19 10:55:30 PDT 2005
// Added support for operating on rectilinear meshes directly.
//
// ****************************************************************************
class EXPRESSION_API avtVMetricVolume : public avtVerdictFilter
......@@ -35,6 +38,9 @@ class EXPRESSION_API avtVMetricVolume : public avtVerdictFilter
void UseOnlyPositiveVolumes(bool val)
{ useOnlyPositiveVolumes = val; };
virtual bool OperateDirectlyOnMesh(vtkDataSet *);
virtual void MetricForWholeMesh(vtkDataSet *, vtkDataArray *);
protected:
bool useOnlyPositiveVolumes;
};
......
......@@ -117,6 +117,10 @@ avtVerdictFilter::~avtVerdictFilter()
// Akira Haddox, Wed Jul 2 08:26:30 PDT 2003
// Added conversion from pixel cell type.
//
// Hank Childs, Thu May 19 10:47:08 PDT 2005
// Allow for sub-types to speed up execution by operating directly on the
// mesh.
//
// ****************************************************************************
vtkDataArray *
......@@ -126,73 +130,73 @@ avtVerdictFilter::DeriveVariable(vtkDataSet *in_ds)
int nCells = in_ds->GetNumberOfCells();
double *results = new double[nCells];
//
// Set up a VTK variable reflecting the results we have calculated.
//
vtkFloatArray *dv = vtkFloatArray::New();
dv->SetNumberOfTuples(nCells);
//
// Iterate over each cell in the mesh and if it matches a
// testData prerequisites, run the corresponding metric
//
const int MAXPOINTS = 100;
double coordinates[MAXPOINTS][3];
for (i = 0; i < nCells; i++)
if (OperateDirectlyOnMesh(in_ds))
{
vtkCell *cell = in_ds->GetCell(i);
int numPointsForThisCell = cell->GetNumberOfPoints();
// Grab a pointer to the cell's points' underlying data array
vtkDataArray *pointData = cell->GetPoints()->GetData();
//
// Since the Verdict functions make their own copy of the data anyway
// it would be nice to get the coordinate data without copying (to cut
// down on unneeded copying). However, this might be infesible since
// Verdict expects doubles, and vtk (potentially) uses floats.
//
if (pointData->GetNumberOfComponents() != 3)
{
EXCEPTION0(ImproperUseException);
}
// Fortunately, Verdict will convert to a double[3] for us
for (j = 0; j < numPointsForThisCell; j++)
{
coordinates[j][2] = 0; // In case of 2d coordinates
pointData->GetTuple(j,coordinates[j]);
}
int cellType = cell->GetCellType();
// Convert Voxel format into hexahedron format.
if (cellType == VTK_VOXEL)
{
Swap3(coordinates, 2,3