Commit b323a65a authored by hrchilds's avatar hrchilds

Update from October 19, 2004

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@342 18c085ea-50e0-402c-830e-de6fd14e8384
parent aacb34a6
......@@ -20,7 +20,6 @@
#include <avtExtents.h>
#include <avtIOInformation.h>
#include <avtIntervalTree.h>
#include <avtMetaData.h>
#include <avtSIL.h>
#include <InvalidVariableException.h>
......@@ -270,6 +269,11 @@ avtDatabase::GetOutput(const char *var, int ts)
// Mark C. Miller, Tue Sep 28 19:32:50 PDT 2004
// Added argument for data selections that have been applied as well
// as code to populate data attributes
//
// Mark C. Miller, Tue Oct 19 14:08:56 PDT 2004
// Changed 'spec' arg to ref_ptr. Added code to attempt to get spatial/data
// extents trees and set true extents from those if available
//
// ****************************************************************************
void
......@@ -277,7 +281,7 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
const char *var,
int ts,
const vector<bool> &selectionsApplied,
avtDataSpecification *spec)
avtDataSpecification_p spec)
{
int i;
......@@ -288,6 +292,7 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
string mesh = GetMetaData(ts)->MeshForVar(var);
const avtMeshMetaData *mmd = GetMetaData(ts)->GetMesh(mesh);
bool haveSetTrueSpatialExtents = false;
if (mmd != NULL)
{
atts.SetCellOrigin(mmd->cellOrigin);
......@@ -321,6 +326,34 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
extents[2*i+1] = mmd->maxSpatialExtents[i];
}
atts.GetTrueSpatialExtents()->Set(extents);
haveSetTrueSpatialExtents = true;
}
}
//
// If we haven't set spatial extents, try using a data tree
//
if (haveSetTrueSpatialExtents == false)
{
VoidRefList list;
if (*spec != NULL)
{
avtDataSpecification_p tmp_spec = new avtDataSpecification(spec, -1);
GetAuxiliaryData(tmp_spec, list, AUXILIARY_DATA_SPATIAL_EXTENTS,
(void *) mesh.c_str());
}
if (list.nList == 1 && *(list.list[0]) != NULL)
{
avtIntervalTree *tree = (avtIntervalTree *) *(list.list[0]);
float extents[6];
tree->GetExtents(extents);
double dextents[6];
for (int i = 0; i < 6; i++)
dextents[i] = extents[i];
atts.GetTrueSpatialExtents()->Set(dextents);
haveSetTrueSpatialExtents = true;
}
}
......@@ -330,7 +363,7 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
//
vector<const char *> var_list;
var_list.push_back(var);
if (spec != NULL)
if (*spec != NULL)
{
const std::vector<CharStrRef> &secondaryVariables
= spec->GetSecondaryVariables();
......@@ -346,6 +379,7 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
//
for (i = 0 ; i < var_list.size() ; i++)
{
bool haveSetTrueDataExtents = false;
const avtScalarMetaData *smd = GetMetaData(ts)->GetScalar(var_list[i]);
if (smd != NULL)
{
......@@ -368,6 +402,7 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
extents[1] = smd->maxDataExtents;
atts.GetTrueDataExtents(var_list[i])->Set(extents);
haveSetTrueDataExtents = true;
}
}
......@@ -392,6 +427,34 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
extents[0] = vmd->minDataExtents;
extents[1] = vmd->maxDataExtents;
atts.GetTrueDataExtents(var_list[i])->Set(extents);
haveSetTrueDataExtents = true;
}
}
//
// If we haven't set data extents, try using a data tree
//
if (haveSetTrueDataExtents == false)
{
VoidRefList list;
if (*spec != NULL)
{
avtDataSpecification_p tmp_spec = new avtDataSpecification(spec, -1);
GetAuxiliaryData(tmp_spec, list, AUXILIARY_DATA_DATA_EXTENTS,
(void *) var_list[i]);
}
if (list.nList == 1 && *(list.list[0]) != NULL)
{
avtIntervalTree *tree = (avtIntervalTree *) *(list.list[0]);
float extents[2];
tree->GetExtents(extents);
double dextents[2];
for (int j = 0; j < 2; j++)
dextents[j] = extents[j];
atts.GetTrueDataExtents(var_list[i])->Set(dextents);
haveSetTrueDataExtents = true;
}
}
......@@ -452,7 +515,7 @@ avtDatabase::PopulateDataObjectInformation(avtDataObject_p &dob,
// an unfilled boundary. The way this is handles (by directly
// checking a data specification) needs to change.
//
if (spec && spec->NeedBoundarySurfaces())
if (*spec && spec->NeedBoundarySurfaces())
atts.SetTopologicalDimension(atts.GetTopologicalDimension() - 1);
char str[1024];
......
......@@ -185,6 +185,9 @@ typedef struct {
// Mark C. Miller, Tue Sep 28 19:57:42 PDT 2004
// Added argument for selections applied to PopulateDataObjectInformation
//
// Mark C. Miller, Tue Oct 19 14:08:56 PDT 2004
// Changed 'spec' arg of PopulateDataObjectInformation to a ref_ptr
//
// ****************************************************************************
class DATABASE_API avtDatabase
......@@ -273,7 +276,7 @@ class DATABASE_API avtDatabase
const char *,
int,
const vector<bool> &selsApplied,
avtDataSpecification* =NULL);
avtDataSpecification_p =NULL);
virtual bool QueryScalars(const std::string &, const int,
const int, const int,
const std::vector<int> &,
......
......@@ -38,7 +38,6 @@
#include <avtDomainBoundaries.h>
#include <avtDomainNesting.h>
#include <avtFileFormatInterface.h>
#include <avtMetaData.h>
#include <avtMixedVariable.h>
#include <avtParallel.h>
#include <avtSILGenerator.h>
......@@ -486,7 +485,7 @@ avtGenericDatabase::GetOutput(avtDataSpecification_p spec,
if (nDomains == 0)
dob->GetInfo().GetValidity().SetHasEverOwnedAnyDomain(false);
PopulateDataObjectInformation(dob, spec->GetVariable(), timeStep,
selectionsApplied, *spec);
selectionsApplied, spec);
return rv;
}
......@@ -1864,6 +1863,9 @@ avtGenericDatabase::GetMesh(const char *meshname, int ts, int domain,
// timesteps (for example, global node ids where the nodes don't change
// over time).
//
// Mark C. Miller, Mon Oct 18 13:02:37 PDT 2004
// Added code to set variable name from 'args' for Data/Spatial extents
//
// ****************************************************************************
void
......@@ -1878,8 +1880,14 @@ avtGenericDatabase::GetAuxiliaryData(avtDataSpecification_p spec,
// tree (which it represents as domain -1).
//
int ts = spec->GetTimestep();
const char *var = spec->GetVariable();
avtSILSpecification sil = spec->GetSIL();
const char *var = spec->GetVariable();
if ((strcmp(type, AUXILIARY_DATA_SPATIAL_EXTENTS) == 0) ||
(strcmp(type, AUXILIARY_DATA_DATA_EXTENTS) == 0))
{
if (args != NULL)
var = (char *) args;
}
vector<int> domains;
sil.GetDomainList(domains);
......
......@@ -63,7 +63,8 @@ avtResampleFilter.C avtSamplePointCommunicator.C avtSamplePointExtractor.C \
avtSamplePointToSurfaceFilter.C avtShiftCenteringFilter.C \
avtSimilarityTransformFilter.C avtSmoothPolyDataFilter.C \
avtSummationFilter.C avtTransform.C avtVertexNormalsFilter.C \
avtWholeImageCompositer.C avtWorldSpaceToImageSpaceTransform.C
avtWholeImageCompositerWithZ.C avtWholeImageCompositerNoZ.C \
avtWorldSpaceToImageSpaceTransform.C
CPPFLAGS=@COMPONENT_CPPFLAGS@ @CPPFLAGS@
......
......@@ -47,7 +47,7 @@ avtImageCompositer::avtImageCompositer()
avtImageCompositer::~avtImageCompositer()
{
;
inputImages.clear();
}
......
......@@ -4,7 +4,9 @@
#ifndef AVT_WHOLE_IMAGE_COMPOSITER_H
#define AVT_WHOLE_IMAGE_COMPOSITER_H
#include <filters_exports.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
......@@ -14,27 +16,30 @@
// ****************************************************************************
// Class: avtWholeImageCompositer
//
// Purpose:
// An image compositor based largely on MeshTV's image compositer.
// The key limitation of this image compositer is that it assumes that
// every piece of image to be composited has origin 0,0 and size of the
// intended output image. That is, every piece being composited is a
// Purpose: Base class for whole image compositors. That is a compositor in
// which every piece of image to be composited has origin 0,0 and size
// of the intended output image. Every piece being composited is a
// whole image. All the algorithms for chunking and message passing
// depend on this being the case.
//
// Programmer: Mark C. Miller
// Creation: February 12, 2003
//
// Modifications:
//
// Mark C. Miller, Tue Oct 19 15:35:12 PDT 2004
// Turned into a base class
//
// ****************************************************************************
class AVTFILTERS_API avtWholeImageCompositer : public avtImageCompositer
{
public:
avtWholeImageCompositer();
virtual ~avtWholeImageCompositer();
avtWholeImageCompositer() {
chunkSize = 1000000;
bg_r = 255; bg_g = 255; bg_b = 255; };
const char *GetType(void);
const char *GetDescription(void);
virtual ~avtWholeImageCompositer() {};
void SetChunkSize(const int chunkSize);
int GetChunkSize() const;
......@@ -42,38 +47,17 @@ class AVTFILTERS_API avtWholeImageCompositer : public avtImageCompositer
unsigned char g,
unsigned char b);
void Execute();
private:
friend void MergeBuffers(avtWholeImageCompositer *thisObj,
int npixels, bool doParallel,
const float *inz, const unsigned char *inrgb,
float *ioz, unsigned char *iorgb);
virtual void Execute() = 0;
static int objectCount;
protected:
int chunkSize;
unsigned char bg_r;
unsigned char bg_g;
unsigned char bg_b;
static void InitializeMPIStuff();
static void FinalizeMPIStuff();
#ifdef PARALLEL
static MPI_Datatype mpiTypeZFPixel;
static MPI_Op mpiOpMergeZFPixelBuffers;
#endif
};
inline const char* avtWholeImageCompositer::GetType()
{ return "avtWholeImageCompositer";}
inline const char* avtWholeImageCompositer::GetDescription()
{ return "performing whole-image composite"; }
inline void avtWholeImageCompositer::SetChunkSize(const int _chunkSize)
{ chunkSize = _chunkSize; }
......
// ************************************************************************* //
// avtWholeImageCompositerNoZ.C //
// ************************************************************************* //
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include <avtParallel.h>
#include <avtWholeImageCompositerNoZ.h>
#include <vtkImageData.h>
#include <ImproperUseException.h>
typedef struct zfpixel {
unsigned char r;
unsigned char g;
unsigned char b;
} ZFPixel_t;
// place holders for global data used in MergeZFPixelBuffers
static unsigned char local_bg_r;
static unsigned char local_bg_g;
static unsigned char local_bg_b;
// ****************************************************************************
// Function: MergeZFPixelBuffers
//
// Purpose: User-defined function for MPI_Op_create. Will be used
// to perform collective buffer merge operations. Merges
// frame and z-buffers.
//
// Programmer: Mark C. Miller (plagerized from Katherine Price)
// Date: 26Feb03
// ****************************************************************************
static void
#ifdef PARALLEL
MergeZFPixelBuffers(void *ibuf, void *iobuf, int *count, MPI_Datatype *datatype)
#else
MergeZFPixelBuffers(void *ibuf, void *iobuf, int *count, void *datatype)
#endif
{
ZFPixel_t *in_zfpixels = (ZFPixel_t *) ibuf;
ZFPixel_t *inout_zfpixels = (ZFPixel_t *) iobuf;
int i;
// quiet the compiler
datatype = datatype;
for (i = 0; i < *count; i++)
{
{
if ((inout_zfpixels[i].r == local_bg_r) &&
(inout_zfpixels[i].g == local_bg_g) &&
(inout_zfpixels[i].b == local_bg_b))
{
// Since 'inout' is background color, take whatever
// is in 'in' even if it too is background color
inout_zfpixels[i].r = in_zfpixels[i].r;
inout_zfpixels[i].g = in_zfpixels[i].g;
inout_zfpixels[i].b = in_zfpixels[i].b;
}
else if ((in_zfpixels[i].r != local_bg_r) ||
(in_zfpixels[i].g != local_bg_g) ||
(in_zfpixels[i].b != local_bg_b))
{
// Neither 'inout' nor 'in' is the background color.
// So, average them.
float newr = (float) in_zfpixels[i].r +
(float) inout_zfpixels[i].r;
float newg = (float) in_zfpixels[i].g +
(float) inout_zfpixels[i].g;
float newb = (float) in_zfpixels[i].b +
(float) inout_zfpixels[i].b;
inout_zfpixels[i].r = (unsigned char) (newr / 2.0);
inout_zfpixels[i].g = (unsigned char) (newg / 2.0);
inout_zfpixels[i].b = (unsigned char) (newb / 2.0);
}
}
}
}
// declare initialize static data members
int avtWholeImageCompositerNoZ::objectCount = 0;
#ifdef PARALLEL
MPI_Op avtWholeImageCompositerNoZ::mpiOpMergeZFPixelBuffers = MPI_OP_NULL;
MPI_Datatype avtWholeImageCompositerNoZ::mpiTypeZFPixel;
// ****************************************************************************
// Function: InitializeMPIStuff
//
// Purpose: Build MPI objects necessary to support avtWholeImageCompositerNoZ
// class.
//
// Programmer: Mark C. Miller
// Date: 01Apr03
// ****************************************************************************
void
avtWholeImageCompositerNoZ::InitializeMPIStuff(void)
{
MPI_Type_contiguous(3, MPI_UNSIGNED_CHAR, &avtWholeImageCompositerNoZ::mpiTypeZFPixel);
MPI_Type_commit(&avtWholeImageCompositerNoZ::mpiTypeZFPixel);
MPI_Op_create(MergeZFPixelBuffers, 1,
&avtWholeImageCompositerNoZ::mpiOpMergeZFPixelBuffers);
}
// ****************************************************************************
// Function: FinalizeMPIStuff
//
// Purpose: Free MPI objects used support avtWholeImageCompositerNoZ class.
//
// Programmer: Mark C. Miller
// Date: 01Apr03
// ****************************************************************************
void
avtWholeImageCompositerNoZ::FinalizeMPIStuff(void)
{
MPI_Op_free(&avtWholeImageCompositerNoZ::mpiOpMergeZFPixelBuffers);
MPI_Type_free(&avtWholeImageCompositerNoZ::mpiTypeZFPixel);
}
#else
void avtWholeImageCompositerNoZ::InitializeMPIStuff(void) {;}
void avtWholeImageCompositerNoZ::FinalizeMPIStuff(void) {;}
#endif
// ****************************************************************************
// Method: avtWholeImageCompositerNoZ constructor
//
// Programmer: Mark C. Miller
// Creation: February 12, 2003
//
// Modifications:
// Mark C. Miller, Tue Mar 30 10:58:01 PST 2004
// Added code to initialize background color
//
// ****************************************************************************
avtWholeImageCompositerNoZ::avtWholeImageCompositerNoZ()
{
if (avtWholeImageCompositerNoZ::objectCount == 0)
InitializeMPIStuff();
avtWholeImageCompositerNoZ::objectCount++;
}
// ****************************************************************************
// Method: avtWholeImageCompositerNoZ destructor
//
// Programmer: Mark C. Miller
// Creation: February 18, 2003
//
// ****************************************************************************
avtWholeImageCompositerNoZ::~avtWholeImageCompositerNoZ()
{
avtWholeImageCompositerNoZ::objectCount--;
if (avtWholeImageCompositerNoZ::objectCount == 0)
FinalizeMPIStuff();
}
// ****************************************************************************
// Method: Execute
//
// Purpose: Perform the composite
//
// Programmer: Mark C. Miller (modified from orig code by Kat Price)
// Creation: February 18, 2003
//
// ****************************************************************************
void
avtWholeImageCompositerNoZ::Execute(void)
{ int i, numRows, numCols;
unsigned char *iorgb, *riorgb;
vtkImageData *mergedLocalImage, *mergedGlobalImage;
// sanity checks
if (inputImages.size() == 0)
EXCEPTION0(ImproperUseException);
for (i = 0; i < inputImages.size(); i++)
{
inputImages[i]->GetImage().GetSize(&numRows, &numCols);
if (numRows != outRows || numCols != outCols)
EXCEPTION0(ImproperUseException);
}
int nPixels = outRows * outCols;
avtImageRepresentation &zeroImageRep = inputImages[0]->GetImage();
if (inputImages.size() > 1)
{
//
// Merge within a processor
//
mergedLocalImage = avtImageRepresentation::NewImage(outCols, outRows);
iorgb = (unsigned char *) mergedLocalImage->GetScalarPointer(0, 0, 0);
const unsigned char *rgb0 = zeroImageRep.GetRGBBuffer();
// we memcpy because we can't alter any of the input images
memcpy(iorgb, rgb0, nPixels * 3 * sizeof(unsigned char));
// do the merges, accumulating results in ioz and iorgb
for (i = 1; i < inputImages.size(); i++)
{
const unsigned char *rgb = inputImages[i]->GetImage().GetRGBBuffer();
MergeBuffers(nPixels, false, rgb, iorgb);
}
}
else
{
mergedLocalImage = NULL;
iorgb = zeroImageRep.GetRGBBuffer();
}
if (mpiRoot >= 0)
{
// only root allocates output AVT imge
if (mpiRank == mpiRoot)
{
mergedGlobalImage = avtImageRepresentation::NewImage(outCols, outRows);
riorgb = (unsigned char *) mergedGlobalImage->GetScalarPointer(0, 0, 0);
}
//
// Merge across processors
//
MergeBuffers(nPixels, true, iorgb, riorgb);
if (mergedLocalImage != NULL)
{
mergedLocalImage->Delete();
}
if (mpiRank == mpiRoot)
{
{
avtImageRepresentation theOutput(mergedGlobalImage);
SetOutputImage(theOutput);
}
mergedGlobalImage->Delete();
}
else
{
avtImageRepresentation theOutput(NULL);
SetOutputImage(theOutput);
}
}
else
{
if (mergedLocalImage != NULL)
{
{
avtImageRepresentation theOutput(mergedLocalImage);
SetOutputImage(theOutput);
}
mergedLocalImage->Delete();
}
else
{
{
avtImageRepresentation theOutput(zeroImageRep.GetImageVTK());
SetOutputImage(theOutput);
}
}
}
}
// ****************************************************************************
// Function: MergeBuffers
//
// Purpose: Merge images represented by separate z and rgb buffers.
// The merge is broken into chunks to help MPI to digest it and
// to reduce peak memory usage.
//
// Issues: A combination of several different constraints conspire to
// create a problem with getting background color information
// into the MPI reduce operator, MergeZFPixelBuffers. So, to
// get around this problem, we pass the background color as
// the last ZFPixel entry in the array of ZFPixels. We allocate
// one extr ZFPixel for this purpose.
//
//
// Programmer: Mark C. Miller (plagerized from Kat Price's MeshTV version)