Commit 1627a5da authored by hrchilds's avatar hrchilds

Update from March 19, 2004

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@201 18c085ea-50e0-402c-830e-de6fd14e8384
parent f94a9da5
......@@ -4,6 +4,8 @@
#include <avtDataAttributes.h>
#include <algorithm>
#include <avtDataObjectString.h>
#include <avtDataObjectWriter.h>
#include <avtExtents.h>
......@@ -15,6 +17,7 @@
using std::string;
using std::vector;
using std::sort;
// ****************************************************************************
......@@ -1734,28 +1737,58 @@ avtDataAttributes::Read(char *input)
// Progammer: Kathleen Bonnell
// Creation: September 19, 2001
//
// Modifications:
//
// Hank Childs, Thu Mar 18 20:20:48 PST 2004
// Re-wrote to avoid a quadratic performance.
//
// ****************************************************************************
void
avtDataAttributes::MergeLabels(const vector<string> &l)
{
bool found = false;
for (int i = 0; i < l.size(); i++)
if (labels.size() == l.size())
{
for (int j = 0; j < labels.size(); j++)
{
if ( l[i] == labels[j] )
bool foundDifference = false;
for (int i = 0 ; i < labels.size() ; i++)
if (labels[i] != l[i])
{
found = true;
foundDifference = true;
break;
}
}
if (!found)
if (!foundDifference)
return;
}
vector<string> list1 = l;
vector<string> list2 = labels;
sort(list1.begin(), list1.end());
sort(list2.begin(), list2.end());
int list1_counter = 0;
int list2_counter = 0;
vector<string> master_list;
while ((list1_counter < list1.size()) || (list2_counter < list2.size()))
{
if ((list1_counter < list1.size()) && (list2_counter < list2.size()))
{
labels.push_back(l[i]);
if (list1[list1_counter] == list2[list2_counter])
{
master_list.push_back(list1[list1_counter]);
list1_counter++;
list2_counter++;
}
else if (list1[list1_counter] < list2[list2_counter])
master_list.push_back(list1[list1_counter++]);
else
master_list.push_back(list2[list2_counter++]);
}
found = false;
else if (list1_counter < list1.size())
master_list.push_back(list1[list1_counter++]);
else
master_list.push_back(list2[list2_counter++]);
}
labels = master_list;
}
......
......@@ -25,6 +25,12 @@
using std::string;
//
// Static members
//
bool avtDataRepresentation::initializedNullDataset = false;
vtkDataSet *avtDataRepresentation::nullDataset = NULL;
//
// Function Prototypes
//
......@@ -83,22 +89,21 @@ avtDataRepresentation::avtDataRepresentation()
// Hank Childs, Thu Sep 27 16:43:27 PDT 2001
// Initialized datasetType.
//
// Hank Childs, Wed Mar 17 19:21:22 PST 2004
// Make use of the null dataset to make sure we don't blow memory in SR-mode
//
// ****************************************************************************
avtDataRepresentation::avtDataRepresentation(vtkDataSet *d, int dom, string s,
bool dontCopyData)
{
InitializeNullDataset();
if (dontCopyData)
{
// build the points object (not a vtkDataSet object)
vtkPoints *dummyPoints = vtkPoints::New();
vtkUnstructuredGrid *dummyGrid = vtkUnstructuredGrid::New();
dummyPoints->SetNumberOfPoints(0);
dummyGrid->SetPoints(dummyPoints);
asVTK = dummyGrid;
asVTK = nullDataset;
datasetType = DATASET_TYPE_NULL;
asVTK->Register(NULL);
dummyPoints->Delete();
dummyGrid->Delete();
}
else
{
......@@ -398,36 +403,49 @@ avtDataRepresentation::GetNumberOfCells(int topoDim, bool polysOnly) const
// Hank Childs, Thu Sep 27 16:43:27 PDT 2001
// Added return value for dataset type.
//
// Hank Childs, Wed Mar 17 19:21:22 PST 2004
// Make use of the null dataset to make sure we don't blow memory in SR-mode
//
// ****************************************************************************
unsigned char *
avtDataRepresentation::GetDataString(int &length, DataSetType &dst)
{
InitializeNullDataset();
if (asChar == NULL)
{
if (asVTK == NULL)
{
EXCEPTION0(NoInputException);
}
dst = DatasetTypeForVTK(asVTK);
datasetType = dst;
vtkDataSetWriter *writer = vtkDataSetWriter::New();
writer->SetInput(asVTK);
writer->SetWriteToOutputString(1);
writer->SetFileTypeToBinary();
writer->Write();
asCharLength = writer->GetOutputStringLength();
asChar = (unsigned char *) writer->RegisterAndGetOutputString();
originalString = (char *)asChar;
writer->Delete();
else if (asVTK == nullDataset)
{
dst = DATASET_TYPE_NULL;
asCharLength = 0;
asChar = NULL;
}
else
{
dst = DatasetTypeForVTK(asVTK);
datasetType = dst;
vtkDataSetWriter *writer = vtkDataSetWriter::New();
writer->SetInput(asVTK);
writer->SetWriteToOutputString(1);
writer->SetFileTypeToBinary();
writer->Write();
asCharLength = writer->GetOutputStringLength();
asChar = (unsigned char *) writer->RegisterAndGetOutputString();
originalString = (char *)asChar;
writer->Delete();
}
}
else
{
dst = datasetType;
}
length = asCharLength;
return asChar;
}
......@@ -456,97 +474,147 @@ avtDataRepresentation::GetDataString(int &length, DataSetType &dst)
// Make use of new VTK method that avoids making an unnecessary copy of the
// data.
//
// Hank Childs, Wed Mar 17 19:21:22 PST 2004
// Make use of the null dataset to make sure we don't blow memory in SR-mode
//
// ****************************************************************************
vtkDataSet *
avtDataRepresentation::GetDataVTK(void)
{
InitializeNullDataset();
if (asVTK == NULL)
{
if (asChar == NULL)
{
EXCEPTION0(NoInputException);
}
vtkDataReader *reader = NULL;
vtkDataSetReader *dsreader = NULL;
bool readerIsAFrontEnd = false;
switch (datasetType)
{
case DATASET_TYPE_RECTILINEAR:
{
vtkRectilinearGridReader *r1 = vtkRectilinearGridReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
case DATASET_TYPE_CURVILINEAR:
{
vtkStructuredGridReader *r1 = vtkStructuredGridReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
case DATASET_TYPE_UNSTRUCTURED:
{
vtkUnstructuredGridReader *r1 = vtkUnstructuredGridReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
case DATASET_TYPE_POLYDATA:
{
vtkPolyDataReader *r1 = vtkPolyDataReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
default:
{
debug1 << "Entered the VTK DATASET READER case. "
<< "This should not happen." << endl;
dsreader = vtkDataSetReader::New();
reader = dsreader;
readerIsAFrontEnd = true;
break;
}
}
vtkCharArray *charArray = vtkCharArray::New();
int iOwnIt = 1; // 1 means we own it -- you don't delete it.
charArray->SetArray((char *) asChar, asCharLength, iOwnIt);
reader->SetReadFromInputString(1);
reader->SetInputArray(charArray);
if (readerIsAFrontEnd)
else if (datasetType == DATASET_TYPE_NULL)
{
//
// Readers that are a front end to other readers automatically
// do an Update when you get their output. That is why we are
// waiting to get their output here (->after we set the string
// input).
//
asVTK = dsreader->GetOutput();
asVTK = nullDataset;
asVTK->Register(NULL);
}
else
{
asVTK->Update();
vtkDataReader *reader = NULL;
vtkDataSetReader *dsreader = NULL;
bool readerIsAFrontEnd = false;
switch (datasetType)
{
case DATASET_TYPE_RECTILINEAR:
{
vtkRectilinearGridReader *r1 = vtkRectilinearGridReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
case DATASET_TYPE_CURVILINEAR:
{
vtkStructuredGridReader *r1 = vtkStructuredGridReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
case DATASET_TYPE_UNSTRUCTURED:
{
vtkUnstructuredGridReader *r1 =
vtkUnstructuredGridReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
case DATASET_TYPE_POLYDATA:
{
vtkPolyDataReader *r1 = vtkPolyDataReader::New();
reader = r1;
asVTK = r1->GetOutput();
readerIsAFrontEnd = false;
break;
}
default:
{
debug1 << "Entered the VTK DATASET READER case. "
<< "This should not happen." << endl;
dsreader = vtkDataSetReader::New();
reader = dsreader;
readerIsAFrontEnd = true;
break;
}
}
vtkCharArray *charArray = vtkCharArray::New();
int iOwnIt = 1; // 1 means we own it -- you don't delete it.
charArray->SetArray((char *) asChar, asCharLength, iOwnIt);
reader->SetReadFromInputString(1);
reader->SetInputArray(charArray);
if (readerIsAFrontEnd)
{
//
// Readers that are a front end to other readers automatically
// do an Update when you get their output. That is why we are
// waiting to get their output here (->after we set the string
// input).
//
asVTK = dsreader->GetOutput();
}
else
{
asVTK->Update();
}
asVTK->Register(NULL);
asVTK->SetSource(NULL);
reader->Delete();
charArray->Delete();
}
asVTK->Register(NULL);
asVTK->SetSource(NULL);
reader->Delete();
charArray->Delete();
}
return asVTK;
}
// ****************************************************************************
// Method: avtDataRepresentation::InitializeNullDataset
//
// Purpose:
// The null dataset is used to represent that the contents of a tree
// are not present (because we are in scalable rendering mode). Prior
// to using the null dataset (which is a singleton), each node of a tree
// got its own, personal null dataset. In cases where there were 10,000
// domains, this was a large memory hit. For this reason, all of the
// nodes now share this single null dataset. The null dataset is a
// static to the avt data representation class. It is important that
// any method that might reference the null dataset call this routine
// first.
//
// Programmer: Hank Childs
// Creation: March 17, 2004
//
// ****************************************************************************
void
avtDataRepresentation::InitializeNullDataset(void)
{
if (initializedNullDataset)
return;
// build the points object (not a vtkDataSet object)
vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New();
vtkPoints *dummyPoints = vtkPoints::New();
dummyPoints->SetNumberOfPoints(0);
ugrid->SetPoints(dummyPoints);
dummyPoints->Delete();
nullDataset = ugrid;
initializedNullDataset = true;
}
// ****************************************************************************
// Function: DatasetTypeForVTK
//
......@@ -561,11 +629,21 @@ avtDataRepresentation::GetDataVTK(void)
// Programmer: Hank Childs
// Creation: September 27, 2001
//
// Modifications:
//
// Hank Childs, Wed Mar 17 19:51:05 PST 2004
// Account for the null dataset.
//
// ****************************************************************************
DataSetType
DatasetTypeForVTK(vtkDataSet *ds)
avtDataRepresentation::DatasetTypeForVTK(vtkDataSet *ds)
{
InitializeNullDataset();
if (ds == nullDataset)
return DATASET_TYPE_NULL;
DataSetType rv = DATASET_TYPE_UNKNOWN;
int vtktype = ds->GetDataObjectType();
......
......@@ -19,6 +19,7 @@ typedef enum
DATASET_TYPE_CURVILINEAR,
DATASET_TYPE_UNSTRUCTURED,
DATASET_TYPE_POLYDATA,
DATASET_TYPE_NULL,
DATASET_TYPE_UNKNOWN
} DataSetType;
......@@ -52,6 +53,9 @@ typedef enum
// Added member 'label' and retrieval method. Modifed constructor to
// include the label.
//
// Hank Childs, Wed Mar 17 19:16:48 PST 2004
// Added a static null dataset to prevent unnecessary memory usage with SR.
//
// ****************************************************************************
class PIPELINE_API avtDataRepresentation
......@@ -85,6 +89,12 @@ class PIPELINE_API avtDataRepresentation
int domain;
std::string label;
static bool initializedNullDataset;
static vtkDataSet *nullDataset;
static void InitializeNullDataset(void);
static DataSetType DatasetTypeForVTK(vtkDataSet *);
};
......
......@@ -212,6 +212,13 @@ avtSpecies::Initialize(const vector<int> ns,
// Programmer: Jeremy Meredith
// Creation: November 19, 2003
//
// Modifications:
// Jeremy Meredith, Fri Mar 19 10:53:22 PST 2004
// I added a check to make sure there was a valid string for a species
// name in a material with only one species. It seems reasonable for
// databases to not provide a name for the species in a material with
// only one, so I provided a default name.
//
// ****************************************************************************
vector<CellSpecInfo>
avtSpecies::ExtractCellSpecInfo(int c, int m, avtMaterial *mat)
......@@ -247,7 +254,10 @@ avtSpecies::ExtractCellSpecInfo(int c, int m, avtMaterial *mat)
if (specindex == 0)
{
// A zero indicates only one species in this material
info.push_back(CellSpecInfo(species[m][0], 1.0));
if (nSpecies[m] > 0)
info.push_back(CellSpecInfo(species[m][0], 1.0));
else
info.push_back(CellSpecInfo("(single species)", 1.0));
}
else if (specindex > 0)
{
......
......@@ -112,6 +112,9 @@ avtDataSetWriter::DataObjectWrite(avtDataObjectString &str)
// Hank Childs, Mon Oct 1 09:16:42 PDT 2001
// Removed objwriter argument.
//
// Hank Childs, Wed Mar 17 20:40:56 PST 2004
// Reduce the number of socket writes.
//
// ****************************************************************************
void
......@@ -148,27 +151,28 @@ avtDataSetWriter::WriteDataTree(avtDataTree_p tree, avtDataObjectString &str)
else
{
int len;
int lengthAndChunkAndDST[3];
int lengthAndChunkAndDSTAndLabel[4];
unsigned char * s;
DataSetType dst;
// get the domain string and its length
s = tree->GetDataRepresentation().GetDataString(len, dst);
lengthAndChunkAndDST[0] = len;
lengthAndChunkAndDSTAndLabel[0] = len;
// write out the length
// write out the chunk index
int chunk = tree->GetDataRepresentation().GetDomain();
lengthAndChunkAndDST[1] = chunk;
lengthAndChunkAndDSTAndLabel[1] = chunk;
// write out the dataset's type.
lengthAndChunkAndDST[2] = dst;
WriteInt(str, lengthAndChunkAndDST, 3);
lengthAndChunkAndDSTAndLabel[2] = dst;
// write out the label
string label = tree->GetDataRepresentation().GetLabel();
WriteInt(str, label.size());
lengthAndChunkAndDSTAndLabel[3] = label.size();
WriteInt(str, lengthAndChunkAndDSTAndLabel, 4);
if (label.size() > 0)
{
str.Append((char *) label.c_str(), label.size(),
......@@ -176,8 +180,11 @@ avtDataSetWriter::WriteDataTree(avtDataTree_p tree, avtDataObjectString &str)
}
// write out the string
str.Append((char*) s, len,
if (len > 0)
{
str.Append((char*) s, len,
avtDataObjectString::DATA_OBJECT_STRING_DOES_NOT_OWN_REFERENCE);
}
}
}
......
......@@ -296,6 +296,9 @@ avtMapper::GetDrawable(void)
// Brad Whitlock, Mon Sep 23 16:56:50 PST 2002
// Changed the immediate mode rendering test so it uses a new member.
//
// Hank Childs, Thu Mar 18 16:02:27 PST 2004
// Do not create actors and mappers for empty datasets.
//
// ****************************************************************************
void
......@@ -330,13 +333,6 @@ avtMapper::SetUpMappers(void)
mappers = new vtkDataSetMapper*[nMappers];
actors = new vtkActor*[nMappers];
// if there was an exception upstream, then we may get false leaves.
// Bottom line is that all of the logic below should initialize the mappers
// in case there was a problem, so let's initialize them just in case.
// Kat's note 21 Sep 01: now that tree's are compacted, this
// initialization is probably no longer necesary, but I will leave it in
// for now, just in case.
//
for (int j = 0 ; j < nMappers ; j++)
{
mappers[j] = NULL;
......@@ -345,6 +341,12 @@ avtMapper::SetUpMappers(void)
SetUpFilters(nMappers);
for (int i = 0; i < nMappers; i++)
{
// We might have some dummy data (SR-mode). If so, just continue.
if (children[i] == NULL)
continue;
if (children[i]->GetNumberOfCells() <= 0)
continue;
mappers[i] = CreateMapper();
vtkDataSet *ds = InsertFilters(children[i], i);
mappers[i]->SetInput(ds);
......
......@@ -49,6 +49,10 @@ using std::string;
// Static data
Engine *Engine::instance = NULL;
// Static method
static void WriteByteStreamToSocket(NonBlockingRPC *, Connection *,
avtDataObjectString &);
#if defined(_WIN32)
// Get around a macro problem
#define GetMessageA GetMessage
......@@ -704,6 +708,85 @@ Engine::AlarmHandler(int signal)
exit(0);
}
// ****************************************************************************
// Method: WriteByteStreamToSocket
//
// Purpose:
// Writes a byte stream to a socket.
//
// Programmer: Hank Childs