vtkClientServerMoveData.cxx 8.67 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkClientServerMoveData.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkClientServerMoveData.h"

#include "vtkCharArray.h"
18
#include "vtkDataObject.h"
19
#include "vtkDataObjectTypes.h"
20 21
#include "vtkGenericDataObjectReader.h"
#include "vtkGenericDataObjectWriter.h"
22 23
#include "vtkInformation.h"
#include "vtkInformationVector.h"
24
#include "vtkMultiBlockDataSet.h"
25
#include "vtkMultiProcessController.h"
26 27
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
28
#include "vtkProcessModule.h"
29
#include "vtkPVSession.h"
30 31
#include "vtkSelection.h"
#include "vtkSelectionSerializer.h"
32
#include "vtkStreamingDemandDrivenPipeline.h"
33
#include "vtkUnstructuredGrid.h"
34 35

#include <vtksys/ios/sstream>
36 37

vtkStandardNewMacro(vtkClientServerMoveData);
38 39
vtkCxxSetObjectMacro(vtkClientServerMoveData, Controller,
  vtkMultiProcessController);
40 41 42
//-----------------------------------------------------------------------------
vtkClientServerMoveData::vtkClientServerMoveData()
{
43
  this->OutputDataType = VTK_POLY_DATA;
44 45 46 47 48 49
  this->WholeExtent[0] =  0;
  this->WholeExtent[1] = -1;
  this->WholeExtent[2] =  0;
  this->WholeExtent[3] = -1;
  this->WholeExtent[4] =  0;
  this->WholeExtent[5] = -1;
50
  this->Controller = 0;
51
  this->ProcessType = AUTO;
52 53 54 55 56
}

//-----------------------------------------------------------------------------
vtkClientServerMoveData::~vtkClientServerMoveData()
{
57
  this->SetController(NULL);
58 59 60 61 62 63 64 65 66 67 68
}

//-----------------------------------------------------------------------------
int vtkClientServerMoveData::FillInputPortInformation(int idx, vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
  return this->Superclass::FillInputPortInformation(idx, info);
}

//----------------------------------------------------------------------------
int vtkClientServerMoveData::RequestDataObject(
Dave Demarle's avatar
Dave Demarle committed
69
  vtkInformation* vtkNotUsed(reqInfo), 
70
  vtkInformationVector**, 
71 72
  vtkInformationVector* outputVector)
{
73 74 75
  const char *outTypeStr = 
    vtkDataObjectTypes::GetClassNameFromTypeId(this->OutputDataType);

76 77 78
  vtkInformation* info = outputVector->GetInformationObject(0);
  vtkDataObject *output = info->Get(vtkDataObject::DATA_OBJECT());
  if (!output || !output->IsA(outTypeStr)) 
79
    {
80 81 82
    vtkDataObject* newOutput = 
      vtkDataObjectTypes::NewDataObject(this->OutputDataType);
    if (!newOutput)
83
      {
84 85 86
      vtkErrorMacro("Could not create chosen output data type: "
                    << outTypeStr);
      return 0;
87
      }
88
    info->Set(vtkDataObject::DATA_OBJECT(), newOutput);
89 90 91
    this->GetOutputPortInformation(0)->Set(
      vtkDataObject::DATA_EXTENT_TYPE(), newOutput->GetExtentType());
    newOutput->Delete();
92 93
    }

94
  return 1;
95 96
}

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//-----------------------------------------------------------------------------
int vtkClientServerMoveData::RequestInformation(
  vtkInformation* request, 
  vtkInformationVector** inputVector, 
  vtkInformationVector* outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  if (inputVector[0]->GetNumberOfInformationObjects() > 0)
    {
    return 
      this->Superclass::RequestInformation(request, inputVector, outputVector);
    }
  else
    {
    outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
                 this->WholeExtent,
                 6);
    }
  return 1;
}

118 119 120 121 122 123 124
//-----------------------------------------------------------------------------
int vtkClientServerMoveData::RequestData(vtkInformation*,
                                vtkInformationVector** inputVector,
                                vtkInformationVector* outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

125 126
  vtkDataObject* input = 0;
  vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT());
127 128 129

  if (inputVector[0]->GetNumberOfInformationObjects() > 0)
    {
130 131
    input = inputVector[0]->GetInformationObject(0)->Get(
        vtkDataObject::DATA_OBJECT());
132 133
    }

134 135 136
  vtkMultiProcessController* controller = this->Controller;
  int processType = this->ProcessType;
  if (this->ProcessType == AUTO)
137
    {
138
    vtkPVSession* session = vtkPVSession::SafeDownCast(
139
      vtkProcessModule::GetProcessModule()->GetSession());
140 141 142 143 144
    if (!session)
      {
      vtkErrorMacro("No active ParaView session");
      return 0;
      }
145 146
    if (vtkProcessModule::GetProcessType() ==
      vtkProcessModule::PROCESS_CLIENT)
147 148 149 150 151 152 153 154 155
      {
      controller = session->GetController(vtkPVSession::DATA_SERVER);
      processType = CLIENT;
      }
    else
      {
      controller = session->GetController(vtkPVSession::CLIENT);
      processType = SERVER;
      }
156
    }
157 158

  if (controller)
159
    {
160 161
    bool is_server = (processType == SERVER);
    bool is_client = (processType == CLIENT);
162
    if (is_server)
163 164
      {
      vtkDebugMacro("Server Root: Send input data to client.");
165
      return this->SendData(input, controller);
166
      }
167
    else if (is_client)
168 169 170
      {
      vtkDebugMacro("Client: Get data from server and put it on the output.");
      // This is a client node.
171 172
      // If it is a selection, use the XML serializer.
      // Otherwise, use the communicator.
173 174

      vtkDataObject* data = this->ReceiveData(controller);
175 176 177 178 179 180 181 182
      if (data)
        {
        if (output->IsA(data->GetClassName()))
          {
          output->ShallowCopy(data);
          }
        else
          {
183
          outputVector->GetInformationObject(0)->Set(vtkDataObject::DATA_OBJECT(), data);
184 185 186 187 188 189 190 191 192 193 194 195 196 197
          }
        data->Delete();
        return 1;
        }
      }
    }

  vtkDebugMacro("Shallow copying input to output.");
  // If not a remote connection, nothing more to do than
  // act as a pass through filter.
  output->ShallowCopy(input);
  return 1;
}

198 199
//-----------------------------------------------------------------------------
int vtkClientServerMoveData::SendData(vtkDataObject* input,
200
  vtkMultiProcessController* controller)
201 202 203 204
{
  // This is a server root node.
  // If it is a selection, use the XML serializer.
  // Otherwise, use the communicator.
205
  if (this->OutputDataType == VTK_SELECTION)
206 207 208
    {
    // Convert to XML.
    vtkSelection* sel = vtkSelection::SafeDownCast(input);
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
    if (!sel)
      {
      int size=0;
      return controller->Send(&size, 1, 1,
        vtkClientServerMoveData::TRANSMIT_DATA_OBJECT);
      }
    else
      {
      vtksys_ios::ostringstream res;
      vtkSelectionSerializer::PrintXML(res, vtkIndent(), 1, sel);

      // Send the size of the string.
      int size = static_cast<int>(res.str().size());
      controller->Send(&size, 1, 1,
        vtkClientServerMoveData::TRANSMIT_DATA_OBJECT);
      // Send the XML string.
      return controller->Send(res.str().c_str(), size, 1,
        vtkClientServerMoveData::TRANSMIT_DATA_OBJECT);
      }
228 229 230 231 232 233 234
    }

  return controller->Send(input, 1,
    vtkClientServerMoveData::TRANSMIT_DATA_OBJECT);
}

//-----------------------------------------------------------------------------
235
vtkDataObject* vtkClientServerMoveData::ReceiveData(vtkMultiProcessController* controller)
236 237 238 239 240 241 242 243
{
  vtkDataObject* data = NULL; 
  if (this->OutputDataType == VTK_SELECTION)
    {
    // Get the size of the string.
    int size = 0;
    controller->Receive(&size, 1, 1,
      vtkClientServerMoveData::TRANSMIT_DATA_OBJECT);
244 245 246 247
    if (size == 0)
      {
      return NULL;
      }
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
    char* xml = new char[size+1];
    // Get the string itself.
    controller->Receive(xml, size, 1,
      vtkClientServerMoveData::TRANSMIT_DATA_OBJECT);
    xml[size] = 0;

    // Parse the XML.
    vtkSelection* sel = vtkSelection::New();
    vtkSelectionSerializer::Parse(xml, sel);
    delete[] xml;
    data = sel;
    }
  else
    {
    data = controller->ReceiveDataObject(
      1, vtkClientServerMoveData::TRANSMIT_DATA_OBJECT);
    }
  return data;
}

268 269 270 271
//-----------------------------------------------------------------------------
void vtkClientServerMoveData::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
272 273 274 275 276 277 278 279
  os << indent << "WholeExtent: " 
    << this->WholeExtent[0] << ", "
    << this->WholeExtent[1] << ", "
    << this->WholeExtent[2] << ", "
    << this->WholeExtent[3] << ", "
    << this->WholeExtent[4] << ", "
    << this->WholeExtent[5] << endl;
  os << indent << "OutputDataType: " << this->OutputDataType << endl;
280
  os << indent << "ProcessType: " << this->ProcessType << endl;
281
  os << indent << "Controller: " << this->Controller << endl;
282
}