mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
236 lines
7.7 KiB
C++
236 lines
7.7 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: vtkPVClientServerSynchronizedRenderers.cxx
|
|
|
|
Copyright (c) Kitware, Inc.
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkPVClientServerSynchronizedRenderers.h"
|
|
|
|
#include "vtkLZ4Compressor.h"
|
|
#include "vtkMultiProcessController.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkOpenGLRenderer.h"
|
|
#include "vtkSquirtCompressor.h"
|
|
#include "vtkUnsignedCharArray.h"
|
|
#include "vtkZlibImageCompressor.h"
|
|
|
|
#include <sstream>
|
|
#include <assert.h>
|
|
|
|
vtkStandardNewMacro(vtkPVClientServerSynchronizedRenderers);
|
|
vtkCxxSetObjectMacro(vtkPVClientServerSynchronizedRenderers, Compressor,
|
|
vtkImageCompressor);
|
|
//----------------------------------------------------------------------------
|
|
vtkPVClientServerSynchronizedRenderers::vtkPVClientServerSynchronizedRenderers()
|
|
{
|
|
this->Compressor = NULL;
|
|
this->ConfigureCompressor("vtkLZ4Compressor 0 3");
|
|
this->LossLessCompression = true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkPVClientServerSynchronizedRenderers::~vtkPVClientServerSynchronizedRenderers()
|
|
{
|
|
this->SetCompressor(NULL);
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVClientServerSynchronizedRenderers::MasterEndRender()
|
|
{
|
|
// receive image from slave.
|
|
assert(this->ParallelController->IsA("vtkSocketController") ||
|
|
this->ParallelController->IsA("vtkCompositeMultiProcessController") );
|
|
|
|
vtkRawImage& rawImage = (this->ImageReductionFactor == 1)?
|
|
this->FullImage : this->ReducedImage;
|
|
|
|
int header[4];
|
|
this->ParallelController->Receive(header, 4, 1, 0x023430);
|
|
if (header[0] > 0)
|
|
{
|
|
rawImage.Resize(header[1], header[2], header[3]);
|
|
if (this->Compressor)
|
|
{
|
|
vtkUnsignedCharArray* data = vtkUnsignedCharArray::New();
|
|
this->ParallelController->Receive(data, 1, 0x023430);
|
|
this->Decompress(data, rawImage.GetRawPtr());
|
|
data->Delete();
|
|
}
|
|
else
|
|
{
|
|
this->ParallelController->Receive(rawImage.GetRawPtr(), 1, 0x023430);
|
|
}
|
|
rawImage.MarkValid();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVClientServerSynchronizedRenderers::SlaveStartRender()
|
|
{
|
|
this->Superclass::SlaveStartRender();
|
|
|
|
#ifdef VTKGL2
|
|
// In client-server mode, we want all the server ranks to simply render using
|
|
// a black background. That makes it easier to blend the image we obtain from
|
|
// the server rank on top of the background rendered locally on the client.
|
|
// vtkPVSynchronizedRenderer only creates
|
|
// vtkPVClientServerSynchronizedRenderers in client-server mode that support
|
|
// image delivery to client (i.e. not in tile-display, or cave mode).
|
|
// Hence, we know it won't affect server ranks that do display the rendered
|
|
// result. (Fixes BUG #0015961).
|
|
this->Renderer->SetBackground(0, 0, 0);
|
|
this->Renderer->SetGradientBackground(false);
|
|
this->Renderer->SetTexturedBackground(false);
|
|
#endif
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVClientServerSynchronizedRenderers::SlaveEndRender()
|
|
{
|
|
assert(this->ParallelController->IsA("vtkSocketController") ||
|
|
this->ParallelController->IsA("vtkCompositeMultiProcessController") );
|
|
|
|
vtkRawImage &rawImage = this->CaptureRenderedImage();
|
|
|
|
int header[4];
|
|
header[0] = rawImage.IsValid()? 1 : 0;
|
|
header[1] = rawImage.GetWidth();
|
|
header[2] = rawImage.GetHeight();
|
|
header[3] = rawImage.IsValid()?
|
|
rawImage.GetRawPtr()->GetNumberOfComponents() : 0;
|
|
|
|
// send the image to the client.
|
|
this->ParallelController->Send(header, 4, 1, 0x023430);
|
|
if (rawImage.IsValid())
|
|
{
|
|
this->ParallelController->Send(
|
|
this->Compress(rawImage.GetRawPtr()), 1, 0x023430);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkUnsignedCharArray* vtkPVClientServerSynchronizedRenderers::Compress(
|
|
vtkUnsignedCharArray* data)
|
|
{
|
|
if (this->Compressor)
|
|
{
|
|
this->Compressor->SetLossLessMode(this->LossLessCompression);
|
|
this->Compressor->SetInput(data);
|
|
if (this->Compressor->Compress() == 0)
|
|
{
|
|
vtkErrorMacro("Image compression failed!");
|
|
return data;
|
|
}
|
|
return this->Compressor->GetOutput();
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVClientServerSynchronizedRenderers::Decompress(
|
|
vtkUnsignedCharArray* data, vtkUnsignedCharArray* outputBuffer)
|
|
{
|
|
if (this->Compressor)
|
|
{
|
|
this->Compressor->SetLossLessMode(this->LossLessCompression);
|
|
this->Compressor->SetInput(data);
|
|
this->Compressor->SetOutput(outputBuffer);
|
|
if (this->Compressor->Decompress() == 0)
|
|
{
|
|
vtkErrorMacro("Image de-compression failed!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro("No compressor present.");
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVClientServerSynchronizedRenderers::ConfigureCompressor(const char *stream)
|
|
{
|
|
// cerr << this->GetClassName() << "::ConfigureCompressor " << stream << endl;
|
|
|
|
// Configure the compressor from a string. The string will
|
|
// contain the class name of the compressor type to use,
|
|
// follwed by a stream that the named class will restore itself
|
|
// from.
|
|
std::istringstream iss(stream);
|
|
std::string className;
|
|
iss >> className;
|
|
|
|
// Allocate the desired compressor unless we have one in hand.
|
|
if (!(this->Compressor && this->Compressor->IsA(className.c_str())))
|
|
{
|
|
vtkImageCompressor *comp=0;
|
|
if (className=="vtkSquirtCompressor")
|
|
{
|
|
comp=vtkSquirtCompressor::New();
|
|
}
|
|
else if (className=="vtkZlibImageCompressor")
|
|
{
|
|
comp=vtkZlibImageCompressor::New();
|
|
}
|
|
else if (className == "vtkLZ4Compressor")
|
|
{
|
|
comp = vtkLZ4Compressor::New();
|
|
}
|
|
else if (className=="NULL" || className.empty())
|
|
{
|
|
this->SetCompressor(0);
|
|
return;
|
|
}
|
|
if (comp==0)
|
|
{
|
|
vtkWarningMacro("Could not create the compressor by name " << className << ".");
|
|
return;
|
|
}
|
|
this->SetCompressor(comp);
|
|
comp->Delete();
|
|
}
|
|
// move passed the class name and let the compressor configure itself
|
|
// from the stream.
|
|
const char *ok=this->Compressor->RestoreConfiguration(stream);
|
|
if (!ok)
|
|
{
|
|
vtkWarningMacro("Could not configure the compressor, invalid stream. " << stream << ".");
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVClientServerSynchronizedRenderers::PushImageToScreen()
|
|
{
|
|
// This trick allows us to not clear the color buffer before pasting back
|
|
// the image from the server. This makes it possible to preserve any
|
|
// annotations rendered esp. vtkGridAxes3DActor which renders in multiple
|
|
// layers.
|
|
// This is not the most elegant solution. We should rethink if
|
|
// vtkSynchronizedRenderers::PushImageToScreen() should clear the screen by
|
|
// default -- I can argue not.
|
|
int layer = this->Renderer->GetLayer();
|
|
int prev = this->Renderer->GetPreserveColorBuffer();
|
|
if (layer == 0)
|
|
{
|
|
this->Renderer->SetPreserveColorBuffer(1);
|
|
}
|
|
this->Superclass::PushImageToScreen();
|
|
this->Renderer->SetPreserveColorBuffer(prev);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVClientServerSynchronizedRenderers::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|