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

  Program:   Visualization Toolkit
  Module:    vtkImageDataToUniformGrid.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 "vtkImageDataToUniformGrid.h"

18 19 20 21 22 23 24 25 26 27 28
#include "vtkCellData.h"
#include "vtkDataObjectTree.h"
#include "vtkDataObjectTreeIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkUniformGrid.h"
#include "vtkUnsignedCharArray.h"
29 30 31 32 33 34

vtkStandardNewMacro(vtkImageDataToUniformGrid);

//----------------------------------------------------------------------------
vtkImageDataToUniformGrid::vtkImageDataToUniformGrid()
{
35
  this->Reverse = 0;
36 37 38
}

//----------------------------------------------------------------------------
39
vtkImageDataToUniformGrid::~vtkImageDataToUniformGrid() = default;
40 41 42 43 44

//----------------------------------------------------------------------------
void vtkImageDataToUniformGrid::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
45
  os << indent << "Reverse: " << this->Reverse << "\n";
46 47 48 49 50 51 52 53 54
}

//----------------------------------------------------------------------------
int vtkImageDataToUniformGrid::RequestDataObject(vtkInformation *,
                                                 vtkInformationVector **inV,
                                                 vtkInformationVector *outV)
{
  vtkInformation* inInfo = inV[0]->GetInformationObject(0);
  if (!inInfo)
55
  {
56
    return VTK_ERROR;
57
  }
58 59 60

  vtkInformation* outInfo = outV->GetInformationObject(0);

61
  if(vtkDataObjectTree* input = vtkDataObjectTree::GetData(inInfo) )
62
  { // multiblock data sets
63 64
    vtkDataObjectTree* output = vtkDataObjectTree::GetData(outInfo);
    if (!output)
65
    {
66 67 68 69 70 71
      output = input->NewInstance();
      outInfo->Set(vtkDataObject::DATA_OBJECT(), output);
      this->GetOutputPortInformation(0)->Set(
        vtkDataObject::DATA_EXTENT_TYPE(), output->GetExtentType());
      output->Delete();
    }
72 73
    return VTK_OK;
  }
74
  if(vtkImageData::GetData(inInfo) != nullptr)
75
  {
76
    vtkUniformGrid* output = vtkUniformGrid::New();
77 78 79 80 81 82
    outInfo->Set(vtkDataObject::DATA_OBJECT(), output);
    this->GetOutputPortInformation(0)->Set(
      vtkDataObject::DATA_EXTENT_TYPE(), output->GetExtentType());
    output->Delete();

    return VTK_OK;
83
  }
84

85 86
  vtkErrorMacro("Don't know how to handle input of type " <<
                vtkDataObject::GetData(inInfo)->GetClassName());
87
  return VTK_ERROR;
88 89 90 91 92 93 94 95 96 97 98 99 100
}

//----------------------------------------------------------------------------
int vtkImageDataToUniformGrid::RequestData(vtkInformation *,
                                           vtkInformationVector **,
                                           vtkInformationVector *outV)
{
  vtkDataObject* input = this->GetInput();
  vtkInformation *outInfo = outV->GetInformationObject(0);
  vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT());

  vtkInformation *inArrayInfo = this->GetInputArrayInformation(0);
  if (!inArrayInfo)
101
  {
102 103
    vtkErrorMacro("Problem getting array to process.");
    return 0;
104
  }
105 106
  int association = -1;
  if (!inArrayInfo->Has(vtkDataObject::FIELD_ASSOCIATION()))
107
  {
108 109
    vtkErrorMacro("Unable to query field association for the scalar.");
    return 0;
110
  }
111 112 113 114
  association = inArrayInfo->Get(vtkDataObject::FIELD_ASSOCIATION());

  const char* arrayName = inArrayInfo->Get(vtkDataObject::FIELD_NAME());
  if (!arrayName)
115
  {
116 117
    vtkErrorMacro("Problem getting array name to process.");
    return 0;
118
  }
119 120

  if(vtkImageData* inImageData = vtkImageData::SafeDownCast(input))
121
  {
122 123
    return this->Process(inImageData, association, arrayName,
                         vtkUniformGrid::SafeDownCast(output));
124
  }
125 126 127 128 129 130 131
  vtkDataObjectTree* inMB = vtkDataObjectTree::SafeDownCast(input);
  vtkDataObjectTree* outMB = vtkDataObjectTree::SafeDownCast(output);
  outMB->CopyStructure(inMB);
  vtkDataObjectTreeIterator* iter = inMB->NewTreeIterator();
  iter->VisitOnlyLeavesOn();
  iter->TraverseSubTreeOn();
  for(iter->GoToFirstItem();!iter->IsDoneWithTraversal();iter->GoToNextItem())
132
  {
133 134
    if(vtkImageData* inImageData =
       vtkImageData::SafeDownCast(iter->GetCurrentDataObject()))
135
    {
136
      vtkNew<vtkUniformGrid> outUniformGrid;
137
      if(this->Process(inImageData, association, arrayName, outUniformGrid) != VTK_OK)
138
      {
139 140 141
        iter->Delete();
        return VTK_ERROR;
      }
142
      outMB->SetDataSetFrom(iter, outUniformGrid);
143
    }
144
    else
145
    { // not a uniform grid so we just shallow copy from input to output
146 147
      outMB->SetDataSetFrom(iter, iter->GetCurrentDataObject());
    }
148
  }
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
  iter->Delete();

  return VTK_OK;
}

//-----------------------------------------------------------------------------
int vtkImageDataToUniformGrid::FillInputPortInformation(int port,
                                                        vtkInformation* info)
{
  this->Superclass::FillInputPortInformation(port, info);

  // According to the documentation this is the way to append additional
  // input data set type since VTK 5.2.
  info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
    "vtkDataObjectTree");
  return VTK_OK;
}

//----------------------------------------------------------------------------
int vtkImageDataToUniformGrid::FillOutputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
  // now add our info
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkDataObject");

  return VTK_OK;
}

//----------------------------------------------------------------------------
int vtkImageDataToUniformGrid::Process(
  vtkImageData* input, int association,
  const char* arrayName, vtkUniformGrid* output)
{
182
  if(vtkUniformGrid* uniformGrid = vtkUniformGrid::SafeDownCast(input))
183
  {
184
    output->ShallowCopy(uniformGrid);
185
  }
186
  else
187
  {
188
    output->ShallowCopy(input);
189
  }
190

191
  vtkDataArray* inScalars = nullptr;
192
  if(association == vtkDataObject::FIELD_ASSOCIATION_POINTS)
193
  {
194
    inScalars = input->GetPointData()->GetArray(arrayName);
195
  }
196
  else if(association == vtkDataObject::FIELD_ASSOCIATION_CELLS)
197
  {
198
    inScalars = input->GetCellData()->GetArray(arrayName);
199
  }
200
  else
201
  {
Kunda's avatar
Kunda committed
202
    vtkErrorMacro("Wrong association type: " << association);
203
    return VTK_ERROR;
204
  }
205 206

  if (!inScalars)
207
  {
208 209
    vtkErrorMacro("No scalar data to use for blanking.");
    return VTK_ERROR;
210
  }
211
  else if(inScalars->GetNumberOfComponents() != 1)
212
  {
213 214
    vtkErrorMacro("Scalar data must be a single component array.");
    return VTK_ERROR;
215
  }
216 217 218

  vtkNew<vtkUnsignedCharArray> blankingArray;
  blankingArray->DeepCopy(inScalars);
219
  blankingArray->SetName(vtkDataSetAttributes::GhostArrayName());
220

221 222 223 224

  unsigned char value1;
  unsigned char value2;
  if (association == vtkDataObject::FIELD_ASSOCIATION_CELLS)
225
  {
226
    if (this->Reverse)
227
    {
228 229
      value1 = 0;
      value2 = vtkDataSetAttributes::HIDDENCELL;
230
    }
231
    else
232
    {
233 234 235
      value1 = vtkDataSetAttributes::HIDDENCELL;
      value2 = 0;
    }
236
  }
237
  else
238
  {
239
    if (this->Reverse)
240
    {
241 242
      value1 = 0;
      value2 = vtkDataSetAttributes::HIDDENPOINT;
243
    }
244
    else
245
    {
246 247 248
      value1 = vtkDataSetAttributes::HIDDENPOINT;
      value2 = 0;
    }
249
  }
250
  for(vtkIdType i=0;i<blankingArray->GetNumberOfTuples();i++)
251
  {
252 253
    char value = blankingArray->GetValue(i) == 0 ? value1 : value2;
    blankingArray->SetValue(i, value);
254
  }
255

256
  if(association == vtkDataObject::FIELD_ASSOCIATION_POINTS)
257
  {
258
    output->GetPointData()->AddArray(blankingArray);
259
  }
260
  else
261
  {
262
    output->GetCellData()->AddArray(blankingArray);
263
  }
264 265 266

  return VTK_OK;
}