Commit a50d50c1 authored by hrchilds's avatar hrchilds
Browse files

Update from July 16, 2004

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@281 18c085ea-50e0-402c-830e-de6fd14e8384
parent 346e6392
......@@ -37,6 +37,10 @@
# Brad Whitlock, Mon Jul 28 17:09:09 PST 2003
# I added makemovie.py to the list of files that get distributed.
#
# Jeremy Meredith, Fri Jul 16 08:59:15 PDT 2004
# Renamed the MOC target so it would always get rebuilt. There wasn't
# enough dependency information to determine if the Qt version changed.
#
##############################################################################
@SET_MAKE@
......@@ -45,9 +49,9 @@
DISTRIB= install-sh visit makemovie.py
NOT_DISTRIB= run_doxygen
all: moc
all: mocprogram
moc:
mocprogram:
if test -n "@QTDIR@"; then \
$(RM) moc ; \
ln -s @QTDIR@/bin/moc moc ; \
......
......@@ -176,6 +176,9 @@
# Jeremy Meredith, Wed Jul 7 12:12:52 PDT 2004
# I changed _ser.o to simply be .o.
#
# Brad Whitlock, Thu Jul 15 15:54:25 PST 2004
# Added avtImageTiler.C
#
##############################################################################
@SET_MAKE@
......@@ -245,6 +248,7 @@ Pipeline_src= \
Pipeline/avtDataSetWriter.C \
Pipeline/avtDataSpecification.C \
Pipeline/avtImageReader.C \
Pipeline/avtImageTiler.C \
Pipeline/avtImageWriter.C \
Pipeline/avtNullDataReader.C \
Pipeline/avtNullDataWriter.C \
......
#include <avtImageTiler.h>
#include <BadIndexException.h>
#include <vtkImageData.h>
// ****************************************************************************
// Method: avtImageTiler::avtImageTiler
//
// Purpose:
// Constructor for the avtImageTiler class.
//
// Arguments:
// nImg : The maximum number of images in the tiled image.
//
// Programmer: Brad Whitlock
// Creation: Thu Jul 15 17:04:01 PST 2004
//
// Modifications:
//
// ****************************************************************************
avtImageTiler::avtImageTiler(int nImg)
{
maxImages = nImg;
nImages = 0;
images = new avtImage_p[maxImages];
}
// ****************************************************************************
// Method: avtImageTiler::~avtImageTiler
//
// Purpose:
// Destructor for the avtImageTiler class.
//
// Programmer: Brad Whitlock
// Creation: Thu Jul 15 17:04:33 PST 2004
//
// Modifications:
//
// ****************************************************************************
avtImageTiler::~avtImageTiler()
{
// Delete the images in the array.
for(int i = 0; i < maxImages; ++i)
images[i] = 0;
// Delete the array storage.
delete [] images;
}
// ****************************************************************************
// Method: avtImageTiler::AddImage
//
// Purpose:
// Adds an image to the list of images to be added as a tile.
//
// Arguments:
// img : A pointer to the image to be added as a tile.
//
// Programmer: Brad Whitlock
// Creation: Thu Jul 15 17:04:53 PST 2004
//
// Modifications:
//
// ****************************************************************************
void
avtImageTiler::AddImage(avtImage_p img)
{
if(*img == 0)
{
EXCEPTION0(VisItException);
}
if(nImages < maxImages)
{
images[nImages++] = img;
}
else
{
EXCEPTION2(BadIndexException,(nImages+1), maxImages);
}
}
// ****************************************************************************
// Method: avtImageTiler::GetNumberOfColumnsForNTiles
//
// Purpose:
// Returns the number of columns in the tiled image for the number of tiles.
//
// Arguments:
// nTiles : The number of tiles.
//
// Returns: The number of columns to use.
//
// Programmer: Brad Whitlock
// Creation: Thu Jul 15 17:05:48 PST 2004
//
// Modifications:
//
// ****************************************************************************
int
avtImageTiler::GetNumberOfColumnsForNTiles(int nTiles) const
{
const int maxTilesPerRow[] = {1,1,2,3,2,3,3,4,4,3,4,4,4,4,4,4,4};
int retval = 4;
if(nTiles >= 0 && nTiles <= 16)
retval = maxTilesPerRow[nTiles];
return retval;
}
// ****************************************************************************
// Method: avtImageTiler::GetNumberOfRowsForNTiles
//
// Purpose:
// Returns the number of rows in the tiled image for the number of tiles.
//
// Arguments:
// nTiles : The number of tiles.
//
// Returns: The number of rows to use.
//
// Programmer: Brad Whitlock
// Creation: Thu Jul 15 17:05:48 PST 2004
//
// Modifications:
//
// ****************************************************************************
int
avtImageTiler::GetNumberOfRowsForNTiles(int nTiles) const
{
int nCols = GetNumberOfColumnsForNTiles(nTiles);
int nRows = nTiles / nCols;
if(nRows * nCols < nTiles)
++nRows;
return nRows;
}
// ****************************************************************************
// Method: avtImageTiler::CreateTiledImage
//
// Purpose:
// Creates a tiled image and returns it.
//
// Returns: An avtImage_p containing the new tiled image.
//
// Note:
//
// Programmer: Brad Whitlock
// Creation: Thu Jul 15 17:06:50 PST 2004
//
// Modifications:
//
// ****************************************************************************
avtImage_p
avtImageTiler::CreateTiledImage()
{
int tilesPerRow = GetNumberOfColumnsForNTiles(nImages);
int nRows = GetNumberOfRowsForNTiles(nImages);
//
// Find the maximum size of the images so we can try to tile images with
// different sizes.
//
int tileWidth = 0, tileHeight = 0;
images[0]->GetImage().GetSize(&tileHeight, &tileWidth);
for(int i = 1; i < nImages; ++i)
{
int w, h;
images[i]->GetImage().GetSize(&h, &w);
tileWidth = (tileWidth < w) ? w : tileWidth;
tileHeight = (tileHeight < h) ? h : tileHeight;
}
//
// Create a vtkImageData object to contain the tiled image.
//
int totalWidth = tileWidth * tilesPerRow;
int totalHeight = tileHeight * nRows;
const int nColorComponents = 3;
vtkImageData *newImage = vtkImageData::New();
newImage->SetDimensions(totalWidth, totalHeight, 1);
newImage->SetScalarTypeToUnsignedChar();
newImage->SetNumberOfScalarComponents(nColorComponents);
newImage->AllocateScalars();
unsigned char *output = (unsigned char *)newImage->GetScalarPointer();
//
// Tile the input images into the final image.
//
int outScanY = 0;
int srcStart = 0;
const unsigned char bgR = 255;
const unsigned char bgG = 255;
const unsigned char bgB = 255;
for(int row = 0; row < nRows; ++row)
{
for(int y = tileHeight-1; y >= 0; --y, ++outScanY)
{
unsigned char *outputRow = output + ((totalHeight-1-outScanY) *
nColorComponents * totalWidth);
unsigned char *p = outputRow;
for(int s = srcStart; s < srcStart + tilesPerRow; ++s)
{
int x;
if(s < nImages)
{
int imgWidth = 0, imgHeight = 0;
images[s]->GetImage().GetSize(&imgHeight, &imgWidth);
vtkImageData *img = images[s]->GetImage().GetImageVTK();
int dY1 = (tileHeight - imgHeight) / 2;
if(y >= dY1 && y < (dY1 + imgHeight))
{
int dX1 = (tileWidth - imgWidth) / 2;
int dX2 = tileWidth - imgWidth - dX1;
// Pad the left side of the image.
for(x = 0; x < dX1; ++x)
{
*p++ = bgR;
*p++ = bgG;
*p++ = bgB;
}
//
// Fill in the pixels.
//
if(img->GetNumberOfScalarComponents() == 4)
{
unsigned char *srcRow =
((unsigned char *)img->GetScalarPointer()) +
((y-dY1) * imgWidth * 4);
for(x = 0; x < imgWidth; ++x)
{
*p++ = *srcRow++;
*p++ = *srcRow++;
*p++ = *srcRow++;
srcRow++;
}
}
else if(img->GetNumberOfScalarComponents() == 3)
{
unsigned char *srcRow =
((unsigned char *)img->GetScalarPointer()) +
((y-dY1) * imgWidth * 3);
for(x = 0; x < imgWidth; ++x)
{
*p++ = *srcRow++;
*p++ = *srcRow++;
*p++ = *srcRow++;
}
}
// Pad the right side of the image.
for(x = 0; x < dX2; ++x)
{
*p++ = bgR;
*p++ = bgG;
*p++ = bgB;
}
}
else
{
// y is outside of the image so use bg color
for(x = 0; x < tileWidth; ++x)
{
*p++ = bgR;
*p++ = bgG;
*p++ = bgB;
}
}
}
else
{
// There is no input image for s. Use the background.
int n = tileWidth * nColorComponents;
for(x = 0; x < n; ++x)
*p++ = 0;
}
}
}
srcStart += tilesPerRow;
}
//
// Now that we have a vtkImageData object, wrap it in something AVT likes.
//
avtImage_p retval = new avtImage(0);
retval->GetImage() = avtImageRepresentation(newImage);
newImage->Delete();
return retval;
}
#ifndef AVT_IMAGE_TILER_H
#define AVT_IMAGE_TILER_H
#include <avtImage.h>
// ****************************************************************************
// Class: avtImageTiler
//
// Purpose:
// Creates a new tiled image out of several avtImage objects and destroys
// the input images.
//
// Notes:
//
// Programmer: Brad Whitlock
// Creation: Thu Jul 15 15:18:17 PST 2004
//
// Modifications:
//
// ****************************************************************************
class PIPELINE_API avtImageTiler
{
public:
avtImageTiler(int nImg);
virtual ~avtImageTiler();
void AddImage(avtImage_p img);
int GetNumberOfColumnsForNTiles(int nTiles) const;
int GetNumberOfRowsForNTiles(int nTiles) const;
avtImage_p CreateTiledImage();
private:
avtImage_p *images;
int nImages;
int maxImages;
};
#endif
......@@ -245,13 +245,11 @@ QvisSaveWindow::CreateWindowContents()
toggleLayout2->addWidget(stereoCheckBox);
toggleLayout2->addStretch(10);
#if 1
// Get rid of this code when saving images is fully implemented in the
// viewer.
hostLabel->setEnabled(false);
hostLineEdit->setEnabled(false);
saveTiledCheckBox->setEnabled(false);
#endif
saveTiledCheckBox->setEnabled(true);
}
// ****************************************************************************
......@@ -291,6 +289,10 @@ QvisSaveWindow::CreateWindowContents()
// Hank Childs, Thu Jun 17 11:39:35 PDT 2004
// Disable "Screen capture" button when saving out polygonal formats.
//
// Brad Whitlock, Fri Jul 16 12:30:42 PDT 2004
// I added code to disable the height line edit when we're saving a tiled
// image.
//
// ****************************************************************************
void
......@@ -412,6 +414,15 @@ QvisSaveWindow::UpdateWindow(bool doAll)
break;
}
} // end for
// Make sure that the height text field is not enabled when we're saving
// a tiled image.
bool shouldBeEnabled = !saveWindowAtts->GetSaveTiled();
if(maintainAspectCheckBox->isEnabled() != shouldBeEnabled)
{
maintainAspectCheckBox->setEnabled(shouldBeEnabled);
heightLineEdit->setEnabled(shouldBeEnabled);
}
}
// ****************************************************************************
......@@ -428,10 +439,12 @@ QvisSaveWindow::UpdateWindow(bool doAll)
// Creation: Fri Feb 9 17:16:08 PST 2001
//
// Modifications:
//
// Hank Childs, Fri May 24 13:36:05 PDT 2002
// Renamed saveImageAtts to saveWindowAtts.
//
// Brad Whitlock, Fri Jul 16 15:46:40 PST 2004
// Removed some code and added new code to enforce the 1:1 aspect if needed.
//
// ****************************************************************************
void
......@@ -479,6 +492,7 @@ QvisSaveWindow::GetCurrentValues(int which_widget)
}
// Do the image width
bool setWidth = false;
if(which_widget == 2 || doAll)
{
temp = widthLineEdit->displayText().simplifyWhiteSpace();
......@@ -489,12 +503,8 @@ QvisSaveWindow::GetCurrentValues(int which_widget)
okay = (sscanf(temp.latin1(), "%d", &w) == 1);
if(okay)
{
setWidth = (saveWindowAtts->GetWidth() != w);
saveWindowAtts->SetWidth(w);
// If we're maintaining the 1:1 aspect ratio, udpate
// the height too.
if(saveWindowAtts->GetMaintainAspect())
saveWindowAtts->SetHeight(w);
}
}
......@@ -509,6 +519,7 @@ QvisSaveWindow::GetCurrentValues(int which_widget)
}
// Do the image height
bool setHeight = false;
if(which_widget == 3 || doAll)
{
temp = heightLineEdit->displayText().simplifyWhiteSpace();
......@@ -519,12 +530,8 @@ QvisSaveWindow::GetCurrentValues(int which_widget)
okay = (sscanf(temp.latin1(), "%d", &h) == 1);
if(okay)
{
setHeight = (saveWindowAtts->GetHeight() != h);
saveWindowAtts->SetHeight(h);
// If we're maintaining the 1:1 aspect ratio, udpate
// the width too.
if(saveWindowAtts->GetMaintainAspect())
saveWindowAtts->SetWidth(h);
}
}
......@@ -537,6 +544,21 @@ QvisSaveWindow::GetCurrentValues(int which_widget)
saveWindowAtts->SetHeight(saveWindowAtts->GetHeight());
}
}
//
// If doAll is true then this method is probably getting called by clicking
// the Apply button. In that case, and we're enforcing 1:1 aspect then we
// should update the width or height with the value that was set last in
// case the user never hit the Enter key after typing a new width or height.
//
if(doAll && saveWindowAtts->GetMaintainAspect() &&
saveWindowAtts->GetWidth() != saveWindowAtts->GetHeight())
{
if(setWidth)
saveWindowAtts->SetHeight(saveWindowAtts->GetWidth());
else if(setHeight)
saveWindowAtts->SetWidth(saveWindowAtts->GetHeight());
}
}
// ****************************************************************************
......@@ -768,13 +790,23 @@ QvisSaveWindow::maintainAspectToggled(bool val)
// Creation: Mon Feb 12 13:00:24 PST 2001
//
// Modifications:
//
// Brad Whitlock, Fri Jul 16 14:37:13 PST 2004
// Moved some code out of GetCurrentValues.
//
// ****************************************************************************
void
QvisSaveWindow::processWidthText()
{
GetCurrentValues(2);
// If we're maintaining the 1:1 aspect ratio, udpate
// the height too.
if(saveWindowAtts->GetMaintainAspect())
saveWindowAtts->SetHeight(saveWindowAtts->GetWidth());
QString temp;
temp.sprintf("%d", saveWindowAtts->GetHeight());
heightLineEdit->setText(temp);
Apply();
}
......@@ -788,6 +820,8 @@ QvisSaveWindow::processWidthText()
// Creation: Mon Feb 12 13:00:24 PST 2001
//
// Modifications:
// Brad Whitlock, Fri Jul 16 14:37:13 PST 2004
// Moved some code out of GetCurrentValues.
//
// ****************************************************************************
......@@ -795,6 +829,14 @@ void
QvisSaveWindow::processHeightText()
{
GetCurrentValues(3);
// If we're maintaining the 1:1 aspect ratio, udpate
// the width too.
if(saveWindowAtts->GetMaintainAspect())
saveWindowAtts->SetWidth(saveWindowAtts->GetHeight());
QString temp;
temp.sprintf("%d", saveWindowAtts->GetWidth());
widthLineEdit->setText(temp);
Apply();
}
......@@ -886,21 +928,18 @@ QvisSaveWindow::qualityChanged(int val)
// Creation: Fri Feb 9 17:27:07 PST 2001
//
// Modifications:
//
// Hank Childs, Fri May 24 13:36:05 PDT 2002
// Renamed saveImageAtts to saveWindowAtts.
//
// Brad Whitlock, Thu Jul 15 16:10:25 PST 2004
// Removed some code to prevent saving tiled images.
//
// ****************************************************************************
void
QvisSaveWindow::screenCaptureToggled(bool val)
{
saveWindowAtts->SetScreenCapture(val);
// If we're doing screen capture, prevent saving tiled images.
if(val)
saveWindowAtts->SetSaveTiled(false);
Apply();
}
......@@ -918,20 +957,17 @@ QvisSaveWindow::screenCaptureToggled(bool val)
// Creation: Fri Feb 9 17:27:07 PST 2001
//
// Modifications:
//
// Hank Childs, Fri May 24 13:36:05 PDT 2002
// Renamed saveImageAtts to saveWindowAtts.
//
// Brad Whitlock, Thu Jul 15 16:10:25 PST 2004
// Removed some code to prevent screen capture.
//
// ****************************************************************************
void
QvisSaveWindow::saveTiledToggled(bool val)
{
saveWindowAtts->SetSaveTiled(val);
// If we're doing tiled, prevent screen capture.
if(val)
saveWindowAtts->SetScreenCapture(false);
Apply();
}
......@@ -58,6 +58,7 @@
#include <avtCallback.h>
#include <avtDatabaseMetaData.h>
#include <avtImage.h>
#include <avtImageTiler.h>
#include <avtFileWriter.h>
#include <avtToolInterface.h>
#include <ImproperUseException.h>
......@@ -1363,6 +1364,9 @@ ViewerWindowManager::ChooseCenterOfRotation(int windowIndex,
// Hank Childs, Tue Apr 6 18:05:39 PDT 2004
// Do not save out empty data objects.
//
// Brad Whitlock, Thu Jul 15 16:27:15 PST 2004
// I made it send a different message for tiled images.
//
// ****************************************************************************
void
......@@ -1475,8 +1479,15 @@ ViewerWindowManager::SaveWindow(int windowIndex)
// status message display for 10 minutes.
//
char message[1000];
SNPRINTF(message, sizeof(message), "Rendering window %d...",
(windowIndex == -1) ? (activeWindow + 1) : (windowIndex + 1));
if(saveWindowClientAtts->GetSaveTiled())
{
strcpy(message, "Saving tiled image...");
}
else
{
SNPRINTF(message, sizeof(message), "Rendering window %d...",
(windowIndex == -1) ? (activeWindow + 1) : (windowIndex + 1));
}
Status(message, 6000000);
Message(message);
......@@ -1486,13 +1497,22 @@ ViewerWindowManager::SaveWindow(int windowIndex)
{