vtkExtractUnstructuredGrid.cxx 9.25 KB
Newer Older
1 2 3 4 5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkExtractUnstructuredGrid.cxx

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 8
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9

10 11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
     PURPOSE.  See the above copyright notice for more information.
13 14 15

=========================================================================*/
#include "vtkExtractUnstructuredGrid.h"
16

17 18 19
#include "vtkCell.h"
#include "vtkCellData.h"
#include "vtkIdList.h"
20 21
#include "vtkInformation.h"
#include "vtkInformationVector.h"
22
#include "vtkMergePoints.h"
23
#include "vtkObjectFactory.h"
24
#include "vtkPointData.h"
25
#include "vtkUnstructuredGrid.h"
26
#include "vtkIncrementalPointLocator.h"
27

Brad King's avatar
Brad King committed
28
vtkStandardNewMacro(vtkExtractUnstructuredGrid);
29

30 31 32 33
// Construct with all types of clipping turned off.
vtkExtractUnstructuredGrid::vtkExtractUnstructuredGrid()
{
  this->PointMinimum = 0;
34
  this->PointMaximum = VTK_ID_MAX;
35 36

  this->CellMinimum = 0;
37
  this->CellMaximum = VTK_ID_MAX;
38

Ken Martin's avatar
Ken Martin committed
39 40 41 42 43 44
  this->Extent[0] = -VTK_DOUBLE_MAX;
  this->Extent[1] = VTK_DOUBLE_MAX;
  this->Extent[2] = -VTK_DOUBLE_MAX;
  this->Extent[3] = VTK_DOUBLE_MAX;
  this->Extent[4] = -VTK_DOUBLE_MAX;
  this->Extent[5] = VTK_DOUBLE_MAX;
45 46 47 48

  this->PointClipping = 0;
  this->CellClipping = 0;
  this->ExtentClipping = 0;
49 50

  this->Merging = 0;
51
  this->Locator = nullptr;
52 53 54
}

// Specify a (xmin,xmax, ymin,ymax, zmin,zmax) bounding box to clip data.
Ken Martin's avatar
Ken Martin committed
55 56
void vtkExtractUnstructuredGrid::SetExtent(double xMin,double xMax, double yMin,
                                           double yMax, double zMin, double zMax)
57
{
Ken Martin's avatar
Ken Martin committed
58
  double extent[6];
59 60 61 62 63 64 65 66 67 68 69 70

  extent[0] = xMin;
  extent[1] = xMax;
  extent[2] = yMin;
  extent[3] = yMax;
  extent[4] = zMin;
  extent[5] = zMax;

  this->SetExtent(extent);
}

// Specify a (xmin,xmax, ymin,ymax, zmin,zmax) bounding box to clip data.
Ken Martin's avatar
Ken Martin committed
71
void vtkExtractUnstructuredGrid::SetExtent(double extent[6])
72 73 74 75
{
  int i;

  if ( extent[0] != this->Extent[0] || extent[1] != this->Extent[1] ||
Amy Squillacote's avatar
Amy Squillacote committed
76 77
       extent[2] != this->Extent[2] || extent[3] != this->Extent[3] ||
       extent[4] != this->Extent[4] || extent[5] != this->Extent[5] )
78
  {
79
    this->ExtentClippingOn();
80
    for (i=0; i<3; i++)
81
    {
Bill Lorensen's avatar
Bill Lorensen committed
82
      if ( extent[2*i+1] < extent[2*i] )
83
      {
84
        extent[2*i+1] = extent[2*i];
85
      }
86 87 88
      this->Extent[2*i] = extent[2*i];
      this->Extent[2*i+1] = extent[2*i+1];
    }
89
  }
90 91
}

92 93
// Extract cells and pass points and point data through. Also handles
// cell data.
94 95 96 97
int vtkExtractUnstructuredGrid::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
98
{
99 100 101 102
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

103
  // get the input and output
104 105 106 107 108
  vtkUnstructuredGrid *input = vtkUnstructuredGrid::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

Amy Squillacote's avatar
Amy Squillacote committed
109
  vtkIdType cellId, i, newCellId;
110
  vtkIdType newPtId;
Amy Squillacote's avatar
Amy Squillacote committed
111 112
  vtkIdType numPts=input->GetNumberOfPoints();
  vtkIdType numCells=input->GetNumberOfCells();
113
  vtkPoints *inPts=input->GetPoints(), *newPts;
114 115
  char *cellVis;
  vtkCell *cell;
Ken Martin's avatar
Ken Martin committed
116
  double x[3];
117 118
  vtkIdList *ptIds;
  vtkIdList *cellIds;
Amy Squillacote's avatar
Amy Squillacote committed
119
  vtkIdType ptId;
120
  vtkPointData *pd = input->GetPointData();
121 122
  vtkCellData *cd = input->GetCellData();
  int allVisible, numIds;
123
  vtkPointData *outputPD = output->GetPointData();
124
  vtkCellData *outputCD = output->GetCellData();
125
  vtkIdType *pointMap = nullptr;
126

127
  vtkDebugMacro(<<"Executing extraction filter");
128 129

  if ( numPts < 1 || numCells < 1 || !inPts )
130
  {
131
    vtkDebugMacro(<<"No data to extract!");
132
    return 1;
133
  }
134
  cellIds=vtkIdList::New();
135

136
  if ( (!this->CellClipping) && (!this->PointClipping) &&
137
       (!this->ExtentClipping) )
138
  {
139
    allVisible = 1;
140
    cellVis = nullptr;
141
  }
142
  else
143
  {
144 145
    allVisible = 0;
    cellVis = new char[numCells];
146
  }
147 148

  // Mark cells as being visible or not
149
  if ( ! allVisible )
150
  {
151
    for(cellId=0; cellId < numCells; cellId++)
152
    {
153 154
        if ( this->CellClipping && (cellId < this->CellMinimum ||
                                    cellId > this->CellMaximum) )
155 156 157 158
        {
        cellVis[cellId] = 0;
        }
      else
159
      {
160 161
        cell = input->GetCell(cellId);
        ptIds = cell->GetPointIds();
162
        numIds = ptIds->GetNumberOfIds();
163
        for (i=0; i < numIds; i++)
164
        {
165
          ptId = ptIds->GetId(i);
166
          input->GetPoint(ptId, x);
167 168 169

          if ( (this->PointClipping && (ptId < this->PointMinimum ||
          ptId > this->PointMaximum) ) ||
170
          (this->ExtentClipping &&
171 172 173
          (x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
          x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
          x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
174
          {
175 176 177
            cellVis[cellId] = 0;
            break;
          }
178
        }
Bill Lorensen's avatar
Bill Lorensen committed
179
        if ( i >= numIds )
180
        {
181
          cellVis[cellId] = 1;
182 183 184
        }
      }
    }
185
  }
186 187 188 189

  // Allocate
  newPts = vtkPoints::New();
  newPts->Allocate(numPts);
190
  output->Allocate(numCells);
191 192
  outputPD->CopyAllocate(pd,numPts,numPts/2);
  outputCD->CopyAllocate(cd,numCells,numCells/2);
193 194

  if ( this->Merging )
195
  {
196
    if ( this->Locator == nullptr )
197
    {
198 199
      this->CreateDefaultLocator();
    }
200 201
    this->Locator->InitPointInsertion (newPts, input->GetBounds());
  }
202
  else
203
  {
Amy Squillacote's avatar
Amy Squillacote committed
204
    pointMap = new vtkIdType[numPts];
205
    for (i=0; i<numPts; i++)
206
    {
207
      pointMap[i] = (-1); //initialize as unused
Bill Lorensen's avatar
Bill Lorensen committed
208
    }
209
  }
210 211

  // Traverse cells to extract geometry
212
  for(cellId=0; cellId < numCells; cellId++)
213
  {
214
    if ( allVisible || cellVis[cellId] )
215
    {
216
      cell = input->GetCell(cellId);
217
      numIds = cell->PointIds->GetNumberOfIds();
218
      cellIds->Reset();
219
      if ( this->Merging )
220
      {
221
        for (i=0; i < numIds; i++)
222
        {
223
          ptId = cell->PointIds->GetId(i);
224
          input->GetPoint(ptId, x);
225
          if ( this->Locator->InsertUniquePoint(x, newPtId) )
226
          {
227 228
            outputPD->CopyData(pd,ptId,newPtId);
          }
229 230 231
          cellIds->InsertNextId(newPtId);
        }
      }//merging coincident points
232
      else
233
      {
234
        for (i=0; i < numIds; i++)
235
        {
236 237
          ptId = cell->PointIds->GetId(i);
          if ( pointMap[ptId] < 0 )
238
          {
239
            pointMap[ptId] = newPtId
240 241 242
              = newPts->InsertNextPoint(inPts->GetPoint(ptId));
            outputPD->CopyData(pd, ptId, newPtId);
          }
243 244 245
          cellIds->InsertNextId(pointMap[ptId]);
        }
      }//keeping original point list
246

247
      newCellId = output->InsertNextCell(input->GetCellType(cellId), cellIds);
248
      outputCD->CopyData(cd, cellId, newCellId);
249

250 251
    } //if cell is visible
  } //for all cells
252

253
  // Update ourselves and release memory
254 255 256
  output->SetPoints(newPts);
  newPts->Delete();

257 258 259
  vtkDebugMacro(<<"Extracted " << output->GetNumberOfPoints() << " points,"
                << output->GetNumberOfCells() << " cells.");

260
  if ( this->Merging && this->Locator )
261
  {
262
    this->Locator->Initialize();
263
  }
264
  else
265
  {
266
    delete [] pointMap;
267
  }
268
  output->Squeeze();
269

270
  delete [] cellVis;
271
  cellIds->Delete();
272 273

  return 1;
274 275
}

Bill Lorensen's avatar
Bill Lorensen committed
276
vtkMTimeType vtkExtractUnstructuredGrid::GetMTime()
277
{
Bill Lorensen's avatar
Bill Lorensen committed
278 279
  vtkMTimeType mTime= this->Superclass::GetMTime();
  vtkMTimeType time;
280

281
  if ( this->Locator != nullptr )
282
  {
283 284
    time = this->Locator->GetMTime();
    mTime = ( time > mTime ? time : mTime );
285
  }
286 287 288 289 290
  return mTime;
}

void vtkExtractUnstructuredGrid::CreateDefaultLocator()
{
291
  if ( this->Locator == nullptr )
292
  {
293
    this->Locator = vtkMergePoints::New();
294
  }
295 296 297 298
}

// Specify a spatial locator for merging points. By
// default an instance of vtkMergePoints is used.
299
void vtkExtractUnstructuredGrid::SetLocator(vtkIncrementalPointLocator *locator)
300
{
301
  if ( this->Locator == locator )
302
  {
303
    return;
304
  }
305
  if ( this->Locator )
306
  {
307
    this->Locator->UnRegister(this);
308
    this->Locator = nullptr;
309
  }
310
  if ( locator )
311
  {
312
    locator->Register(this);
313
  }
314 315 316 317
  this->Locator = locator;
  this->Modified();
}

318
void vtkExtractUnstructuredGrid::PrintSelf(ostream& os, vtkIndent indent)
319
{
Brad King's avatar
Brad King committed
320
  this->Superclass::PrintSelf(os,indent);
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336

  os << indent << "Point Minimum : " << this->PointMinimum << "\n";
  os << indent << "Point Maximum : " << this->PointMaximum << "\n";

  os << indent << "Cell Minimum : " << this->CellMinimum << "\n";
  os << indent << "Cell Maximum : " << this->CellMaximum << "\n";

  os << indent << "Extent: \n";
  os << indent << "  Xmin,Xmax: (" << this->Extent[0] << ", " << this->Extent[1] << ")\n";
  os << indent << "  Ymin,Ymax: (" << this->Extent[2] << ", " << this->Extent[3] << ")\n";
  os << indent << "  Zmin,Zmax: (" << this->Extent[4] << ", " << this->Extent[5] << ")\n";

  os << indent << "PointClipping: " << (this->PointClipping ? "On\n" : "Off\n");
  os << indent << "CellClipping: " << (this->CellClipping ? "On\n" : "Off\n");
  os << indent << "ExtentClipping: " << (this->ExtentClipping ? "On\n" : "Off\n");

337 338
  os << indent << "Merging: " << (this->Merging ? "On\n" : "Off\n");
  if ( this->Locator )
339
  {
340
    os << indent << "Locator: " << this->Locator << "\n";
341
  }
342
  else
343
  {
344
    os << indent << "Locator: (none)\n";
345
  }
346
}