vtkOnionPeelFilter.C 34.7 KB
Newer Older
hrchilds's avatar
hrchilds committed
1 2
/*****************************************************************************
*
3
* Copyright (c) 2000 - 2014, Lawrence Livermore National Security, LLC
hrchilds's avatar
hrchilds committed
4
* Produced at the Lawrence Livermore National Laboratory
5
* LLNL-CODE-442911
hrchilds's avatar
hrchilds committed
6 7
* All rights reserved.
*
8
* This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
hrchilds's avatar
hrchilds committed
9 10 11 12 13 14 15 16 17 18
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution  and  use  in  source  and  binary  forms,  with  or  without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of  source code must  retain the above  copyright notice,
*    this list of conditions and the disclaimer below.
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
19 20 21
*    documentation and/or other materials provided with the distribution.
*  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
*    be used to endorse or promote products derived from this software without
hrchilds's avatar
hrchilds committed
22 23 24 25 26
*    specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
27 28 29
* ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
* LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
* DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
hrchilds's avatar
hrchilds committed
30 31 32 33 34 35 36 37 38
* DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
* SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
* CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
* LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
* OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/

hrchilds's avatar
hrchilds committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
//========================================================================
//
//  Class:   vtkOnionPeelFilter
//
//  Purpose:
//    Derived type of vtkDataSetToUnstructuredGridFilter.
//
//  Notes:  
//
//  Programmer:  Kathleen S. Bonnell
//
//  Creation:  5 October 2000
//
//========================================================================

#include <vtkCell.h>
hrchilds's avatar
hrchilds committed
55
#include <vtkCellData.h>
hrchilds's avatar
hrchilds committed
56
#include <vtkIdList.h>
57 58
#include <vtkInformation.h>
#include <vtkInformationVector.h>
hrchilds's avatar
hrchilds committed
59
#include <vtkIntArray.h>
hrchilds's avatar
hrchilds committed
60 61
#include <vtkObjectFactory.h>
#include <vtkOnionPeelFilter.h>
hrchilds's avatar
hrchilds committed
62
#include <vtkPointData.h>
hrchilds's avatar
hrchilds committed
63 64 65
#include <vtkRectilinearGrid.h>
#include <vtkStructuredGrid.h>
#include <vtkUnstructuredGrid.h>
hrchilds's avatar
hrchilds committed
66
#include <vtkUnsignedIntArray.h>
hrchilds's avatar
hrchilds committed
67
#include <vtkVisItUtility.h>
hrchilds's avatar
hrchilds committed
68 69


70 71
// ****************************************************************************
//  Modifications:
bonnell's avatar
bonnell committed
72 73
//    Kathleen Bonnell, Wed Mar  6 15:14:29 PST 2002
//    Replace 'New' method with Macro to match VTK 4.0 API.
hrchilds's avatar
hrchilds committed
74
//
75
// ****************************************************************************
hrchilds's avatar
hrchilds committed
76 77 78
vtkStandardNewMacro(vtkOnionPeelFilter);


79 80 81
// ****************************************************************************
//  Construct with adjacency set to Node-Adjacency.
//  SeedCellId set to 0, RequestedLayer set to 0
hrchilds's avatar
hrchilds committed
82
//
83
//  Modifications:
bonnell's avatar
bonnell committed
84 85
//    Kathleen Bonnell, Thu Aug 15 18:37:59 PDT 2002
//    Initialize logicalIndex and useLogicalIndex.
hrchilds's avatar
hrchilds committed
86
//
bonnell's avatar
bonnell committed
87
//    Kathleen Bonnell, Tue Jan 18 19:37:46 PST 2005
88
//    Initialize ReconstructOriginalCells. 
hrchilds's avatar
hrchilds committed
89
//
bonnell's avatar
bonnell committed
90 91
//    Kathleen Bonnell, Wed Jan 19 15:54:38 PST 2005
//    Renamed 'SeedCellId' to 'SeedId'.  Initialize SeedIdIsForCell.
hrchilds's avatar
hrchilds committed
92
//
93
// ****************************************************************************
hrchilds's avatar
hrchilds committed
94 95 96
vtkOnionPeelFilter::vtkOnionPeelFilter()
{
    this->RequestedLayer = 0;
hrchilds's avatar
hrchilds committed
97
    this->SeedId = 0;
hrchilds's avatar
hrchilds committed
98 99 100
    this->logicalIndex[0] = this->logicalIndex[1] = this->logicalIndex[2] = 0;
    this->useLogicalIndex = false;
    this->maxLayersReached = 0;
bonnell's avatar
bonnell committed
101
    this->maxLayerNum = VTK_INT_MAX;
hrchilds's avatar
hrchilds committed
102
    this->AdjacencyType = VTK_NODE_ADJACENCY;
hrchilds's avatar
hrchilds committed
103
    this->ReconstructOriginalCells = 0; 
hrchilds's avatar
hrchilds committed
104
    this->SeedIdIsForCell = 1; 
hrchilds's avatar
hrchilds committed
105 106 107 108 109 110 111 112 113 114 115

    this->layerCellIds = vtkIdList::New();
    this->layerCellIds->Allocate(500);
    this->cellOffsets = vtkIdList::New();
    this->cellOffsets->Allocate(50);

    this->bsc_callback = NULL;
    this->bsc_args = NULL;
}


116
// ****************************************************************************
hrchilds's avatar
hrchilds committed
117 118 119 120 121 122 123 124 125 126
// Destructor
vtkOnionPeelFilter::~vtkOnionPeelFilter()
{
    this->layerCellIds->Delete();
    this->layerCellIds = NULL;

    this->cellOffsets->Delete();
    this->cellOffsets = NULL;
}

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

// ****************************************************************************
//  Method: vtkOnionPeelFilter::SetBadSeedCallback
//
//  Purpose:  
//    Sets a callback that is called if the seed cell is bad.
//
//  Arguments:
//    cb      The callback.
//    args    The arguments to cb.
//
//  Returns:  None 
//
//  Programmer: Hank Childs
//  Creation:   May 22, 2002
//
//  Modifications:
//    Kathleen Bonnell, Wed Jan 19 15:54:38 PST 2005
//    Removed 'Cell' from method name, arg name.
//
// ****************************************************************************
hrchilds's avatar
hrchilds committed
148
void 
hrchilds's avatar
hrchilds committed
149
vtkOnionPeelFilter::SetBadSeedCallback(BadSeedCallback cb, void *args)
hrchilds's avatar
hrchilds committed
150 151 152 153 154
{
    bsc_callback = cb;
    bsc_args     = args;
}

155 156 157

// ****************************************************************************
//  Method: vtkOnionPeelFilter::Initialize
hrchilds's avatar
hrchilds committed
158
//
159 160
//  Purpose:  
//    Initialize data members in preparation for new layers.
hrchilds's avatar
hrchilds committed
161
//
162
//  Arguments:  None
hrchilds's avatar
hrchilds committed
163
//
164
//  Returns:  None 
hrchilds's avatar
hrchilds committed
165
//
166 167 168 169
//  Assumptions and Comments:
//    Intialization should occur when certain fields of the filter have been
//    modified.  Namely input to the filter, SeedCellId, and
//    AdjacencyType.  Modification of RequestedLayer requires no initialization.
hrchilds's avatar
hrchilds committed
170
//
171
//    first item (slot 0) of layerCellIds is always SeedCellId
bonnell's avatar
bonnell committed
172
//    first item (slot 0) of cellOffsets is always adjacenyType
173
//    (used for modification check in Execute method).
hrchilds's avatar
hrchilds committed
174
//
175 176
//  Programmer: Kathleen S. Bonnell
//  Creation:   5 October 2000
hrchilds's avatar
hrchilds committed
177
//
178 179 180
//  Modifications:
//    Hank Childs, Wed May 22 16:59:53 PDT 2002
//    Also call a callback if the seed cell is invalid.
hrchilds's avatar
hrchilds committed
181
//
bonnell's avatar
bonnell committed
182
//    Kathleen Bonnell, Thu Aug 15 17:48:38 PDT 2002
183
//    Since we are issuing an error callback for a bad seed,
bonnell's avatar
bonnell committed
184
//    don't allow further processing.
hrchilds's avatar
hrchilds committed
185
//
186 187 188
//    Hank Childs, Fri Aug 27 15:15:20 PDT 2004
//    Renamed ghost data arrays.
//
bonnell's avatar
bonnell committed
189
//    Kathleen Bonnell, Tue Jan 18 19:37:46 PST 2005
190 191 192
//    Addeed logic to handle requests for reconstructing original cells,
//    e.g. when connectivity of original input has changed.
//
bonnell's avatar
bonnell committed
193
//    Kathleen Bonnell, Wed Jan 19 15:54:38 PST 2005
194
//    Renamed 'SeedCellId to 'SeedId', 'numCells' arg to 'numIds'.
bonnell's avatar
bonnell committed
195
//    Added code to handle seedId that is a node.
196
//
197 198 199 200
//    Kathleen Biagas, Wed Jul 23 16:40:51 MST 2014
//    Add maxId for error reporting when reconstructing original zones, 
//    otherwise numIds used which is incorrect in this instance.
//
201
// ****************************************************************************
hrchilds's avatar
hrchilds committed
202
bool 
bonnell's avatar
bonnell committed
203
vtkOnionPeelFilter::Initialize(vtkDataSet *input)
hrchilds's avatar
hrchilds committed
204
{
bonnell's avatar
bonnell committed
205
    int numIds = 0;
206
    if (this->SeedIdIsForCell)
bonnell's avatar
bonnell committed
207
       numIds = input->GetNumberOfCells();
208
    else 
bonnell's avatar
bonnell committed
209 210 211 212
       numIds = input->GetNumberOfPoints();

    this->maxLayersReached = 0;
    this->maxLayerNum = VTK_INT_MAX;
hrchilds's avatar
hrchilds committed
213 214 215 216

    if (useLogicalIndex)
    {
        int dims[3] = { 1, 1, 1};
bonnell's avatar
bonnell committed
217
        if (input->GetDataObjectType() == VTK_STRUCTURED_GRID)
hrchilds's avatar
hrchilds committed
218
        {
bonnell's avatar
bonnell committed
219
            ((vtkStructuredGrid*)input)->GetDimensions(dims);
hrchilds's avatar
hrchilds committed
220
        }
bonnell's avatar
bonnell committed
221
        else if (input->GetDataObjectType() == VTK_RECTILINEAR_GRID)
hrchilds's avatar
hrchilds committed
222
        {
bonnell's avatar
bonnell committed
223
            ((vtkRectilinearGrid*)input)->GetDimensions(dims);
hrchilds's avatar
hrchilds committed
224 225 226 227 228 229 230
        }
        if (this->logicalIndex[0] >= dims[0] ||
            this->logicalIndex[1] >= dims[1] ||
            this->logicalIndex[2] >= dims[2])
        {
            if (bsc_callback != NULL) 
            {
hrchilds's avatar
hrchilds committed
231
                bsc_callback(bsc_args, SeedId, numIds, false);
hrchilds's avatar
hrchilds committed
232 233
           
            } 
hrchilds's avatar
hrchilds committed
234
            vtkWarningMacro(<<"SeedIndex (" << this->logicalIndex[0] << " "
hrchilds's avatar
hrchilds committed
235 236 237 238 239
                << this->logicalIndex[1] << " " << this->logicalIndex[2] 
                << ")  Exceeds dimensions of dataset ("
                << dims[0] << " " << dims[1] << " " << dims[2] << ").");
            return false; //unsuccessful initialization
        } 
hrchilds's avatar
hrchilds committed
240 241 242
        if (this->SeedIdIsForCell)
        {
            this->SeedId = this->logicalIndex[2]*(dims[0]-1)*(dims[1]-1) + 
hrchilds's avatar
hrchilds committed
243 244
                           this->logicalIndex[1]*(dims[0]-1) + 
                           this->logicalIndex[0];
hrchilds's avatar
hrchilds committed
245 246 247 248 249 250 251
        } 
        else 
        {
            this->SeedId = this->logicalIndex[2]*(dims[0])*(dims[1]) + 
                           this->logicalIndex[1]*(dims[0]) + 
                           this->logicalIndex[0];
        } 
hrchilds's avatar
hrchilds committed
252 253
    }
    // check for out-of-range error on seedcellId;
254 255
    if (!this->ReconstructOriginalCells &&
       (this->SeedId < 0 || this->SeedId >= numIds))
hrchilds's avatar
hrchilds committed
256 257 258 259 260
    {
        if (bsc_callback != NULL) 
        {
            if (useLogicalIndex)
            {
hrchilds's avatar
hrchilds committed
261
                bsc_callback(bsc_args, SeedId, numIds, false);
hrchilds's avatar
hrchilds committed
262 263 264
            }
            else 
            {
hrchilds's avatar
hrchilds committed
265
                bsc_callback(bsc_args, SeedId, numIds, false);
hrchilds's avatar
hrchilds committed
266 267
            }
        }
hrchilds's avatar
hrchilds committed
268 269
        vtkWarningMacro(<<"SeedId " << this->SeedId << " is Invalid."
                        <<"\nValid ids range from 0 to " << numIds-1 << ".");
hrchilds's avatar
hrchilds committed
270 271 272 273 274
        return false; //unsuccessful initialization
    }
    //
    // check if seedcellId is a ghost cell;
    //
hrchilds's avatar
hrchilds committed
275 276
    vtkDataArray *ghosts;
    if (this->SeedIdIsForCell)
bonnell's avatar
bonnell committed
277
       ghosts = input->GetCellData()->GetArray("avtGhostZones");
hrchilds's avatar
hrchilds committed
278
    else
bonnell's avatar
bonnell committed
279
       ghosts = input->GetCellData()->GetArray("avtGhostNodes");
hrchilds's avatar
hrchilds committed
280 281
    if (ghosts)
    {
hrchilds's avatar
hrchilds committed
282
        if (ghosts->GetComponent(this->SeedId, 0) != 0)
hrchilds's avatar
hrchilds committed
283 284 285 286 287
        {
            if (bsc_callback != NULL) 
            {
                if (useLogicalIndex)
                {
hrchilds's avatar
hrchilds committed
288
                    bsc_callback(bsc_args, SeedId, numIds, true);
hrchilds's avatar
hrchilds committed
289 290 291
                }
                else 
                {
hrchilds's avatar
hrchilds committed
292
                    bsc_callback(bsc_args, SeedId, numIds, true);
hrchilds's avatar
hrchilds committed
293 294
                }
            }
hrchilds's avatar
hrchilds committed
295
            vtkWarningMacro(<<"SeedId " << this->SeedId << " is a Ghost Cell.");
hrchilds's avatar
hrchilds committed
296 297 298 299 300 301
            return false; //unsuccessful initialization
        }
    }

    this->layerCellIds->Reset();
    this->cellOffsets->Reset();
hrchilds's avatar
hrchilds committed
302
    if (this->SeedIdIsForCell)
hrchilds's avatar
hrchilds committed
303
    {
hrchilds's avatar
hrchilds committed
304 305 306 307 308 309
        if (!this->ReconstructOriginalCells)
        {
            this->layerCellIds->InsertNextId(this->SeedId);
        }
        else 
        {
310 311
            int maxId=-1;
            this->FindCellsCorrespondingToOriginal(input, this->SeedId, this->layerCellIds, maxId);
hrchilds's avatar
hrchilds committed
312 313 314
            if (this->layerCellIds->GetNumberOfIds() == 0) 
            {
                if (bsc_callback != NULL) 
315
                    bsc_callback(bsc_args, SeedId, (maxId == -1 ? numIds: maxId), false);
hrchilds's avatar
hrchilds committed
316 317 318 319 320
                vtkWarningMacro(<<"SeedId " << this->SeedId 
                                << " is not available from current data.");
                return false; //unsuccessful initialization
            }
        }
hrchilds's avatar
hrchilds committed
321
    }
hrchilds's avatar
hrchilds committed
322
    else  //SeedId is a node Id
hrchilds's avatar
hrchilds committed
323
    {
hrchilds's avatar
hrchilds committed
324
        if (!this->ReconstructOriginalCells)
hrchilds's avatar
hrchilds committed
325
        {
bonnell's avatar
bonnell committed
326
            input->GetPointCells(this->SeedId, this->layerCellIds); 
hrchilds's avatar
hrchilds committed
327 328 329 330 331 332 333 334
            if (this->layerCellIds->GetNumberOfIds() == 0) 
            {
                if (bsc_callback != NULL) 
                    bsc_callback(bsc_args, SeedId, numIds, false);
                vtkWarningMacro(<<"SeedId " << this->SeedId 
                                << " is not available from current data.");
                return false; //unsuccessful initialization
            }
hrchilds's avatar
hrchilds committed
335
        }
hrchilds's avatar
hrchilds committed
336 337 338 339
        else 
        {
            int i;
            vtkIdList *nodes = vtkIdList::New();
bonnell's avatar
bonnell committed
340
            this->FindNodesCorrespondingToOriginal(input, this->SeedId, nodes);
hrchilds's avatar
hrchilds committed
341 342 343 344 345 346 347 348 349 350 351
            if (nodes->GetNumberOfIds() == 0)
            {
                if (bsc_callback != NULL) 
                    bsc_callback(bsc_args, SeedId, numIds, false);
                vtkWarningMacro(<<"SeedId " << this->SeedId 
                                << " is not available from current data.");
                return false; //unsuccessful initialization
            }
            vtkIdList *neighbors = vtkIdList::New();
            for (i = 0; i < nodes->GetNumberOfIds(); i++)
            {
bonnell's avatar
bonnell committed
352
                input->GetPointCells(nodes->GetId(i), neighbors);        
hrchilds's avatar
hrchilds committed
353 354 355 356 357 358 359 360
                for (int nId = 0; nId < neighbors->GetNumberOfIds(); nId++)
                {
                    this->layerCellIds->InsertUniqueId(neighbors->GetId(nId));
                }
            }
            nodes->Delete();
            neighbors->Delete();
            vtkUnsignedIntArray *origCells = vtkUnsignedIntArray::SafeDownCast(
bonnell's avatar
bonnell committed
361
                input->GetCellData()->GetArray("avtOriginalCellNumbers"));
hrchilds's avatar
hrchilds committed
362

363
            int maxId = -1;
hrchilds's avatar
hrchilds committed
364 365 366 367 368 369 370 371 372 373 374 375
            if (origCells)
            {
                unsigned int *oc = origCells->GetPointer(0);
                int nc = origCells->GetNumberOfComponents();
                int comp = nc -1;
                vtkIdList *origIds = vtkIdList::New();
                for (i = 0; i < this->layerCellIds->GetNumberOfIds(); i++)
                {
                        int cellId = this->layerCellIds->GetId(i);
                        int index = cellId *nc + comp;;
                        origIds->InsertNextId(oc[index]);
                }
376
                FindCellsCorrespondingToOriginal(input, origIds, this->layerCellIds, maxId);
hrchilds's avatar
hrchilds committed
377 378 379 380 381 382
                origIds->Delete();
            }
            
            if (this->layerCellIds->GetNumberOfIds() == 0) 
            {
                if (bsc_callback != NULL) 
383
                    bsc_callback(bsc_args, SeedId, (maxId == -1? numIds: maxId), false);
hrchilds's avatar
hrchilds committed
384 385 386 387 388 389
                vtkWarningMacro(<<"SeedId " << this->SeedId 
                                << " is not available from current data.");
                return false; //unsuccessful initialization
            }
        }
    }
hrchilds's avatar
hrchilds committed
390 391 392 393 394 395
    //layer 0 offset always zero, so use zeroth slot to indicate AdjacencyType
    this->cellOffsets->InsertNextId(this->AdjacencyType);
    return true; // successful initialization
} // Initialize


bonnell's avatar
bonnell committed
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
//======================================================================
//
// Method:   vtkOnionPeelFilter::Grow
//
// Purpose:  
//   Adds more layers to the onion peel, up to the layer requested by
//   the user or grid boundaries, whichever is reached first.
// 
// Arguments:  None
// 
// Returns:    None 
// 
// Assumptions and Comments:
//   This method will stop attempting to grow layers when grid
//   boundaries are reached and no more neighbors can be found.  At
//   which point, a warning message is issued and RequestedLayer is
//   set to the maximum layers possible for the current conditions.
//
// Programmer: Kathleen S. Bonnell
// Creation:   5 October 2000
//
// Modifications:
//   Kathleen Bonnell, Thu Aug 15 17:48:38 PDT 2002  
//   Coding style update.
//  
//   Kathleen Bonnell, Tue Jan 18 19:37:46 PST 2005 
//   Addeed logic to handle requests for reconstructing original cells,
//   e.g. when connectivity of original input has changed.
//
//======================================================================
hrchilds's avatar
hrchilds committed
426
void 
bonnell's avatar
bonnell committed
427
vtkOnionPeelFilter::Grow(vtkDataSet *input)
hrchilds's avatar
hrchilds committed
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
{
    vtkIdList  *currentLayerList  = vtkIdList::New();
    int         totalCurrentCells = this->layerCellIds->GetNumberOfIds();
    int         totalLayersGrown  = this->cellOffsets->GetNumberOfIds() - 1;
    int         start = 0, i = 0, j = 0;

    vtkDebugMacro(<<"Grow::");
    while (this->cellOffsets->GetNumberOfIds() <= this->RequestedLayer ) 
    {
        if (this->maxLayersReached) 
        {
            // cannot create more layers, no more neighbors, we
            //  must be at the boundaries of the grid so stop this loop
            vtkWarningMacro(<<"Grid Boundaries reached. \nRequestedLayer has "
                            <<"been set to the maxLayerNum possible.");

            this->RequestedLayer  = this->maxLayerNum 
                                  = this->cellOffsets->GetNumberOfIds()-1;
            break;
        }

        // create list of cell ids for last layer that was grown

        if (totalLayersGrown == 0) 
            start  = 0;
        else
            start = this->cellOffsets->GetId(totalLayersGrown);

        currentLayerList->SetNumberOfIds(this->layerCellIds->GetNumberOfIds() 
                                        - start);

        for (i = start,j = 0; i < this->layerCellIds->GetNumberOfIds(); i++, j++) 
        {
            currentLayerList->InsertId(j, this->layerCellIds->GetId(i));
        }

        // now add another layer by finding neighbors of cells in previous layer 

        if (this->AdjacencyType == VTK_FACE_ADJACENCY)  
        {
bonnell's avatar
bonnell committed
468 469
            FindCellNeighborsByFaceAdjacency(input, currentLayerList, 
                this->layerCellIds);
hrchilds's avatar
hrchilds committed
470 471 472
        }
        else
        {
bonnell's avatar
bonnell committed
473 474
            FindCellNeighborsByNodeAdjacency(input, currentLayerList, 
                this->layerCellIds);
hrchilds's avatar
hrchilds committed
475 476 477 478 479
        }

        // did we add new cells??? 
        if (this->layerCellIds->GetNumberOfIds() > totalCurrentCells) 
        {
hrchilds's avatar
hrchilds committed
480 481 482
            if (this->ReconstructOriginalCells)
            {
                vtkUnsignedIntArray *origCells = vtkUnsignedIntArray::SafeDownCast(
bonnell's avatar
bonnell committed
483
                  input->GetCellData()->GetArray("avtOriginalCellNumbers"));
hrchilds's avatar
hrchilds committed
484 485 486 487 488 489 490 491 492 493 494 495 496 497

                if (origCells)
                {
                    unsigned int *oc = origCells->GetPointer(0);
                    int nc = origCells->GetNumberOfComponents();
                    int comp = nc -1;
                    vtkIdList *origIds = vtkIdList::New();
                    start = totalCurrentCells;
                    for (i = start; i < this->layerCellIds->GetNumberOfIds(); i++)
                    {
                        int cellId = this->layerCellIds->GetId(i);
                        int index = cellId *nc + comp;;
                        origIds->InsertNextId(oc[index]);
                    }
498 499 500
                    int maxId = -1;
                    FindCellsCorrespondingToOriginal(input, origIds, this->layerCellIds, maxId);
                    (void) maxId;
hrchilds's avatar
hrchilds committed
501 502 503
                    origIds->Delete();
                }
            }
hrchilds's avatar
hrchilds committed
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
            // set the offset for this new layer of cells
            this->cellOffsets->InsertNextId(totalCurrentCells);
            totalCurrentCells = this->layerCellIds->GetNumberOfIds();
        }
        else 
        {
            vtkDebugMacro("Grow:  No neighbors found");
            this->maxLayersReached = 1;
        }

        currentLayerList->Reset();
   
    } /* end while */

    currentLayerList->Delete();

} // Grow()


523 524
// ****************************************************************************
//  Method: vtkOnionPeelFilter::RequestData
hrchilds's avatar
hrchilds committed
525
//
bonnell's avatar
bonnell committed
526
//  Purpose:
527
//    vtk Required method. Updates state of the filter by growing
bonnell's avatar
bonnell committed
528
//    onion peel layers as necessary and generating output grid.
529
//    Performs error checking on data set type.
hrchilds's avatar
hrchilds committed
530
//
531
//  Arguments:  None
hrchilds's avatar
hrchilds committed
532
//
533
//  Returns:    None 
hrchilds's avatar
hrchilds committed
534
//
535 536 537 538
//  Assumptions and Comments:
//    Assumes this filter's input data set is rectilinear, structured
//    or unstructured grid only.  Check for this condition performed
//    in Execute() method.
hrchilds's avatar
hrchilds committed
539
//
bonnell's avatar
bonnell committed
540
//    Passes along all of the input points and point data, but only
541
//    cells and cell data corresponding to requested layers.
hrchilds's avatar
hrchilds committed
542
//
543 544
//  Programmer: Kathleen S. Bonnell
//  Creation:   5 October 2000
hrchilds's avatar
hrchilds committed
545
//
546 547 548 549 550
//  Modifications:
//    Kathleen Bonnell, Tue Sep 25 14:32:46 PDT 2001
//    Removed tests for modification, re-excute from scratch each time
//    as is appropriate for the VisIt pipeline.
//
bonnell's avatar
bonnell committed
551
//    Kathleen Bonnell, Thu Aug 15 17:48:38 PDT 2002
552
//    Made Initialize return a bool indicating wheter the initialization
bonnell's avatar
bonnell committed
553
//    was a success or not.  If not, don't process further.
554 555
//
//    Kathleen Bonnell, Wed Jan 19 15:54:38 PST 2005 
bonnell's avatar
bonnell committed
556
//    Use different args for Initialize when seedId is for a node.
557 558
//
// ****************************************************************************
bonnell's avatar
bonnell committed
559

560 561
int
vtkOnionPeelFilter::RequestData(
bonnell's avatar
bonnell committed
562 563 564
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
hrchilds's avatar
hrchilds committed
565
{
bonnell's avatar
bonnell committed
566 567 568
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
hrchilds's avatar
hrchilds committed
569

bonnell's avatar
bonnell committed
570 571 572 573 574
  // get the input and output
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));
hrchilds's avatar
hrchilds committed
575 576 577

    vtkDebugMacro(<<"Generating OnionPeelFilter Layers");

bonnell's avatar
bonnell committed
578
    if (!this->Initialize(input))
hrchilds's avatar
hrchilds committed
579
    {
580
        return 1;
hrchilds's avatar
hrchilds committed
581 582 583 584 585 586 587 588 589 590 591 592
    }
    // check for out-of-range error on RequestedLayer

    if (RequestedLayer > this->maxLayerNum) 
    {
        vtkWarningMacro(<<"Requested Layer greater than max layers possible."
        <<"\nRequestedLayer has been set to the max possible:  "
        << this->maxLayerNum << ".");

        this->RequestedLayer  = this->maxLayerNum ;
    }

bonnell's avatar
bonnell committed
593
    this->Grow(input);
hrchilds's avatar
hrchilds committed
594

bonnell's avatar
bonnell committed
595
    this->GenerateOutputGrid(input, output);
hrchilds's avatar
hrchilds committed
596

597
    return 1;
bonnell's avatar
bonnell committed
598
} // Execute
hrchilds's avatar
hrchilds committed
599 600

      
bonnell's avatar
bonnell committed
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
//======================================================================
//
// Method:   vtkOnionPeelFilter::GenerateOutputGrid
//
// Purpose:  
//   Creates the unstructured grid for output. 
// 
// Arguments:  None
// 
// Returns:    None 
// 
// Assumptions and Comments:
//   Assumes this filter's input data set is rectilinear, structured
//   or unstructured grid only.  Check for this condition performed
//   in Execute() method.
// 
//   Passes along all of the input points and point data, but on.y
//   cells and cell data corresponding to requested layers.
//
// Programmer: Kathleen S. Bonnell
// Creation:   5 October 2000
//
// Modifications:
//   Kathleen Bonnell, Thu Aug 15 17:48:38 PDT 2002  
//   Coding style update.
//  
//   Kathleen Bonnell, Tue Jun 24 14:19:49 PDT 2003 
//   Allow for poly-data input, retrieve points via vtkVisItUtility::GetPoints. 
//  
//   Hank Childs, Thu Mar 10 09:48:47 PST 2005
//   Fix memory leak.
//
//=======================================================================
hrchilds's avatar
hrchilds committed
634
void 
bonnell's avatar
bonnell committed
635 636
vtkOnionPeelFilter::GenerateOutputGrid(vtkDataSet *input, 
    vtkUnstructuredGrid *output)
hrchilds's avatar
hrchilds committed
637 638 639
{
    vtkDebugMacro(<<"GenerateOutputGrid::");

bonnell's avatar
bonnell committed
640 641 642 643
    vtkPointData        *inPD       = input->GetPointData();
    vtkCellData         *inCD       = input->GetCellData();
    vtkPointData        *outPD      = output->GetPointData();
    vtkCellData         *outCD      = output->GetCellData();
hrchilds's avatar
hrchilds committed
644 645 646 647 648 649 650 651 652 653 654
    vtkIdList           *cellPts    = vtkIdList::New();
    int i, cellId, newCellId, totalCells;

    if (this->RequestedLayer < this->cellOffsets->GetNumberOfIds() -1)
    {
        totalCells = this->cellOffsets->GetId(this->RequestedLayer + 1);
    }
    else
    {
        totalCells =  this->layerCellIds->GetNumberOfIds();
    }
bonnell's avatar
bonnell committed
655
    output->Allocate(totalCells);
hrchilds's avatar
hrchilds committed
656 657

    // grab points from input so they can be passed along directly to ouput
bonnell's avatar
bonnell committed
658 659
    vtkPoints *pts = vtkVisItUtility::GetPoints(input);
    output->SetPoints(pts);
hrchilds's avatar
hrchilds committed
660
    pts->Delete();
hrchilds's avatar
hrchilds committed
661 662 663 664 665 666 667 668
 
    outPD->PassData(inPD);
    outCD->CopyAllocate(inCD);

    // grab only the cell data that corresponds to cells in our layers
    for (i = 0; i < totalCells; i++) 
    {
        cellId = layerCellIds->GetId(i);
bonnell's avatar
bonnell committed
669 670
        input->GetCellPoints(cellId, cellPts);
        newCellId = output->InsertNextCell(input->GetCellType(cellId), cellPts);
hrchilds's avatar
hrchilds committed
671 672 673 674
        outCD->CopyData(inCD, cellId, newCellId);
    }

    // free up unused memory in output
bonnell's avatar
bonnell committed
675
    output->Squeeze();
hrchilds's avatar
hrchilds committed
676 677 678 679 680 681 682

    // free memory used locally
    cellPts->Delete();

} // GenerateOutputGrid


bonnell's avatar
bonnell committed
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
//======================================================================
//
// Method:   vtkOnionPeelFilter::PrintSelf
//
// Purpose:  Prints pertinent information regarding the state of this class 
//           to the given output stream.
// 
// Arguments:
//   os      The output stream to which the information is printed
//   indent  The amount of spaces to indent.
// 
// Returns:  None 
// 
// Assumptions and Comments:
//   Calls the superclass method first. 
// 
// Programmer: Kathleen S. Bonnell
// Creation:   5 October 2000
//
// Modifications:
//   Kathleen Bonnell, Thu Aug 15 17:48:38 PDT 2002  
//   Coding style update.
//  
//=======================================================================
void 
vtkOnionPeelFilter::PrintSelf(ostream& os, vtkIndent indent)
{
    this->Superclass::PrintSelf(os,indent);

    os << indent << "Seed Cell Id:    " << this->SeedId << "\n";
    os << indent << "Requested Layer: " << this->RequestedLayer << "\n";
    os << indent << "Adjacency Type:  " 
       << this->GetAdjacencyTypeAsString() << "\n";
}


//======================================================================
//
// Method:   vtkOnionPeelFilter::FindCellNeighborsByNodeAdjacency
//
// Purpose:  Finds all cells in the input grid that share a node with
//           the given cell. 
// 
// 
// Arguments:
//   prevLayerIds       The unique id numbers of the cells for which 
//                      we want to find neighbors 
//   neighborCellIds    Pointer to list of cells in the onion peel layers 
// 
// Returns:             None 
// 
// Assumptions and Comments:
//   upon entry to the method, neighborCellIds contains cell ids from 
//   previously grown layers.  This method adds new (unique) neighbor 
//   cell ids to the list.
//
//   It is assumed that cellId represents a valid cell
// 
// Programmer: Kathleen S. Bonnell
// Creation:   5 October 2000
//
// Modifications:
//   Kathleen Bonnell, Thu Aug 15 17:48:38 PDT 2002  
//   Coding style update.
//  
//=======================================================================
hrchilds's avatar
hrchilds committed
749
void 
bonnell's avatar
bonnell committed
750 751
vtkOnionPeelFilter::FindCellNeighborsByNodeAdjacency(vtkDataSet *input,
    vtkIdList *prevLayerIds, vtkIdList *neighborCellIds)
hrchilds's avatar
hrchilds committed
752 753 754 755 756 757 758 759 760
{
    vtkIdList  *ids        = vtkIdList::New();
    vtkIdList  *neighbors  = vtkIdList::New();
    int         pntId;
    int         nId;
    int         i;

    for (i = 0; i < prevLayerIds->GetNumberOfIds(); i++) 
    {
bonnell's avatar
bonnell committed
761
        input->GetCellPoints(prevLayerIds->GetId(i), ids);
hrchilds's avatar
hrchilds committed
762 763 764

        for (pntId = 0; pntId < ids->GetNumberOfIds(); pntId++) 
        {
bonnell's avatar
bonnell committed
765
            input->GetPointCells(ids->GetId(pntId), neighbors);        
hrchilds's avatar
hrchilds committed
766 767 768 769 770 771 772 773 774 775 776 777 778

            for (nId = 0; nId < neighbors->GetNumberOfIds(); nId++)
            {
                neighborCellIds->InsertUniqueId(neighbors->GetId(nId));
            }
        }
    }

    neighbors->Delete();
    ids->Delete();
}


bonnell's avatar
bonnell committed
779
//======================================================================
hrchilds's avatar
hrchilds committed
780
//
bonnell's avatar
bonnell committed
781
// Method:   vtkOnionPeelFilter::FindCellNeighborsByFaceAdjacency
hrchilds's avatar
hrchilds committed
782
//
bonnell's avatar
bonnell committed
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
// Purpose:  Finds all cells in the input grid that share a face with
//           the given cell.
// 
// 
// Arguments:
//   cellId             The unique id number of the cell for which 
//                      we want to find neighbors 
//   neighborCellIds    Pointer to list of cells in the onion peel layers 
// 
// Returns:             None 
// 
// Assumptions and Comments:
//   upon entry to the method, neighborCellIds contains cell ids from 
//   previously grown layers.  This method adds new (unique) neighbor 
//   cell ids to the list.
hrchilds's avatar
hrchilds committed
798
//
bonnell's avatar
bonnell committed
799
//   It is assumed that cellId represents a valid cell
hrchilds's avatar
hrchilds committed
800
//
bonnell's avatar
bonnell committed
801 802 803 804 805
//   This method does not consider cells below 3D when determining
//   face neighbors.
// 
// Programmer: Kathleen S. Bonnell
// Creation:   5 October 2000
hrchilds's avatar
hrchilds committed
806
//
bonnell's avatar
bonnell committed
807
// Modifications:
808
//
bonnell's avatar
bonnell committed
809 810
//   Kathleen S. Bonnell, Mon Oct 30 10:37:56 PST 2000
//   Added neighbor search via edges for 2D cells. 
811
//
bonnell's avatar
bonnell committed
812 813 814 815 816
//   Kathleen Bonnell, Thu Aug 15 17:48:38 PDT 2002  
//   Coding style update.
//  
//=======================================================================

hrchilds's avatar
hrchilds committed
817
void 
bonnell's avatar
bonnell committed
818 819
vtkOnionPeelFilter::FindCellNeighborsByFaceAdjacency(vtkDataSet *input,
    vtkIdList *prevLayerIds, vtkIdList *neighborCellIds)
hrchilds's avatar
hrchilds committed
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
{
    vtkIdList  *neighbors = vtkIdList::New();
    vtkIdList  *facePts   = NULL;
    vtkIdList  *edgePts   = NULL;
    vtkCell    *cell      = NULL;
    int         faceId;
    int         edgeId;
    int         nId;
    int         i;
    int         cellId;

  
    for (i = 0; i < prevLayerIds->GetNumberOfIds(); i++) 
    {
        cellId = prevLayerIds->GetId(i);
bonnell's avatar
bonnell committed
835
        cell = input->GetCell(cellId);
hrchilds's avatar
hrchilds committed
836 837 838 839 840 841 842

        if (cell->GetCellDimension() > 2) 
        {
            for (faceId = 0; faceId < cell->GetNumberOfFaces(); faceId++) 
            {
                facePts = (cell->GetFace(faceId))->GetPointIds();

bonnell's avatar
bonnell committed
843
                input->GetCellNeighbors(cellId, facePts, neighbors);
hrchilds's avatar
hrchilds committed
844 845 846 847 848 849 850 851 852 853 854 855 856

                for (nId = 0; nId < neighbors->GetNumberOfIds(); nId++) 
                {
                    neighborCellIds->InsertUniqueId(neighbors->GetId(nId));
                }
            }
        } 
        else 
        {
            for (edgeId = 0; edgeId < cell->GetNumberOfEdges(); edgeId++) 
            {
                edgePts = (cell->GetEdge(edgeId))->GetPointIds();

bonnell's avatar
bonnell committed
857
                input->GetCellNeighbors(cellId, edgePts, neighbors);
hrchilds's avatar
hrchilds committed
858 859 860 861 862 863 864 865 866 867 868 869 870

                for (nId = 0; nId < neighbors->GetNumberOfIds(); nId++) 
                {
                    neighborCellIds->InsertUniqueId(neighbors->GetId(nId));
                }
            }
        }
    }
  
    neighbors->Delete();
}


bonnell's avatar
bonnell committed
871
//======================================================================
hrchilds's avatar
hrchilds committed
872
//
bonnell's avatar
bonnell committed
873
// Method:   vtkOnionPeelFilter::SetLogicalIndex
hrchilds's avatar
hrchilds committed
874
//
bonnell's avatar
bonnell committed
875 876 877 878 879 880 881 882
// Purpose:  
//   Set the logical index. 
// 
// Arguments:  
//   i, j, k   The components of the logical Index.
//   
// 
// Returns:    None 
883
//
bonnell's avatar
bonnell committed
884 885
// Programmer: Kathleen Bonnell
// Creation:   August 15, 2002 
886
//
bonnell's avatar
bonnell committed
887 888 889 890
// Modifications:
//  
//=======================================================================

hrchilds's avatar
hrchilds committed
891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
void
vtkOnionPeelFilter::SetLogicalIndex(const int i, const int j, const int k)
{  
    if (!useLogicalIndex ||
        (this->logicalIndex[0] != i) || 
        (this->logicalIndex[1] != j) || 
        (this->logicalIndex[2] != k) )
    {
        this->logicalIndex[0] = i;
        this->logicalIndex[1] = j;
        this->logicalIndex[2] = k;
        this->Modified();
    }
    useLogicalIndex = true;
}

hrchilds's avatar
hrchilds committed
907

bonnell's avatar
bonnell committed
908
//======================================================================
hrchilds's avatar
hrchilds committed
909
//
bonnell's avatar
bonnell committed
910
// Method:   vtkOnionPeelFilter::SetSeedId
hrchilds's avatar
hrchilds committed
911
//
bonnell's avatar
bonnell committed
912 913 914 915 916 917 918
// Purpose:  
//   Set the seed cell id. 
// 
// Arguments:  
//   seed   The new seed cell id.
//   
// Returns:    None 
919
//
bonnell's avatar
bonnell committed
920 921
// Programmer: Kathleen Bonnell
// Creation:   August 15, 2002 
922
//
bonnell's avatar
bonnell committed
923 924 925 926
// Modifications:
//  
//=======================================================================

hrchilds's avatar
hrchilds committed
927
void
hrchilds's avatar
hrchilds committed
928
vtkOnionPeelFilter::SetSeedId(const int seed)
hrchilds's avatar
hrchilds committed
929
{  
hrchilds's avatar
hrchilds committed
930
    if (useLogicalIndex || this->SeedId != seed)
hrchilds's avatar
hrchilds committed
931
    {
hrchilds's avatar
hrchilds committed
932
        this->SeedId = seed;
hrchilds's avatar
hrchilds committed
933 934 935 936
        this->Modified();
    }
    useLogicalIndex = false;
}
hrchilds's avatar
hrchilds committed
937 938


bonnell's avatar
bonnell committed
939
//======================================================================
hrchilds's avatar
hrchilds committed
940
//
bonnell's avatar
bonnell committed
941
// Method:   vtkOnionPeelFilter::FindCellsCorrespondingToOriginal
hrchilds's avatar
hrchilds committed
942
//
bonnell's avatar
bonnell committed
943 944 945 946 947 948 949 950 951
// Purpose:  
//   Finds all cells whose 'originalCell' designation matches the
//   original id passed as arg. 
// 
// Arguments:  
//   orig      The original cell id. 
//   group     A place to store the corresponding cells.
//   
// Returns:    None 
hrchilds's avatar
hrchilds committed
952
//
bonnell's avatar
bonnell committed
953 954
// Programmer: Kathleen Bonnell
// Creation:   January 18, 2005 
hrchilds's avatar
hrchilds committed
955
//
bonnell's avatar
bonnell committed
956 957 958 959
// Modifications:
//   Kathleen Bonnell, Tue Jun 14 11:45:21 PDT 2005
//   Correct 'n' for loop counting.
//  
960 961 962
//   Kathleen Biagas, Wed Jul 23 16:42:06 MST 2014
//   Added maxId, used in error reporting.
//
bonnell's avatar
bonnell committed
963 964
//=======================================================================

hrchilds's avatar
hrchilds committed
965
void
bonnell's avatar
bonnell committed
966
vtkOnionPeelFilter::FindCellsCorrespondingToOriginal(vtkDataSet *input,
967
    int orig, vtkIdList *group, int &maxId)
hrchilds's avatar
hrchilds committed
968 969
{
    vtkUnsignedIntArray *origCells = vtkUnsignedIntArray::SafeDownCast(
bonnell's avatar
bonnell committed
970
        input->GetCellData()->GetArray("avtOriginalCellNumbers"));
hrchilds's avatar
hrchilds committed
971 972 973 974 975

    if (origCells)
    {
        unsigned int *oc = origCells->GetPointer(0);
        int nc = origCells->GetNumberOfComponents();
hrchilds's avatar
hrchilds committed
976
        int n = origCells->GetNumberOfTuples() *nc;
hrchilds's avatar
hrchilds committed
977
        int comp = nc -1;
978
        maxId = -1;
hrchilds's avatar
hrchilds committed
979 980 981
        for (int i = comp; i < n; i+=nc )
        {
            int id = i / nc;
982
            maxId = (int)oc[i] > maxId ? (int)oc[i] : maxId; 
983
            if (oc[i] == (unsigned int)orig && group->IsId(id) == -1)
hrchilds's avatar
hrchilds committed
984 985 986 987 988 989
                group->InsertNextId(id);
        }
    }
}


bonnell's avatar
bonnell committed
990
//======================================================================
hrchilds's avatar
hrchilds committed
991
//
bonnell's avatar
bonnell committed
992
// Method:   vtkOnionPeelFilter::FindCellsCorrespondingToOriginal
hrchilds's avatar
hrchilds committed
993
//
bonnell's avatar
bonnell committed
994 995 996 997 998 999 1000 1001 1002
// Purpose:  
//   Finds all cells whose 'originalCell' designation matches the
//   original ids passed as arg. 
// 
// Arguments:  
//   origi     A list of original ids. 
//   group     A place to store the corresponding cells.
//   
// Returns:    None 
1003
//
bonnell's avatar
bonnell committed
1004 1005
// Programmer: Kathleen Bonnell
// Creation:   January 18, 2005 
1006
//
bonnell's avatar
bonnell committed
1007 1008 1009 1010
// Modifications:
//   Kathleen Bonnell, Tue Jun 14 11:45:21 PDT 2005
//   Correct 'n' for loop counting.
//  
1011 1012 1013
//   Kathleen Biagas, Wed Jul 23 16:42:06 MST 2014
//   Added maxId, used in error reporting.
//
bonnell's avatar
bonnell committed
1014 1015
//=======================================================================

hrchilds's avatar
hrchilds committed
1016
void
bonnell's avatar
bonnell committed
1017
vtkOnionPeelFilter::FindCellsCorrespondingToOriginal(vtkDataSet *input,
1018
    vtkIdList *origs, vtkIdList *group, int &maxId)
hrchilds's avatar
hrchilds committed
1019 1020
{
    vtkUnsignedIntArray *origCells = vtkUnsignedIntArray::SafeDownCast(
bonnell's avatar
bonnell committed
1021
        input->GetCellData()->GetArray("avtOriginalCellNumbers"));
hrchilds's avatar
hrchilds committed
1022

hrchilds's avatar
hrchilds committed
1023 1024 1025 1026
    if (origCells)
    {
        unsigned int *oc = origCells->GetPointer(0);
        int nc = origCells->GetNumberOfComponents();
hrchilds's avatar
hrchilds committed
1027
        int n = origCells->GetNumberOfTuples()*nc;
hrchilds's avatar
hrchilds committed
1028
        int comp = nc -1;
1029
        maxId = -1;
hrchilds's avatar
hrchilds committed
1030 1031 1032
        for (int i = comp; i < n; i+=nc)
        {
            int id = i / nc;
1033
            maxId = (int)oc[i] > maxId ? (int)oc[i] : maxId;
hrchilds's avatar
hrchilds committed
1034 1035 1036 1037 1038
            if (origs->IsId(oc[i]) != -1 && group->IsId(id) == -1)
                group->InsertNextId(id);
        }
    }
}
hrchilds's avatar
hrchilds committed
1039

bonnell's avatar
bonnell committed
1040
//======================================================================
hrchilds's avatar
hrchilds committed
1041
//
bonnell's avatar
bonnell committed
1042
// Method:   vtkOnionPeelFilter::FindNodesCorrespondingToOriginal
hrchilds's avatar
hrchilds committed
1043
//
bonnell's avatar
bonnell committed
1044 1045 1046 1047 1048 1049 1050 1051 1052
// Purpose:  
//   Finds all nodes whose 'originalNode' designation matches the
//   original id passed as arg. 
// 
// Arguments:  
//   orig      The original node id. 
//   group     A place to store the corresponding cells.
//   
// Returns:    None 
1053
//
bonnell's avatar
bonnell committed
1054 1055
// Programmer: Kathleen Bonnell
// Creation:   January 19, 2005 
1056
//
bonnell's avatar
bonnell committed
1057 1058 1059 1060 1061 1062
// Modifications:
//   Kathleen Bonnell, Tue Jun 14 11:45:21 PDT 2005
//   Correct 'n' for loop counting.
//  
//=======================================================================

hrchilds's avatar
hrchilds committed
1063
void
bonnell's avatar
bonnell committed
1064 1065
vtkOnionPeelFilter::FindNodesCorrespondingToOriginal(vtkDataSet *input,
    int orig, vtkIdList *group)
hrchilds's avatar
hrchilds committed
1066 1067
{
    vtkIntArray *origNodes = vtkIntArray::SafeDownCast(
bonnell's avatar
bonnell committed
1068
        input->GetPointData()->GetArray("avtOriginalNodeNumbers"));
hrchilds's avatar
hrchilds committed
1069 1070 1071 1072 1073

    if (origNodes)
    {
        int *on = origNodes->GetPointer(0);
        int nc = origNodes->GetNumberOfComponents();
hrchilds's avatar
hrchilds committed
1074
        int n = origNodes->GetNumberOfTuples() *nc;
hrchilds's avatar
hrchilds committed
1075 1076 1077 1078 1079 1080 1081 1082 1083
        int comp = nc -1;
        for (int i = comp; i < n; i+=nc )
        {
            int id = i / nc;
            if (on[i] == orig && group->IsId(id) == -1)
                group->InsertNextId(id);
        }
    }
}
bonnell's avatar
bonnell committed
1084 1085 1086 1087 1088 1089 1090 1091


int 
vtkOnionPeelFilter::FillInputPortInformation(int, vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
  return 1;
}