Commit 885331ac authored by pugmire's avatar pugmire

Support for zone centered vector fields.

GUI option to force node centering.



git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@11777 18c085ea-50e0-402c-830e-de6fd14e8384
parent aa3996c0
......@@ -588,6 +588,11 @@ PyStreamlineAttributes_ToString(const StreamlineAttributes *atts, const char *pr
str += tmpStr;
SNPRINTF(tmpStr, 1000, "%snumberOfRandomSamples = %d\n", prefix, atts->GetNumberOfRandomSamples());
str += tmpStr;
if(atts->GetForceNodeCenteredData())
SNPRINTF(tmpStr, 1000, "%sforceNodeCenteredData = 1\n", prefix);
else
SNPRINTF(tmpStr, 1000, "%sforceNodeCenteredData = 0\n", prefix);
str += tmpStr;
return str;
}
......@@ -2632,6 +2637,30 @@ StreamlineAttributes_GetNumberOfRandomSamples(PyObject *self, PyObject *args)
return retval;
}
/*static*/ PyObject *
StreamlineAttributes_SetForceNodeCenteredData(PyObject *self, PyObject *args)
{
StreamlineAttributesObject *obj = (StreamlineAttributesObject *)self;
int ival;
if(!PyArg_ParseTuple(args, "i", &ival))
return NULL;
// Set the forceNodeCenteredData in the object.
obj->data->SetForceNodeCenteredData(ival != 0);
Py_INCREF(Py_None);
return Py_None;
}
/*static*/ PyObject *
StreamlineAttributes_GetForceNodeCenteredData(PyObject *self, PyObject *args)
{
StreamlineAttributesObject *obj = (StreamlineAttributesObject *)self;
PyObject *retval = PyInt_FromLong(obj->data->GetForceNodeCenteredData()?1L:0L);
return retval;
}
PyMethodDef PyStreamlineAttributes_methods[STREAMLINEATTRIBUTES_NMETH] = {
......@@ -2770,6 +2799,8 @@ PyMethodDef PyStreamlineAttributes_methods[STREAMLINEATTRIBUTES_NMETH] = {
{"GetRandomSeed", StreamlineAttributes_GetRandomSeed, METH_VARARGS},
{"SetNumberOfRandomSamples", StreamlineAttributes_SetNumberOfRandomSamples, METH_VARARGS},
{"GetNumberOfRandomSamples", StreamlineAttributes_GetNumberOfRandomSamples, METH_VARARGS},
{"SetForceNodeCenteredData", StreamlineAttributes_SetForceNodeCenteredData, METH_VARARGS},
{"GetForceNodeCenteredData", StreamlineAttributes_GetForceNodeCenteredData, METH_VARARGS},
{NULL, NULL}
};
......@@ -3020,6 +3051,8 @@ PyStreamlineAttributes_getattr(PyObject *self, char *name)
return StreamlineAttributes_GetRandomSeed(self, NULL);
if(strcmp(name, "numberOfRandomSamples") == 0)
return StreamlineAttributes_GetNumberOfRandomSamples(self, NULL);
if(strcmp(name, "forceNodeCenteredData") == 0)
return StreamlineAttributes_GetForceNodeCenteredData(self, NULL);
return Py_FindMethod(PyStreamlineAttributes_methods, self, name);
}
......@@ -3168,6 +3201,8 @@ PyStreamlineAttributes_setattr(PyObject *self, char *name, PyObject *args)
obj = StreamlineAttributes_SetRandomSeed(self, tuple);
else if(strcmp(name, "numberOfRandomSamples") == 0)
obj = StreamlineAttributes_SetNumberOfRandomSamples(self, tuple);
else if(strcmp(name, "forceNodeCenteredData") == 0)
obj = StreamlineAttributes_SetForceNodeCenteredData(self, tuple);
if(obj != NULL)
Py_DECREF(obj);
......
......@@ -44,7 +44,7 @@
//
// Functions exposed to the VisIt module.
//
#define STREAMLINEATTRIBUTES_NMETH 136
#define STREAMLINEATTRIBUTES_NMETH 138
void PyStreamlineAttributes_StartUp(StreamlineAttributes *subj, void *data);
void PyStreamlineAttributes_CloseDown();
PyMethodDef * PyStreamlineAttributes_GetMethodTable(int *nMethods);
......
......@@ -530,11 +530,17 @@ QvisStreamlinePlotWindow::CreateWindowContents()
// Create the absolute tolerance text field.
absTolLabel = new QLabel(tr("Absolute tolerance"), integrationGroup);
absTol = new QLineEdit(integrationGroup);
connect(absTol, SIGNAL(returnPressed()),
this, SLOT(absTolProcessText()));
connect(absTol, SIGNAL(returnPressed()), this, SLOT(absTolProcessText()));
integrationLayout->addWidget(absTolLabel, 3,0);
integrationLayout->addWidget(absTol, 3, 1);
forceNodalLabel = new QLabel(tr("Force node centering"), integrationGroup);
forceNodal = new QCheckBox(integrationGroup);
connect(forceNodal, SIGNAL(toggled(bool)), this, SLOT(forceNodalChanged(bool)));
integrationLayout->addWidget(forceNodalLabel, 4,0);
integrationLayout->addWidget(forceNodal, 4, 1);
// ----------------------------------------------------------------------
// Appearance tab
// ----------------------------------------------------------------------
......@@ -1600,6 +1606,12 @@ QvisStreamlinePlotWindow::UpdateWindow(bool doAll)
numberOfRandomSamples->setValue(streamAtts->GetNumberOfRandomSamples());
numberOfRandomSamples->blockSignals(false);
break;
case StreamlineAttributes::ID_forceNodeCenteredData:
forceNodal->blockSignals(true);
forceNodal->setChecked(streamAtts->GetForceNodeCenteredData());
forceNodal->blockSignals(false);
break;
}
}
}
......@@ -2874,6 +2886,13 @@ QvisStreamlinePlotWindow::absTolProcessText()
Apply();
}
void
QvisStreamlinePlotWindow::forceNodalChanged(bool val)
{
streamAtts->SetForceNodeCenteredData(val);
Apply();
}
void
QvisStreamlinePlotWindow::pointSourceProcessText()
{
......
......@@ -233,6 +233,7 @@ class QvisStreamlinePlotWindow : public QvisPostableWindowObserver
void deletePoint();
void readPoints();
void textChanged(const QString &currentText);
void forceNodalChanged(bool);
private:
int plotType;
......@@ -245,6 +246,8 @@ class QvisStreamlinePlotWindow : public QvisPostableWindowObserver
QLabel *relTolLabel;
QLineEdit *absTol;
QLabel *absTolLabel;
QLabel *forceNodalLabel;
QCheckBox *forceNodal;
QLineEdit *pointSource;
QLabel *pointSourceLabel;
QLineEdit *lineStart;
......
......@@ -219,6 +219,7 @@ StreamlineAttributes::ChangesRequireRecalculation(const StreamlineAttributes &ob
maxStepLength != obj.maxStepLength ||
relTol != obj.relTol ||
absTol != obj.absTol ||
forceNodeCenteredData != obj.forceNodeCenteredData ||
pathlines != obj.pathlines ||
coloringVariable != obj.coloringVariable ||
(displayMethod != obj.displayMethod && obj.displayMethod == Ribbons) ||
......
......@@ -313,6 +313,9 @@
<Field name="numberOfRandomSamples" label="numberOfRandomSamples" type="int">
1
</Field>
<Field name="forceNodeCenteredData" label="forceNodeCenteredData" type="bool">
false
</Field>
<Function name="CopyAttributes" user="false" member="true">
</Function>
<Function name="CreateCompatible" user="false" member="true">
......
......@@ -533,6 +533,7 @@ void StreamlineAttributes::Init()
randomSamples = false;
randomSeed = 0;
numberOfRandomSamples = 1;
forceNodeCenteredData = false;
StreamlineAttributes::SelectAll();
}
......@@ -645,6 +646,7 @@ void StreamlineAttributes::Copy(const StreamlineAttributes &obj)
randomSamples = obj.randomSamples;
randomSeed = obj.randomSeed;
numberOfRandomSamples = obj.numberOfRandomSamples;
forceNodeCenteredData = obj.forceNodeCenteredData;
StreamlineAttributes::SelectAll();
}
......@@ -910,7 +912,8 @@ StreamlineAttributes::operator == (const StreamlineAttributes &obj) const
(fillInterior == obj.fillInterior) &&
(randomSamples == obj.randomSamples) &&
(randomSeed == obj.randomSeed) &&
(numberOfRandomSamples == obj.numberOfRandomSamples));
(numberOfRandomSamples == obj.numberOfRandomSamples) &&
(forceNodeCenteredData == obj.forceNodeCenteredData));
}
// ****************************************************************************
......@@ -1234,6 +1237,7 @@ StreamlineAttributes::SelectAll()
Select(ID_randomSamples, (void *)&randomSamples);
Select(ID_randomSeed, (void *)&randomSeed);
Select(ID_numberOfRandomSamples, (void *)&numberOfRandomSamples);
Select(ID_forceNodeCenteredData, (void *)&forceNodeCenteredData);
}
///////////////////////////////////////////////////////////////////////////////
......@@ -1670,6 +1674,12 @@ StreamlineAttributes::CreateNode(DataNode *parentNode, bool completeSave, bool f
node->AddNode(new DataNode("numberOfRandomSamples", numberOfRandomSamples));
}
if(completeSave || !FieldsEqual(ID_forceNodeCenteredData, &defaultObject))
{
addToParent = true;
node->AddNode(new DataNode("forceNodeCenteredData", forceNodeCenteredData));
}
// Add the node to the parent node.
if(addToParent || forceAdd)
......@@ -1980,6 +1990,8 @@ StreamlineAttributes::SetFromNode(DataNode *parentNode)
SetRandomSeed(node->AsInt());
if((node = searchNode->GetNode("numberOfRandomSamples")) != 0)
SetNumberOfRandomSamples(node->AsInt());
if((node = searchNode->GetNode("forceNodeCenteredData")) != 0)
SetForceNodeCenteredData(node->AsBool());
}
///////////////////////////////////////////////////////////////////////////////
......@@ -2470,6 +2482,13 @@ StreamlineAttributes::SetNumberOfRandomSamples(int numberOfRandomSamples_)
Select(ID_numberOfRandomSamples, (void *)&numberOfRandomSamples);
}
void
StreamlineAttributes::SetForceNodeCenteredData(bool forceNodeCenteredData_)
{
forceNodeCenteredData = forceNodeCenteredData_;
Select(ID_forceNodeCenteredData, (void *)&forceNodeCenteredData);
}
///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////
......@@ -2954,6 +2973,12 @@ StreamlineAttributes::GetNumberOfRandomSamples() const
return numberOfRandomSamples;
}
bool
StreamlineAttributes::GetForceNodeCenteredData() const
{
return forceNodeCenteredData;
}
///////////////////////////////////////////////////////////////////////////////
// Select property methods
///////////////////////////////////////////////////////////////////////////////
......@@ -3127,6 +3152,7 @@ StreamlineAttributes::GetFieldName(int index) const
case ID_randomSamples: return "randomSamples";
case ID_randomSeed: return "randomSeed";
case ID_numberOfRandomSamples: return "numberOfRandomSamples";
case ID_forceNodeCenteredData: return "forceNodeCenteredData";
default: return "invalid index";
}
}
......@@ -3218,6 +3244,7 @@ StreamlineAttributes::GetFieldType(int index) const
case ID_randomSamples: return FieldType_bool;
case ID_randomSeed: return FieldType_int;
case ID_numberOfRandomSamples: return FieldType_int;
case ID_forceNodeCenteredData: return FieldType_bool;
default: return FieldType_unknown;
}
}
......@@ -3309,6 +3336,7 @@ StreamlineAttributes::GetFieldTypeName(int index) const
case ID_randomSamples: return "bool";
case ID_randomSeed: return "int";
case ID_numberOfRandomSamples: return "int";
case ID_forceNodeCenteredData: return "bool";
default: return "invalid index";
}
}
......@@ -3710,6 +3738,11 @@ StreamlineAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
retval = (numberOfRandomSamples == obj.numberOfRandomSamples);
}
break;
case ID_forceNodeCenteredData:
{ // new scope
retval = (forceNodeCenteredData == obj.forceNodeCenteredData);
}
break;
default: retval = false;
}
......@@ -3765,6 +3798,7 @@ StreamlineAttributes::ChangesRequireRecalculation(const StreamlineAttributes &ob
maxStepLength != obj.maxStepLength ||
relTol != obj.relTol ||
absTol != obj.absTol ||
forceNodeCenteredData != obj.forceNodeCenteredData ||
pathlines != obj.pathlines ||
coloringVariable != obj.coloringVariable ||
(displayMethod != obj.displayMethod && obj.displayMethod == Ribbons) ||
......
......@@ -238,6 +238,7 @@ public:
void SetRandomSamples(bool randomSamples_);
void SetRandomSeed(int randomSeed_);
void SetNumberOfRandomSamples(int numberOfRandomSamples_);
void SetForceNodeCenteredData(bool forceNodeCenteredData_);
// Property getting methods
SourceType GetSourceType() const;
......@@ -320,6 +321,7 @@ public:
bool GetRandomSamples() const;
int GetRandomSeed() const;
int GetNumberOfRandomSamples() const;
bool GetForceNodeCenteredData() const;
// Persistence methods
virtual bool CreateNode(DataNode *node, bool completeSave, bool forceAdd);
......@@ -456,6 +458,7 @@ public:
ID_randomSamples,
ID_randomSeed,
ID_numberOfRandomSamples,
ID_forceNodeCenteredData,
ID__LAST
};
......@@ -527,11 +530,12 @@ private:
bool randomSamples;
int randomSeed;
int numberOfRandomSamples;
bool forceNodeCenteredData;
// Static class format string for type map.
static const char *TypeMapFormatString;
static const private_tmfs_t TmfsStruct;
};
#define STREAMLINEATTRIBUTES_TMFS "iddDDDDDDdDDbd*iiiibbddiisabbiddiiiiiibsbbddddbbdiddisdddbbiidddbbii"
#define STREAMLINEATTRIBUTES_TMFS "iddDDDDDDdDDbd*iiiibbddiisabbiddiiiiiibsbbddddbbdiddisdddbbiidddbbiib"
#endif
......@@ -62,7 +62,7 @@ import llnl.visit.ColorAttribute;
public class StreamlineAttributes extends AttributeSubject implements Plugin
{
private static int StreamlineAttributes_numAdditionalAtts = 67;
private static int StreamlineAttributes_numAdditionalAtts = 68;
// Enum values
public final static int SOURCETYPE_SPECIFIEDPOINT = 0;
......@@ -222,6 +222,7 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
randomSamples = false;
randomSeed = 0;
numberOfRandomSamples = 1;
forceNodeCenteredData = false;
}
public StreamlineAttributes(int nMoreFields)
......@@ -331,6 +332,7 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
randomSamples = false;
randomSeed = 0;
numberOfRandomSamples = 1;
forceNodeCenteredData = false;
}
public StreamlineAttributes(StreamlineAttributes obj)
......@@ -443,6 +445,7 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
randomSamples = obj.randomSamples;
randomSeed = obj.randomSeed;
numberOfRandomSamples = obj.numberOfRandomSamples;
forceNodeCenteredData = obj.forceNodeCenteredData;
SelectAll();
}
......@@ -577,7 +580,8 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
(fillInterior == obj.fillInterior) &&
(randomSamples == obj.randomSamples) &&
(randomSeed == obj.randomSeed) &&
(numberOfRandomSamples == obj.numberOfRandomSamples));
(numberOfRandomSamples == obj.numberOfRandomSamples) &&
(forceNodeCenteredData == obj.forceNodeCenteredData));
}
public String GetName() { return "Streamline"; }
......@@ -1057,6 +1061,12 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
Select(66);
}
public void SetForceNodeCenteredData(boolean forceNodeCenteredData_)
{
forceNodeCenteredData = forceNodeCenteredData_;
Select(67);
}
// Property getting methods
public int GetSourceType() { return sourceType; }
public double GetMaxStepLength() { return maxStepLength; }
......@@ -1125,6 +1135,7 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
public boolean GetRandomSamples() { return randomSamples; }
public int GetRandomSeed() { return randomSeed; }
public int GetNumberOfRandomSamples() { return numberOfRandomSamples; }
public boolean GetForceNodeCenteredData() { return forceNodeCenteredData; }
// Write and read methods.
public void WriteAtts(CommunicationBuffer buf)
......@@ -1263,6 +1274,8 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
buf.WriteInt(randomSeed);
if(WriteSelect(66, buf))
buf.WriteInt(numberOfRandomSamples);
if(WriteSelect(67, buf))
buf.WriteBool(forceNodeCenteredData);
}
public void ReadAtts(int index, CommunicationBuffer buf)
......@@ -1471,6 +1484,9 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
case 66:
SetNumberOfRandomSamples(buf.ReadInt());
break;
case 67:
SetForceNodeCenteredData(buf.ReadBool());
break;
}
}
......@@ -1632,6 +1648,7 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
str = str + boolToString("randomSamples", randomSamples, indent) + "\n";
str = str + intToString("randomSeed", randomSeed, indent) + "\n";
str = str + intToString("numberOfRandomSamples", numberOfRandomSamples, indent) + "\n";
str = str + boolToString("forceNodeCenteredData", forceNodeCenteredData, indent) + "\n";
return str;
}
......@@ -1704,5 +1721,6 @@ public class StreamlineAttributes extends AttributeSubject implements Plugin
private boolean randomSamples;
private int randomSeed;
private int numberOfRandomSamples;
private boolean forceNodeCenteredData;
}
......@@ -219,12 +219,9 @@ avtStreamlinePlot::ApplyOperators(avtDataObject_p input)
if (input->GetInfo().GetAttributes().ValidVariable(varname))
centering = input->GetInfo().GetAttributes().GetCentering(varname);
// If the variable centering is zonal, convert it to nodal or the
// streamline filter will not play with it.
if(centering == AVT_ZONECENT)
//Convert from zonal to nodal, if requested.
if(centering == AVT_ZONECENT && atts.GetForceNodeCenteredData())
{
avtCallback::IssueWarning("The vector field being used to generate the streamline(s) is zone (cell) centered. Streamline requires nodal data, moving data from from zones to the nodes. This change in centering may have unintended consequences." );
if(shiftCenteringFilter != NULL)
delete shiftCenteringFilter;
shiftCenteringFilter = new avtShiftCenteringFilter(AVT_NODECENT);
......
......@@ -47,12 +47,15 @@
#include <vtkIdList.h>
#include <vtkObjectFactory.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkRectilinearGrid.h>
#include <vtkVisItCellLocator.h>
#include <vtkVisItUtility.h>
#include <DebugStream.h>
static void
InterpVector(vtkGenericCell *cell, int numPts, vtkDataArray *vectors, double *weights, double *vel);
vtkVisItInterpolatedVelocityField* vtkVisItInterpolatedVelocityField::New()
{
......@@ -127,10 +130,19 @@ vtkVisItInterpolatedVelocityField::Evaluate(double *pt, double *vel, double t)
vtkDataArray *vectors2 = NULL;
if (doPathlines)
vectors2 = ds->GetPointData()->GetArray(nextTimeName.c_str());
bool nodeCenteredVector = true;
if (vectors == NULL)
{
debug1 <<" vtkVisItInterpolatedVelocityField::Can't locate vectors to interpolate" << endl;
return false;
vectors = ds->GetCellData()->GetVectors();
if (vectors == NULL)
{
debug1 <<" vtkVisItInterpolatedVelocityField::Can't locate vectors to interpolate" << endl;
return false;
}
nodeCenteredVector = false;
if (doPathlines)
vectors2 = ds->GetCellData()->GetArray(nextTimeName.c_str());
}
if (doPathlines && vectors2 == NULL)
{
......@@ -167,55 +179,75 @@ vtkVisItInterpolatedVelocityField::Evaluate(double *pt, double *vel, double t)
int subId = 0;
locator->IgnoreGhostsOff();
int success = locator->FindClosestPointWithinRadius(pt, rad, resPt,
cell, subId, dist);
cell, subId, dist);
}
if (cell < 0)
return false;
vtkGenericCell *GenCell = vtkGenericCell::New();
ds->GetCell(cell, GenCell);
lastCell = cell;
int numPts = GenCell->GetNumberOfPoints();
double closestPoint[3];
int subId;
double dist2;
int val = GenCell->EvaluatePosition(pt, closestPoint, subId, pcoords, dist2, weights);
if (val <= 0)
return false;
// interpolate the vectors
vel[0] = vel[1] = vel[2] = 0;
double vec[3];
for (int j=0; j < numPts; j++)
//For zone centered vector fields:
if (!nodeCenteredVector)
{
int id = GenCell->PointIds->GetId(j);
vectors->GetTuple(id, vec);
for (int i=0; i < 3; i++)
{
vel[i] += vec[i] * weights[j];
}
vectors->GetTuple(cell, vel);
if (doPathlines)
{
double vel2[3];
vectors2->GetTuple(cell, vel2);
double prop1 = 1. - (t - curTime) / (nextTime - curTime);
vel[0] = prop1*vel[0] + (1-prop1)*vel2[0];
vel[1] = prop1*vel[1] + (1-prop1)*vel2[1];
vel[2] = prop1*vel[2] + (1-prop1)*vel2[2];
}
}
if (doPathlines)
else
{
double vel2[3] = { 0, 0, 0 };
double vel1[3] = { vel[0], vel[1], vel[2] };
for (int j=0; j < numPts; j++)
{
int id = GenCell->PointIds->GetId(j);
vectors2->GetTuple(id, vec);
for (int i=0; i < 3; i++)
vtkGenericCell *GenCell = vtkGenericCell::New();
ds->GetCell(cell, GenCell);
int numPts = GenCell->GetNumberOfPoints();
double closestPoint[3], dist2;
int subId;
int val = GenCell->EvaluatePosition(pt, closestPoint, subId, pcoords, dist2, weights);
if (val <= 0)
{
GenCell->Delete();
return false;
}
// interpolate the vectors
InterpVector(GenCell, numPts, vectors, weights, vel);
if (doPathlines)
{
vel2[i] += vec[i] * weights[j];
double vel2[3];
InterpVector(GenCell, numPts, vectors2, weights, vel2);
double prop1 = 1. - (t - curTime) / (nextTime - curTime);
vel[0] = prop1*vel[0] + (1-prop1)*vel2[0];
vel[1] = prop1*vel[1] + (1-prop1)*vel2[1];
vel[2] = prop1*vel[2] + (1-prop1)*vel2[2];
}
}
double prop1 = 1. - (t - curTime) / (nextTime - curTime);
vel[0] = prop1*vel1[0] + (1-prop1)*vel2[0];
vel[1] = prop1*vel1[1] + (1-prop1)*vel2[1];
vel[2] = prop1*vel1[2] + (1-prop1)*vel2[2];
GenCell->Delete();
}
GenCell->Delete();
return true;
}
static void
InterpVector(vtkGenericCell *cell, int numPts, vtkDataArray *vectors, double *weights, double *vel)
{
vel[0] = vel[1] = vel[2] = 0;
double vec[3];
for (int j=0; j < numPts; j++)
{
int id = cell->PointIds->GetId(j);
vectors->GetTuple(id, vec);
for (int i=0; i < 3; i++)
vel[i] += vec[i] * weights[j];
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment