1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPolyData.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkPolyData.h"
16
17 #include "vtkCellArray.h"
18 #include "vtkCellData.h"
19 #include "vtkCriticalSection.h"
20 #include "vtkEmptyCell.h"
21 #include "vtkGenericCell.h"
22 #include "vtkInformation.h"
23 #include "vtkInformationVector.h"
24 #include "vtkLine.h"
25 #include "vtkNew.h"
26 #include "vtkObjectFactory.h"
27 #include "vtkPointData.h"
28 #include "vtkPointLocator.h"
29 #include "vtkPolyLine.h"
30 #include "vtkPolyVertex.h"
31 #include "vtkPolygon.h"
32 #include "vtkQuad.h"
33 #include "vtkTriangle.h"
34 #include "vtkTriangleStrip.h"
35 #include "vtkVertex.h"
36
37 #include "vtkSmartPointer.h"
38
39 vtkStandardNewMacro(vtkPolyData);
40
41 //----------------------------------------------------------------------------
42 // Initialize static member. This member is used to simplify traversal
43 // of verts, lines, polygons, and triangle strips lists. It basically
44 // "marks" empty lists so that the traveral method "GetNextCell"
45 // works properly.
46
47 struct vtkPolyDataDummyContainter
48 {
49 vtkSmartPointer<vtkCellArray> Dummy;
50
vtkPolyDataDummyContaintervtkPolyDataDummyContainter51 vtkPolyDataDummyContainter()
52 {
53 this->Dummy.TakeReference(vtkCellArray::New());
54 }
55 };
56
57 vtkPolyDataDummyContainter vtkPolyData::DummyContainer;
58
vtkPolyData()59 vtkPolyData::vtkPolyData ()
60 {
61 // Create these guys only when needed. This saves a huge amount
62 // of memory and time spent in memory allocation.
63 this->Vertex = NULL;
64 this->PolyVertex = NULL;
65 this->Line = NULL;
66 this->PolyLine = NULL;
67 this->Triangle = NULL;
68 this->Quad = NULL;
69 this->Polygon = NULL;
70 this->TriangleStrip = NULL;
71 this->EmptyCell = NULL;
72
73 this->Verts = NULL;
74 this->Lines = NULL;
75 this->Polys = NULL;
76 this->Strips = NULL;
77
78 this->Information->Set(vtkDataObject::DATA_EXTENT_TYPE(), VTK_PIECES_EXTENT);
79 this->Information->Set(vtkDataObject::DATA_PIECE_NUMBER(), -1);
80 this->Information->Set(vtkDataObject::DATA_NUMBER_OF_PIECES(), 1);
81 this->Information->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 0);
82
83 this->Cells = NULL;
84 this->Links = NULL;
85 }
86
87 //----------------------------------------------------------------------------
~vtkPolyData()88 vtkPolyData::~vtkPolyData()
89 {
90 this->Cleanup();
91
92 if (this->Vertex)
93 {
94 this->Vertex->Delete();
95 }
96
97 if (this->PolyVertex)
98 {
99 this->PolyVertex->Delete();
100 }
101
102 if (this->Line)
103 {
104 this->Line->Delete();
105 }
106
107 if (this->PolyLine)
108 {
109 this->PolyLine->Delete();
110 }
111
112 if (this->Triangle)
113 {
114 this->Triangle->Delete();
115 }
116
117 if (this->Quad)
118 {
119 this->Quad->Delete();
120 }
121
122 if (this->Polygon)
123 {
124 this->Polygon->Delete();
125 }
126
127 if (this->TriangleStrip)
128 {
129 this->TriangleStrip->Delete();
130 }
131
132 if (this->EmptyCell)
133 {
134 this->EmptyCell->Delete();
135 }
136 }
137
138 //----------------------------------------------------------------------------
GetPiece()139 int vtkPolyData::GetPiece()
140 {
141 return this->Information->Get(vtkDataObject::DATA_PIECE_NUMBER());
142 }
143
144 //----------------------------------------------------------------------------
GetNumberOfPieces()145 int vtkPolyData::GetNumberOfPieces()
146 {
147 return this->Information->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
148 }
149
150 //----------------------------------------------------------------------------
GetGhostLevel()151 int vtkPolyData::GetGhostLevel()
152 {
153 return this->Information->Get(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS());
154 }
155
156 //----------------------------------------------------------------------------
157 // Copy the geometric and topological structure of an input poly data object.
CopyStructure(vtkDataSet * ds)158 void vtkPolyData::CopyStructure(vtkDataSet *ds)
159 {
160 vtkPolyData *pd=static_cast<vtkPolyData *>(ds);
161 vtkPointSet::CopyStructure(ds);
162
163 if (this->Verts != pd->Verts)
164 {
165 if (this->Verts)
166 {
167 this->Verts->UnRegister(this);
168 }
169 this->Verts = pd->Verts;
170 if (this->Verts)
171 {
172 this->Verts->Register(this);
173 }
174 }
175
176 if (this->Lines != pd->Lines)
177 {
178 if (this->Lines)
179 {
180 this->Lines->UnRegister(this);
181 }
182 this->Lines = pd->Lines;
183 if (this->Lines)
184 {
185 this->Lines->Register(this);
186 }
187 }
188
189 if (this->Polys != pd->Polys)
190 {
191 if (this->Polys)
192 {
193 this->Polys->UnRegister(this);
194 }
195 this->Polys = pd->Polys;
196 if (this->Polys)
197 {
198 this->Polys->Register(this);
199 }
200 }
201
202 if (this->Strips != pd->Strips)
203 {
204 if (this->Strips)
205 {
206 this->Strips->UnRegister(this);
207 }
208 this->Strips = pd->Strips;
209 if (this->Strips)
210 {
211 this->Strips->Register(this);
212 }
213 }
214
215 if ( this->Cells )
216 {
217 this->Cells->UnRegister(this);
218 this->Cells = NULL;
219 }
220
221 if ( this->Links )
222 {
223 this->Links->UnRegister(this);
224 this->Links = NULL;
225 }
226 }
227
228 //----------------------------------------------------------------------------
GetCellType(vtkIdType cellId)229 int vtkPolyData::GetCellType(vtkIdType cellId)
230 {
231 if ( !this->Cells )
232 {
233 this->BuildCells();
234 }
235 return this->Cells->GetCellType(cellId);
236 }
237
238 //----------------------------------------------------------------------------
GetCell(vtkIdType cellId)239 vtkCell *vtkPolyData::GetCell(vtkIdType cellId)
240 {
241 int i, loc;
242 vtkIdType *pts, numPts;
243 vtkCell *cell = NULL;
244 unsigned char type;
245
246 if ( !this->Cells )
247 {
248 this->BuildCells();
249 }
250
251 type = this->Cells->GetCellType(cellId);
252 loc = this->Cells->GetCellLocation(cellId);
253
254 switch (type)
255 {
256 case VTK_VERTEX:
257 if (!this->Vertex)
258 {
259 this->Vertex = vtkVertex::New();
260 }
261 cell = this->Vertex;
262 this->Verts->GetCell(loc,numPts,pts);
263 break;
264
265 case VTK_POLY_VERTEX:
266 if (! this->PolyVertex)
267 {
268 this->PolyVertex = vtkPolyVertex::New();
269 }
270 cell = this->PolyVertex;
271 this->Verts->GetCell(loc,numPts,pts);
272 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
273 cell->Points->SetNumberOfPoints(numPts);
274 break;
275
276 case VTK_LINE:
277 if (! this->Line )
278 {
279 this->Line = vtkLine::New();
280 }
281 cell = this->Line;
282 this->Lines->GetCell(loc,numPts,pts);
283 break;
284
285 case VTK_POLY_LINE:
286 if (!this->PolyLine)
287 {
288 this->PolyLine = vtkPolyLine::New();
289 }
290 cell = this->PolyLine;
291 this->Lines->GetCell(loc,numPts,pts);
292 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
293 cell->Points->SetNumberOfPoints(numPts);
294 break;
295
296 case VTK_TRIANGLE:
297 if (!this->Triangle)
298 {
299 this->Triangle = vtkTriangle::New();
300 }
301 cell = this->Triangle;
302 this->Polys->GetCell(loc,numPts,pts);
303 break;
304
305 case VTK_QUAD:
306 if (!this->Quad)
307 {
308 this->Quad = vtkQuad::New();
309 }
310 cell = this->Quad;
311 this->Polys->GetCell(loc,numPts,pts);
312 break;
313
314 case VTK_POLYGON:
315 if (!this->Polygon)
316 {
317 this->Polygon = vtkPolygon::New();
318 }
319 cell = this->Polygon;
320 this->Polys->GetCell(loc,numPts,pts);
321 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
322 cell->Points->SetNumberOfPoints(numPts);
323 break;
324
325 case VTK_TRIANGLE_STRIP:
326 if (!this->TriangleStrip)
327 {
328 this->TriangleStrip = vtkTriangleStrip::New();
329 }
330 cell = this->TriangleStrip;
331 this->Strips->GetCell(loc,numPts,pts);
332 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
333 cell->Points->SetNumberOfPoints(numPts);
334 break;
335
336 default:
337 if (!this->EmptyCell)
338 {
339 this->EmptyCell = vtkEmptyCell::New();
340 }
341 cell = this->EmptyCell;
342 return cell;
343 }
344
345 for (i=0; i < numPts; i++)
346 {
347 cell->PointIds->SetId(i,pts[i]);
348 cell->Points->SetPoint(i,this->Points->GetPoint(pts[i]));
349 }
350
351 return cell;
352 }
353
354 //----------------------------------------------------------------------------
GetCell(vtkIdType cellId,vtkGenericCell * cell)355 void vtkPolyData::GetCell(vtkIdType cellId, vtkGenericCell *cell)
356 {
357 int i, loc;
358 vtkIdType *pts=0;
359 vtkIdType numPts;
360 unsigned char type;
361 double x[3];
362
363 if ( !this->Cells )
364 {
365 this->BuildCells();
366 }
367
368 type = this->Cells->GetCellType(cellId);
369 loc = this->Cells->GetCellLocation(cellId);
370
371 switch (type)
372 {
373 case VTK_VERTEX:
374 cell->SetCellTypeToVertex();
375 this->Verts->GetCell(loc,numPts,pts);
376 break;
377
378 case VTK_POLY_VERTEX:
379 cell->SetCellTypeToPolyVertex();
380 this->Verts->GetCell(loc,numPts,pts);
381 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
382 cell->Points->SetNumberOfPoints(numPts);
383 break;
384
385 case VTK_LINE:
386 cell->SetCellTypeToLine();
387 this->Lines->GetCell(loc,numPts,pts);
388 break;
389
390 case VTK_POLY_LINE:
391 cell->SetCellTypeToPolyLine();
392 this->Lines->GetCell(loc,numPts,pts);
393 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
394 cell->Points->SetNumberOfPoints(numPts);
395 break;
396
397 case VTK_TRIANGLE:
398 cell->SetCellTypeToTriangle();
399 this->Polys->GetCell(loc,numPts,pts);
400 break;
401
402 case VTK_QUAD:
403 cell->SetCellTypeToQuad();
404 this->Polys->GetCell(loc,numPts,pts);
405 break;
406
407 case VTK_POLYGON:
408 cell->SetCellTypeToPolygon();
409 this->Polys->GetCell(loc,numPts,pts);
410 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
411 cell->Points->SetNumberOfPoints(numPts);
412 break;
413
414 case VTK_TRIANGLE_STRIP:
415 cell->SetCellTypeToTriangleStrip();
416 this->Strips->GetCell(loc,numPts,pts);
417 cell->PointIds->SetNumberOfIds(numPts); //reset number of points
418 cell->Points->SetNumberOfPoints(numPts);
419 break;
420
421 default:
422 cell->SetCellTypeToEmptyCell();
423 numPts = 0;
424 }
425
426 for (i=0; i < numPts; i++)
427 {
428 cell->PointIds->SetId(i,pts[i]);
429 this->Points->GetPoint(pts[i], x);
430 cell->Points->SetPoint(i, x);
431 }
432 }
433
434 //----------------------------------------------------------------------------
CopyCells(vtkPolyData * pd,vtkIdList * idList,vtkPointLocator * locator)435 void vtkPolyData::CopyCells(vtkPolyData *pd, vtkIdList *idList,
436 vtkPointLocator *locator)
437 {
438 vtkIdType cellId, ptId, newId, newCellId, locatorPtId;
439 int numPts, numCellPts, i;
440 vtkPoints *newPoints;
441 vtkIdList *pointMap = vtkIdList::New(); //maps old pt ids into new
442 vtkIdList *cellPts, *newCellPts = vtkIdList::New();
443 vtkGenericCell *cell = vtkGenericCell::New();
444 double x[3];
445 vtkPointData *outPD = this->GetPointData();
446 vtkCellData *outCD = this->GetCellData();
447
448 numPts = pd->GetNumberOfPoints();
449
450 if (this->GetPoints() == NULL)
451 {
452 this->Points = vtkPoints::New();
453 }
454
455 newPoints = this->GetPoints();
456
457 pointMap->SetNumberOfIds(numPts);
458 for (i=0; i < numPts; i++)
459 {
460 pointMap->SetId(i,-1);
461 }
462
463 // Filter the cells
464 for (cellId=0; cellId < idList->GetNumberOfIds(); cellId++)
465 {
466 pd->GetCell(idList->GetId(cellId), cell);
467 cellPts = cell->GetPointIds();
468 numCellPts = cell->GetNumberOfPoints();
469
470 for (i=0; i < numCellPts; i++)
471 {
472 ptId = cellPts->GetId(i);
473 if ( (newId = pointMap->GetId(ptId)) < 0 )
474 {
475 pd->GetPoint(ptId, x);
476 if (locator != NULL)
477 {
478 if ((locatorPtId = locator->IsInsertedPoint(x)) == -1)
479 {
480 newId = newPoints->InsertNextPoint(x);
481 locator->InsertNextPoint(x);
482 pointMap->SetId(ptId, newId);
483 outPD->CopyData(pd->GetPointData(), ptId, newId);
484 }
485 else
486 {
487 newId = locatorPtId;
488 }
489 }
490 else
491 {
492 newId = newPoints->InsertNextPoint(x);
493 pointMap->SetId(ptId, newId);
494 outPD->CopyData(pd->GetPointData(), ptId, newId);
495 }
496 }
497 newCellPts->InsertId(i,newId);
498 }
499 newCellId = this->InsertNextCell(cell->GetCellType(), newCellPts);
500 outCD->CopyData(pd->GetCellData(), idList->GetId(cellId), newCellId);
501 newCellPts->Reset();
502 } // for all cells
503 newCellPts->Delete();
504 pointMap->Delete();
505 cell->Delete();
506 }
507
508 //----------------------------------------------------------------------------
509 // Fast implementation of GetCellBounds(). Bounds are calculated without
510 // constructing a cell.
GetCellBounds(vtkIdType cellId,double bounds[6])511 void vtkPolyData::GetCellBounds(vtkIdType cellId, double bounds[6])
512 {
513 int i, loc;
514 vtkIdType *pts, numPts;
515 unsigned char type;
516 double x[3];
517
518 if ( !this->Cells )
519 {
520 this->BuildCells();
521 }
522
523 type = this->Cells->GetCellType(cellId);
524 loc = this->Cells->GetCellLocation(cellId);
525
526 switch (type)
527 {
528 case VTK_VERTEX:
529 case VTK_POLY_VERTEX:
530 this->Verts->GetCell(loc,numPts,pts);
531 break;
532
533 case VTK_LINE:
534 case VTK_POLY_LINE:
535 this->Lines->GetCell(loc,numPts,pts);
536 break;
537
538 case VTK_TRIANGLE:
539 case VTK_QUAD:
540 case VTK_POLYGON:
541 this->Polys->GetCell(loc,numPts,pts);
542 break;
543
544 case VTK_TRIANGLE_STRIP:
545 this->Strips->GetCell(loc,numPts,pts);
546 break;
547
548 default:
549 bounds[0] = bounds[1] = bounds[2] = bounds[3] = bounds[4] = bounds[5]
550 = 0.0;
551 return;
552 }
553
554 // carefully compute the bounds
555 if (numPts)
556 {
557 this->Points->GetPoint( pts[0], x );
558 bounds[0] = x[0];
559 bounds[2] = x[1];
560 bounds[4] = x[2];
561 bounds[1] = x[0];
562 bounds[3] = x[1];
563 bounds[5] = x[2];
564 for (i=1; i < numPts; i++)
565 {
566 this->Points->GetPoint( pts[i], x );
567 bounds[0] = (x[0] < bounds[0] ? x[0] : bounds[0]);
568 bounds[1] = (x[0] > bounds[1] ? x[0] : bounds[1]);
569 bounds[2] = (x[1] < bounds[2] ? x[1] : bounds[2]);
570 bounds[3] = (x[1] > bounds[3] ? x[1] : bounds[3]);
571 bounds[4] = (x[2] < bounds[4] ? x[2] : bounds[4]);
572 bounds[5] = (x[2] > bounds[5] ? x[2] : bounds[5]);
573 }
574 }
575 else
576 {
577 vtkMath::UninitializeBounds(bounds);
578 }
579 }
580
581
582 //----------------------------------------------------------------------------
ComputeBounds()583 void vtkPolyData::ComputeBounds()
584 {
585 if (this->GetMTime() > this->ComputeTime)
586 {
587 // If there are no cells, but there are points, back to the
588 // bounds of the points set.
589 if (this->GetNumberOfCells() == 0 && this->GetNumberOfPoints())
590 {
591 vtkPointSet::ComputeBounds();
592 return;
593 }
594
595 int t, i;
596 vtkIdType *pts = 0;
597 vtkIdType npts = 0;
598 double x[3];
599
600 vtkCellArray *cella[4];
601
602 cella[0] = this->GetVerts();
603 cella[1] = this->GetLines();
604 cella[2] = this->GetPolys();
605 cella[3] = this->GetStrips();
606
607 // carefully compute the bounds
608 int doneOne = 0;
609 this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = VTK_DOUBLE_MAX;
610 this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -VTK_DOUBLE_MAX;
611
612 // Iterate over cells's points
613 for (t = 0; t < 4; t++)
614 {
615 for (cella[t]->InitTraversal(); cella[t]->GetNextCell(npts,pts); )
616 {
617 for (i = 0; i < npts; i++)
618 {
619 this->Points->GetPoint( pts[i], x );
620 this->Bounds[0] = (x[0] < this->Bounds[0] ? x[0] : this->Bounds[0]);
621 this->Bounds[1] = (x[0] > this->Bounds[1] ? x[0] : this->Bounds[1]);
622 this->Bounds[2] = (x[1] < this->Bounds[2] ? x[1] : this->Bounds[2]);
623 this->Bounds[3] = (x[1] > this->Bounds[3] ? x[1] : this->Bounds[3]);
624 this->Bounds[4] = (x[2] < this->Bounds[4] ? x[2] : this->Bounds[4]);
625 this->Bounds[5] = (x[2] > this->Bounds[5] ? x[2] : this->Bounds[5]);
626 doneOne = 1;
627 }
628 }
629 }
630 if (!doneOne)
631 {
632 vtkMath::UninitializeBounds(this->Bounds);
633 }
634 this->ComputeTime.Modified();
635 }
636 }
637
638 //----------------------------------------------------------------------------
639 // Set the cell array defining vertices.
SetVerts(vtkCellArray * v)640 void vtkPolyData::SetVerts (vtkCellArray* v)
641 {
642 if (v == this->DummyContainer.Dummy.GetPointer())
643 {
644 v = NULL;
645 }
646 if ( v != this->Verts)
647 {
648 if (this->Verts)
649 {
650 this->Verts->UnRegister(this);
651 }
652 this->Verts = v;
653 if (this->Verts)
654 {
655 this->Verts->Register(this);
656 }
657 this->Modified();
658 }
659 }
660
661 //----------------------------------------------------------------------------
662 // Get the cell array defining vertices. If there are no vertices, an
663 // empty array will be returned (convenience to simplify traversal).
GetVerts()664 vtkCellArray* vtkPolyData::GetVerts()
665 {
666 if ( !this->Verts )
667 {
668 return this->DummyContainer.Dummy.GetPointer();
669 }
670 else
671 {
672 return this->Verts;
673 }
674 }
675
676 //----------------------------------------------------------------------------
677 // Set the cell array defining lines.
SetLines(vtkCellArray * l)678 void vtkPolyData::SetLines (vtkCellArray* l)
679 {
680 if (l == this->DummyContainer.Dummy.GetPointer())
681 {
682 l = NULL;
683 }
684 if ( l != this->Lines)
685 {
686 if (this->Lines)
687 {
688 this->Lines->UnRegister(this);
689 }
690 this->Lines = l;
691 if (this->Lines)
692 {
693 this->Lines->Register(this);
694 }
695 this->Modified();
696 }
697 }
698
699 //----------------------------------------------------------------------------
700 // Get the cell array defining lines. If there are no lines, an
701 // empty array will be returned (convenience to simplify traversal).
GetLines()702 vtkCellArray* vtkPolyData::GetLines()
703 {
704 if ( !this->Lines )
705 {
706 return this->DummyContainer.Dummy.GetPointer();
707 }
708 else
709 {
710 return this->Lines;
711 }
712 }
713
714 //----------------------------------------------------------------------------
715 // Set the cell array defining polygons.
SetPolys(vtkCellArray * p)716 void vtkPolyData::SetPolys (vtkCellArray* p)
717 {
718 if(p == this->DummyContainer.Dummy.GetPointer())
719 {
720 p = NULL;
721 }
722 if ( p != this->Polys)
723 {
724 if (this->Polys)
725 {
726 this->Polys->UnRegister(this);
727 }
728 this->Polys = p;
729 if (this->Polys)
730 {
731 this->Polys->Register(this);
732 }
733 this->Modified();
734 }
735 }
736
737 //----------------------------------------------------------------------------
738 // Get the cell array defining polygons. If there are no polygons, an
739 // empty array will be returned (convenience to simplify traversal).
GetPolys()740 vtkCellArray* vtkPolyData::GetPolys()
741 {
742 if ( !this->Polys )
743 {
744 return this->DummyContainer.Dummy.GetPointer();
745 }
746 else
747 {
748 return this->Polys;
749 }
750 }
751
752 //----------------------------------------------------------------------------
753 // Set the cell array defining triangle strips.
SetStrips(vtkCellArray * s)754 void vtkPolyData::SetStrips (vtkCellArray* s)
755 {
756 if ( s == this->DummyContainer.Dummy.GetPointer())
757 {
758 s = NULL;
759 }
760 if ( s != this->Strips)
761 {
762 if (this->Strips)
763 {
764 this->Strips->UnRegister(this);
765 }
766 this->Strips = s;
767 if (this->Strips)
768 {
769 this->Strips->Register(this);
770 }
771 this->Modified();
772 }
773 }
774
775 //----------------------------------------------------------------------------
776 // Get the cell array defining triangle strips. If there are no
777 // triangle strips, an empty array will be returned (convenience to
778 // simplify traversal).
GetStrips()779 vtkCellArray* vtkPolyData::GetStrips()
780 {
781 if ( !this->Strips )
782 {
783 return this->DummyContainer.Dummy.GetPointer();
784 }
785 else
786 {
787 return this->Strips;
788 }
789 }
790
791 //----------------------------------------------------------------------------
Cleanup()792 void vtkPolyData::Cleanup()
793 {
794 if ( this->Verts )
795 {
796 this->Verts->UnRegister(this);
797 this->Verts = NULL;
798 }
799
800 if ( this->Lines )
801 {
802 this->Lines->UnRegister(this);
803 this->Lines = NULL;
804 }
805
806 if ( this->Polys )
807 {
808 this->Polys->UnRegister(this);
809 this->Polys = NULL;
810 }
811
812 if ( this->Strips )
813 {
814 this->Strips->UnRegister(this);
815 this->Strips = NULL;
816 }
817
818 if ( this->Cells )
819 {
820 this->Cells->UnRegister(this);
821 this->Cells = NULL;
822 }
823
824 if ( this->Links )
825 {
826 this->Links->UnRegister(this);
827 this->Links = NULL;
828 }
829 }
830
831 //----------------------------------------------------------------------------
832 // Restore object to initial state. Release memory back to system.
Initialize()833 void vtkPolyData::Initialize()
834 {
835 vtkPointSet::Initialize();
836
837 this->Cleanup();
838
839 if(this->Information)
840 {
841 this->Information->Set(vtkDataObject::DATA_PIECE_NUMBER(), -1);
842 this->Information->Set(vtkDataObject::DATA_NUMBER_OF_PIECES(), 0);
843 this->Information->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 0);
844 }
845 }
846
847 //----------------------------------------------------------------------------
GetMaxCellSize()848 int vtkPolyData::GetMaxCellSize()
849 {
850 int maxCellSize=0, cellSize;
851
852 if ( this->Verts )
853 {
854 cellSize = this->Verts->GetMaxCellSize();
855 if ( cellSize > maxCellSize )
856 {
857 maxCellSize = cellSize;
858 }
859 }
860
861 if ( this->Lines )
862 {
863 cellSize = this->Lines->GetMaxCellSize();
864 if ( cellSize > maxCellSize )
865 {
866 maxCellSize = cellSize;
867 }
868 }
869
870 if ( this->Polys )
871 {
872 cellSize = this->Polys->GetMaxCellSize();
873 if ( cellSize > maxCellSize )
874 {
875 maxCellSize = cellSize;
876 }
877 }
878
879 if ( this->Strips )
880 {
881 cellSize = this->Strips->GetMaxCellSize();
882 if ( cellSize > maxCellSize )
883 {
884 maxCellSize = cellSize;
885 }
886 }
887
888 return maxCellSize;
889 }
890
891 //----------------------------------------------------------------------------
GetNumberOfCells()892 vtkIdType vtkPolyData::GetNumberOfCells()
893 {
894 return this->GetNumberOfVerts() + this->GetNumberOfLines() +
895 this->GetNumberOfPolys() + this->GetNumberOfStrips();
896 }
897
898 //----------------------------------------------------------------------------
GetNumberOfVerts()899 vtkIdType vtkPolyData::GetNumberOfVerts()
900 {
901 return (this->Verts ? this->Verts->GetNumberOfCells() : 0);
902 }
903
GetNumberOfLines()904 vtkIdType vtkPolyData::GetNumberOfLines()
905 {
906 return (this->Lines ? this->Lines->GetNumberOfCells() : 0);
907 }
908
GetNumberOfPolys()909 vtkIdType vtkPolyData::GetNumberOfPolys()
910 {
911 return (this->Polys ? this->Polys->GetNumberOfCells() : 0);
912 }
913
GetNumberOfStrips()914 vtkIdType vtkPolyData::GetNumberOfStrips()
915 {
916 return (this->Strips ? this->Strips->GetNumberOfCells() : 0);
917 }
918
919
920 //----------------------------------------------------------------------------
DeleteCells()921 void vtkPolyData::DeleteCells()
922 {
923 // if we have Links, we need to delete them (they are no longer valid)
924 if (this->Links)
925 {
926 this->Links->UnRegister( this );
927 this->Links = NULL;
928 }
929
930 if (this->Cells)
931 {
932 this->Cells->UnRegister( this );
933 this->Cells = NULL;
934 }
935 }
936
937 //----------------------------------------------------------------------------
938 // Create data structure that allows random access of cells.
BuildCells()939 void vtkPolyData::BuildCells()
940 {
941 vtkIdType numCells;
942 vtkCellArray *inVerts=this->GetVerts();
943 vtkCellArray *inLines=this->GetLines();
944 vtkCellArray *inPolys=this->GetPolys();
945 vtkCellArray *inStrips=this->GetStrips();
946 vtkIdType npts=0;
947 vtkIdType *pts=0;
948 vtkCellTypes *cells;
949
950 vtkDebugMacro (<< "Building PolyData cells.");
951
952 if ( (numCells = this->GetNumberOfCells()) < 1 )
953 {
954 numCells = 1000; //may be allocating empty list to begin with
955 }
956
957 if (this->Cells)
958 {
959 this->DeleteCells();
960 }
961
962 this->Cells = cells = vtkCellTypes::New();
963 this->Cells->Allocate(numCells,3*numCells);
964 this->Cells->Register(this);
965 cells->Delete();
966 //
967 // Traverse various lists to create cell array
968 //
969 for (inVerts->InitTraversal(); inVerts->GetNextCell(npts,pts); )
970 {
971 if ( npts > 1 )
972 {
973 cells->InsertNextCell(VTK_POLY_VERTEX,
974 inVerts->GetTraversalLocation(npts));
975 }
976 else
977 {
978 cells->InsertNextCell(VTK_VERTEX,inVerts->GetTraversalLocation(npts));
979 }
980 }
981
982 for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); )
983 {
984 if ( npts > 2 )
985 {
986 cells->InsertNextCell(VTK_POLY_LINE,inLines->GetTraversalLocation(npts));
987 }
988 else
989 {
990 cells->InsertNextCell(VTK_LINE,inLines->GetTraversalLocation(npts));
991 }
992 }
993
994 for (inPolys->InitTraversal(); inPolys->GetNextCell(npts,pts); )
995 {
996 if ( npts == 3 )
997 {
998 cells->InsertNextCell(VTK_TRIANGLE,inPolys->GetTraversalLocation(npts));
999 }
1000 else if ( npts == 4 )
1001 {
1002 cells->InsertNextCell(VTK_QUAD,inPolys->GetTraversalLocation(npts));
1003 }
1004 else
1005 {
1006 cells->InsertNextCell(VTK_POLYGON,inPolys->GetTraversalLocation(npts));
1007 }
1008 }
1009
1010 for (inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts); )
1011 {
1012 cells->InsertNextCell(VTK_TRIANGLE_STRIP,
1013 inStrips->GetTraversalLocation(npts));
1014 }
1015 }
1016
1017 //----------------------------------------------------------------------------
DeleteLinks()1018 void vtkPolyData::DeleteLinks()
1019 {
1020 if (this->Links)
1021 {
1022 this->Links->UnRegister( this );
1023 this->Links = NULL;
1024 }
1025 }
1026
1027 //----------------------------------------------------------------------------
1028 // Create upward links from points to cells that use each point. Enables
1029 // topologically complex queries.
BuildLinks(int initialSize)1030 void vtkPolyData::BuildLinks(int initialSize)
1031 {
1032 if ( this->Links )
1033 {
1034 this->DeleteLinks();
1035 }
1036
1037 if ( this->Cells == NULL )
1038 {
1039 this->BuildCells();
1040 }
1041
1042 this->Links = vtkCellLinks::New();
1043 if ( initialSize > 0 )
1044 {
1045 this->Links->Allocate(initialSize);
1046 }
1047 else
1048 {
1049 this->Links->Allocate(this->GetNumberOfPoints());
1050 }
1051 this->Links->Register(this);
1052 this->Links->Delete();
1053
1054 this->Links->BuildLinks(this);
1055 }
1056
1057 //----------------------------------------------------------------------------
1058 // Copy a cells point ids into list provided. (Less efficient.)
GetCellPoints(vtkIdType cellId,vtkIdList * ptIds)1059 void vtkPolyData::GetCellPoints(vtkIdType cellId, vtkIdList *ptIds)
1060 {
1061 vtkIdType i;
1062 vtkIdType *pts, npts;
1063
1064 ptIds->Reset();
1065 if ( this->Cells == NULL )
1066 {
1067 this->BuildCells();
1068 }
1069
1070 this->vtkPolyData::GetCellPoints(cellId, npts, pts);
1071 ptIds->InsertId (npts-1,pts[npts-1]);
1072 for (i=0; i<npts-1; i++)
1073 {
1074 ptIds->SetId(i,pts[i]);
1075 }
1076 }
1077
1078 //----------------------------------------------------------------------------
1079 // Return a pointer to a list of point ids defining cell. (More efficient.)
1080 // Assumes that cells have been built (with BuildCells()).
GetCellPoints(vtkIdType cellId,vtkIdType & npts,vtkIdType * & pts)1081 void vtkPolyData::GetCellPoints(vtkIdType cellId, vtkIdType& npts,
1082 vtkIdType* &pts)
1083 {
1084 int loc;
1085 unsigned char type;
1086
1087 type = this->Cells->GetCellType(cellId);
1088 loc = this->Cells->GetCellLocation(cellId);
1089
1090 switch (type)
1091 {
1092 case VTK_VERTEX: case VTK_POLY_VERTEX:
1093 this->Verts->GetCell(loc,npts,pts);
1094 break;
1095
1096 case VTK_LINE: case VTK_POLY_LINE:
1097 this->Lines->GetCell(loc,npts,pts);
1098 break;
1099
1100 case VTK_TRIANGLE: case VTK_QUAD: case VTK_POLYGON:
1101 this->Polys->GetCell(loc,npts,pts);
1102 break;
1103
1104 case VTK_TRIANGLE_STRIP:
1105 this->Strips->GetCell(loc,npts,pts);
1106 break;
1107
1108 default:
1109 npts = 0;
1110 pts = NULL;
1111 }
1112 }
1113
1114 //----------------------------------------------------------------------------
GetPointCells(vtkIdType ptId,vtkIdList * cellIds)1115 void vtkPolyData::GetPointCells(vtkIdType ptId, vtkIdList *cellIds)
1116 {
1117 vtkIdType *cells;
1118 vtkIdType numCells;
1119 vtkIdType i;
1120
1121 if ( ! this->Links )
1122 {
1123 this->BuildLinks();
1124 }
1125 cellIds->Reset();
1126
1127 numCells = this->Links->GetNcells(ptId);
1128 cells = this->Links->GetCells(ptId);
1129
1130 for (i=0; i < numCells; i++)
1131 {
1132 cellIds->InsertId(i,cells[i]);
1133 }
1134 }
1135
1136 //----------------------------------------------------------------------------
1137 // Method allocates initial storage for vertex, line, polygon, and
1138 // triangle strip arrays. Use this method before the method
1139 // PolyData::InsertNextCell(). (Or, provide vertex, line, polygon, and
1140 // triangle strip cell arrays.)
Allocate(vtkIdType numCells,int extSize)1141 void vtkPolyData::Allocate(vtkIdType numCells, int extSize)
1142 {
1143 vtkCellArray *cells;
1144
1145 if (!this->Cells)
1146 {
1147 this->Cells = vtkCellTypes::New();
1148 this->Cells->Allocate(numCells,3*numCells);
1149 // Consistent Register/UnRegister. (ShallowCopy).
1150 this->Cells->Register(this);
1151 this->Cells->Delete();
1152 }
1153
1154 cells = vtkCellArray::New();
1155 cells->Allocate(numCells,extSize);
1156 this->SetVerts(cells);
1157 cells->Delete();
1158
1159 cells = vtkCellArray::New();
1160 cells->Allocate(numCells,extSize);
1161 this->SetLines(cells);
1162 cells->Delete();
1163
1164 cells = vtkCellArray::New();
1165 cells->Allocate(numCells,extSize);
1166 this->SetPolys(cells);
1167 cells->Delete();
1168
1169 cells = vtkCellArray::New();
1170 cells->Allocate(numCells,extSize);
1171 this->SetStrips(cells);
1172 cells->Delete();
1173 }
1174
Allocate(vtkPolyData * inPolyData,vtkIdType numCells,int extSize)1175 void vtkPolyData::Allocate(vtkPolyData *inPolyData, vtkIdType numCells,
1176 int extSize)
1177 {
1178 vtkCellArray *cells;
1179 int numVerts=inPolyData->GetVerts()->GetNumberOfCells();
1180 int numLines=inPolyData->GetLines()->GetNumberOfCells();
1181 int numPolys=inPolyData->GetPolys()->GetNumberOfCells();
1182 int numStrips=inPolyData->GetStrips()->GetNumberOfCells();
1183 int total=numVerts+numLines+numPolys+numStrips;
1184
1185 if ( total <= 0 )
1186 {
1187 return;
1188 }
1189
1190 if (!this->Cells)
1191 {
1192 this->Cells = vtkCellTypes::New();
1193 this->Cells->Allocate(numCells,3*numCells);
1194 // Consistent Register/UnRegister. (ShallowCopy).
1195 this->Cells->Register(this);
1196 this->Cells->Delete();
1197 }
1198
1199 if ( numVerts > 0 )
1200 {
1201 cells = vtkCellArray::New();
1202 cells->Allocate(
1203 static_cast<int>(static_cast<double>(numVerts)/total*numCells),extSize);
1204 this->SetVerts(cells);
1205 cells->Delete();
1206 }
1207 if ( numLines > 0 )
1208 {
1209 cells = vtkCellArray::New();
1210 cells->Allocate(
1211 static_cast<int>(static_cast<double>(numLines)/total*numCells),extSize);
1212 this->SetLines(cells);
1213 cells->Delete();
1214 }
1215 if ( numPolys > 0 )
1216 {
1217 cells = vtkCellArray::New();
1218 cells->Allocate(
1219 static_cast<int>(static_cast<double>(numPolys)/total*numCells),extSize);
1220 this->SetPolys(cells);
1221 cells->Delete();
1222 }
1223 if ( numStrips > 0 )
1224 {
1225 cells = vtkCellArray::New();
1226 cells->Allocate(
1227 static_cast<int>(static_cast<double>(numStrips)/total*numCells),extSize);
1228 this->SetStrips(cells);
1229 cells->Delete();
1230 }
1231 }
1232
1233 //----------------------------------------------------------------------------
1234 // Insert a cell of type VTK_VERTEX, VTK_POLY_VERTEX, VTK_LINE, VTK_POLY_LINE,
1235 // VTK_TRIANGLE, VTK_QUAD, VTK_POLYGON, or VTK_TRIANGLE_STRIP. Make sure that
1236 // the PolyData::Allocate() function has been called first or that vertex,
1237 // line, polygon, and triangle strip arrays have been supplied.
1238 // Note: will also insert VTK_PIXEL, but converts it to VTK_QUAD.
InsertNextCell(int type,int npts,vtkIdType * pts)1239 vtkIdType vtkPolyData::InsertNextCell(int type, int npts, vtkIdType *pts)
1240 {
1241 int id;
1242
1243 if ( !this->Cells )
1244 {
1245 // if we get to this point, the user has not made any guess at the
1246 // number of cells, so this guess is as good as any
1247 this->Cells = vtkCellTypes::New();
1248 this->Cells->Allocate(5000,10000);
1249 }
1250
1251 switch (type)
1252 {
1253 case VTK_VERTEX: case VTK_POLY_VERTEX:
1254 this->Verts->InsertNextCell(npts,pts);
1255 id = this->Cells->InsertNextCell(type,
1256 this->Verts->GetInsertLocation(npts));
1257 break;
1258
1259 case VTK_LINE: case VTK_POLY_LINE:
1260 this->Lines->InsertNextCell(npts,pts);
1261 id = this->Cells->InsertNextCell(type,
1262 this->Lines->GetInsertLocation(npts));
1263 break;
1264
1265 case VTK_TRIANGLE: case VTK_QUAD: case VTK_POLYGON:
1266 this->Polys->InsertNextCell(npts,pts);
1267 id = this->Cells->InsertNextCell(type,
1268 this->Polys->GetInsertLocation(npts));
1269 break;
1270
1271 case VTK_PIXEL: //need to rearrange vertices
1272 {
1273 vtkIdType pixPts[4];
1274 pixPts[0] = pts[0];
1275 pixPts[1] = pts[1];
1276 pixPts[2] = pts[3];
1277 pixPts[3] = pts[2];
1278 this->Polys->InsertNextCell(npts,pixPts);
1279 id = this->Cells->InsertNextCell(VTK_QUAD,
1280 this->Polys->GetInsertLocation(npts));
1281 break;
1282 }
1283
1284 case VTK_TRIANGLE_STRIP:
1285 this->Strips->InsertNextCell(npts,pts);
1286 id = this->Cells->InsertNextCell(type,
1287 this->Strips->GetInsertLocation(npts));
1288 break;
1289
1290 default:
1291 id = -1;
1292 vtkErrorMacro(<<"Bad cell type! Can't insert!");
1293 }
1294 return id;
1295 }
1296
1297 //----------------------------------------------------------------------------
1298 // Insert a cell of type VTK_VERTEX, VTK_POLY_VERTEX, VTK_LINE, VTK_POLY_LINE,
1299 // VTK_TRIANGLE, VTK_QUAD, VTK_POLYGON, or VTK_TRIANGLE_STRIP. Make sure that
1300 // the PolyData::Allocate() function has been called first or that vertex,
1301 // line, polygon, and triangle strip arrays have been supplied.
1302 // Note: will also insert VTK_PIXEL, but converts it to VTK_QUAD.
InsertNextCell(int type,vtkIdList * pts)1303 vtkIdType vtkPolyData::InsertNextCell(int type, vtkIdList *pts)
1304 {
1305 vtkIdType id;
1306 vtkIdType npts = pts->GetNumberOfIds();
1307
1308 if ( !this->Cells )
1309 {
1310 this->Cells = vtkCellTypes::New();
1311 this->Cells->Allocate(5000,10000);
1312 }
1313
1314 switch (type)
1315 {
1316 case VTK_VERTEX: case VTK_POLY_VERTEX:
1317 this->Verts->InsertNextCell(pts);
1318 id = this->Cells->InsertNextCell(type, this->Verts->GetInsertLocation(npts));
1319 break;
1320
1321 case VTK_LINE: case VTK_POLY_LINE:
1322 this->Lines->InsertNextCell(pts);
1323 id = this->Cells->InsertNextCell(type, this->Lines->GetInsertLocation(npts));
1324 break;
1325
1326 case VTK_TRIANGLE: case VTK_QUAD: case VTK_POLYGON:
1327 this->Polys->InsertNextCell(pts);
1328 id = this->Cells->InsertNextCell(type, this->Polys->GetInsertLocation(npts));
1329 break;
1330
1331 case VTK_PIXEL: //need to rearrange vertices
1332 {
1333 vtkIdType pixPts[4];
1334 pixPts[0] = pts->GetId(0);
1335 pixPts[1] = pts->GetId(1);
1336 pixPts[2] = pts->GetId(3);
1337 pixPts[3] = pts->GetId(2);
1338 this->Polys->InsertNextCell(4,pixPts);
1339 id = this->Cells->InsertNextCell(VTK_QUAD, this->Polys->GetInsertLocation(npts));
1340 break;
1341 }
1342
1343 case VTK_TRIANGLE_STRIP:
1344 this->Strips->InsertNextCell(pts);
1345 id = this->Cells->InsertNextCell(type, this->Strips->GetInsertLocation(npts));
1346 break;
1347
1348 case VTK_EMPTY_CELL:
1349 id = -1;
1350 // do nothing
1351 break;
1352
1353 default:
1354 id = -1;
1355 vtkErrorMacro(<<"Bad cell type! Can't insert!");
1356 }
1357
1358 return id;
1359 }
1360
1361 //----------------------------------------------------------------------------
1362 // Recover extra allocated memory when creating data whose initial size
1363 // is unknown. Examples include using the InsertNextCell() method, or
1364 // when using the CellArray::EstimateSize() method to create vertices,
1365 // lines, polygons, or triangle strips.
Squeeze()1366 void vtkPolyData::Squeeze()
1367 {
1368 if ( this->Verts != NULL )
1369 {
1370 this->Verts->Squeeze();
1371 }
1372 if ( this->Lines != NULL )
1373 {
1374 this->Lines->Squeeze();
1375 }
1376 if ( this->Polys != NULL )
1377 {
1378 this->Polys->Squeeze();
1379 }
1380 if ( this->Strips != NULL )
1381 {
1382 this->Strips->Squeeze();
1383 }
1384
1385 vtkPointSet::Squeeze();
1386 }
1387
1388 //----------------------------------------------------------------------------
1389 // Begin inserting data all over again. Memory is not freed but otherwise
1390 // objects are returned to their initial state.
Reset()1391 void vtkPolyData::Reset()
1392 {
1393 if ( this->Verts != NULL )
1394 {
1395 this->Verts->Reset();
1396 }
1397 if ( this->Lines != NULL )
1398 {
1399 this->Lines->Reset();
1400 }
1401 if ( this->Polys != NULL )
1402 {
1403 this->Polys->Reset();
1404 }
1405 if ( this->Strips != NULL )
1406 {
1407 this->Strips->Reset();
1408 }
1409 }
1410
1411 //----------------------------------------------------------------------------
1412 // Reverse the order of point ids defining the cell.
ReverseCell(vtkIdType cellId)1413 void vtkPolyData::ReverseCell(vtkIdType cellId)
1414 {
1415 int loc, type;
1416
1417 if ( this->Cells == NULL )
1418 {
1419 this->BuildCells();
1420 }
1421 loc = this->Cells->GetCellLocation(cellId);
1422 type = this->Cells->GetCellType(cellId);
1423
1424 switch (type)
1425 {
1426 case VTK_VERTEX: case VTK_POLY_VERTEX:
1427 this->Verts->ReverseCell(loc);
1428 break;
1429
1430 case VTK_LINE: case VTK_POLY_LINE:
1431 this->Lines->ReverseCell(loc);
1432 break;
1433
1434 case VTK_TRIANGLE: case VTK_QUAD: case VTK_POLYGON:
1435 this->Polys->ReverseCell(loc);
1436 break;
1437
1438 case VTK_TRIANGLE_STRIP:
1439 this->Strips->ReverseCell(loc);
1440 break;
1441
1442 default:
1443 break;
1444 }
1445 }
1446
1447 //----------------------------------------------------------------------------
1448 // Add a point to the cell data structure (after cell pointers have been
1449 // built). This method allocates memory for the links to the cells. (To
1450 // use this method, make sure points are available and BuildLinks() has been invoked.)
InsertNextLinkedPoint(int numLinks)1451 vtkIdType vtkPolyData::InsertNextLinkedPoint(int numLinks)
1452 {
1453 return this->Links->InsertNextPoint(numLinks);
1454 }
1455
1456 //----------------------------------------------------------------------------
1457 // Add a point to the cell data structure (after cell pointers have been
1458 // built). This method adds the point and then allocates memory for the
1459 // links to the cells. (To use this method, make sure points are available
1460 // and BuildLinks() has been invoked.)
InsertNextLinkedPoint(double x[3],int numLinks)1461 vtkIdType vtkPolyData::InsertNextLinkedPoint(double x[3], int numLinks)
1462 {
1463 this->Links->InsertNextPoint(numLinks);
1464 return this->Points->InsertNextPoint(x);
1465 }
1466
1467 //----------------------------------------------------------------------------
1468 // Add a new cell to the cell data structure (after cell pointers have been
1469 // built). This method adds the cell and then updates the links from the points
1470 // to the cells. (Memory is allocated as necessary.)
InsertNextLinkedCell(int type,int npts,vtkIdType * pts)1471 vtkIdType vtkPolyData::InsertNextLinkedCell(int type, int npts, vtkIdType *pts)
1472 {
1473 vtkIdType i, id;
1474
1475 id = this->InsertNextCell(type,npts,pts);
1476
1477 for (i=0; i<npts; i++)
1478 {
1479 this->Links->ResizeCellList(pts[i],1);
1480 this->Links->AddCellReference(id,pts[i]);
1481 }
1482
1483 return id;
1484 }
1485
1486 //----------------------------------------------------------------------------
1487 // Remove a reference to a cell in a particular point's link list. You may also
1488 // consider using RemoveCellReference() to remove the references from all the
1489 // cell's points to the cell. This operator does not reallocate memory; use the
1490 // operator ResizeCellList() to do this if necessary.
RemoveReferenceToCell(vtkIdType ptId,vtkIdType cellId)1491 void vtkPolyData::RemoveReferenceToCell(vtkIdType ptId, vtkIdType cellId)
1492 {
1493 this->Links->RemoveCellReference(cellId, ptId);
1494 }
1495
1496 //----------------------------------------------------------------------------
1497 // Add a reference to a cell in a particular point's link list. (You may also
1498 // consider using AddCellReference() to add the references from all the
1499 // cell's points to the cell.) This operator does not realloc memory; use the
1500 // operator ResizeCellList() to do this if necessary.
AddReferenceToCell(vtkIdType ptId,vtkIdType cellId)1501 void vtkPolyData::AddReferenceToCell(vtkIdType ptId, vtkIdType cellId)
1502 {
1503 this->Links->AddCellReference(cellId, ptId);
1504 }
1505
1506 //----------------------------------------------------------------------------
1507 // Replace the points defining cell "cellId" with a new set of points. This
1508 // operator is (typically) used when links from points to cells have not been
1509 // built (i.e., BuildLinks() has not been executed). Use the operator
1510 // ReplaceLinkedCell() to replace a cell when cell structure has been built.
ReplaceCell(vtkIdType cellId,int npts,vtkIdType * pts)1511 void vtkPolyData::ReplaceCell(vtkIdType cellId, int npts, vtkIdType *pts)
1512 {
1513 int loc, type;
1514
1515 if ( this->Cells == NULL )
1516 {
1517 this->BuildCells();
1518 }
1519 loc = this->Cells->GetCellLocation(cellId);
1520 type = this->Cells->GetCellType(cellId);
1521
1522 switch (type)
1523 {
1524 case VTK_VERTEX: case VTK_POLY_VERTEX:
1525 this->Verts->ReplaceCell(loc,npts,pts);
1526 break;
1527
1528 case VTK_LINE: case VTK_POLY_LINE:
1529 this->Lines->ReplaceCell(loc,npts,pts);
1530 break;
1531
1532 case VTK_TRIANGLE: case VTK_QUAD: case VTK_POLYGON:
1533 this->Polys->ReplaceCell(loc,npts,pts);
1534 break;
1535
1536 case VTK_TRIANGLE_STRIP:
1537 this->Strips->ReplaceCell(loc,npts,pts);
1538 break;
1539
1540 default:
1541 break;
1542 }
1543 }
1544
1545 //----------------------------------------------------------------------------
1546 // Replace one cell with another in cell structure. This operator updates the
1547 // connectivity list and the point's link list. It does not delete references
1548 // to the old cell in the point's link list. Use the operator
1549 // RemoveCellReference() to delete all references from points to (old) cell.
1550 // You may also want to consider using the operator ResizeCellList() if the
1551 // link list is changing size.
ReplaceLinkedCell(vtkIdType cellId,int npts,vtkIdType * pts)1552 void vtkPolyData::ReplaceLinkedCell(vtkIdType cellId, int npts, vtkIdType *pts)
1553 {
1554 int loc = this->Cells->GetCellLocation(cellId);
1555 int type = this->Cells->GetCellType(cellId);
1556
1557 switch (type)
1558 {
1559 case VTK_VERTEX: case VTK_POLY_VERTEX:
1560 this->Verts->ReplaceCell(loc,npts,pts);
1561 break;
1562
1563 case VTK_LINE: case VTK_POLY_LINE:
1564 this->Lines->ReplaceCell(loc,npts,pts);
1565 break;
1566
1567 case VTK_TRIANGLE: case VTK_QUAD: case VTK_POLYGON:
1568 this->Polys->ReplaceCell(loc,npts,pts);
1569 break;
1570
1571 case VTK_TRIANGLE_STRIP:
1572 this->Strips->ReplaceCell(loc,npts,pts);
1573 break;
1574
1575 default:
1576 npts = 0;
1577 }
1578
1579 for (int i=0; i < npts; i++)
1580 {
1581 this->Links->InsertNextCellReference(pts[i],cellId);
1582 }
1583 }
1584
1585 //----------------------------------------------------------------------------
1586 // Get the neighbors at an edge. More efficient than the general
1587 // GetCellNeighbors(). Assumes links have been built (with BuildLinks()),
1588 // and looks specifically for edge neighbors.
GetCellEdgeNeighbors(vtkIdType cellId,vtkIdType p1,vtkIdType p2,vtkIdList * cellIds)1589 void vtkPolyData::GetCellEdgeNeighbors(vtkIdType cellId, vtkIdType p1,
1590 vtkIdType p2, vtkIdList *cellIds)
1591 {
1592 cellIds->Reset();
1593
1594 const vtkCellLinks::Link &link1(this->Links->GetLink(p1));
1595 const vtkCellLinks::Link &link2(this->Links->GetLink(p2));
1596
1597 const vtkIdType *cells1 = link1.cells;
1598 const vtkIdType *cells1End = cells1 + link1.ncells;
1599
1600 const vtkIdType *cells2 = link2.cells;
1601 const vtkIdType *cells2End = cells2 + link2.ncells;
1602
1603 while (cells1 != cells1End)
1604 {
1605 if (*cells1 != cellId)
1606 {
1607 const vtkIdType *cells2Cur(cells2);
1608 while (cells2Cur != cells2End)
1609 {
1610 if (*cells1 == *cells2Cur)
1611 {
1612 cellIds->InsertNextId(*cells1);
1613 break;
1614 }
1615 ++cells2Cur;
1616 }
1617 }
1618 ++cells1;
1619 }
1620 }
1621
1622 //----------------------------------------------------------------------------
GetCellNeighbors(vtkIdType cellId,vtkIdList * ptIds,vtkIdList * cellIds)1623 void vtkPolyData::GetCellNeighbors(vtkIdType cellId, vtkIdList *ptIds,
1624 vtkIdList *cellIds)
1625 {
1626 vtkIdType i, j, numPts, cellNum;
1627 int allFound, oneFound;
1628
1629 if ( ! this->Links )
1630 {
1631 this->BuildLinks();
1632 }
1633
1634 cellIds->Reset();
1635
1636 // load list with candidate cells, remove current cell
1637 vtkIdType ptId = ptIds->GetId(0);
1638 int numPrime = this->Links->GetNcells(ptId);
1639 vtkIdType *primeCells = this->Links->GetCells(ptId);
1640 numPts = ptIds->GetNumberOfIds();
1641
1642 // for each potential cell
1643 for (cellNum = 0; cellNum < numPrime; cellNum++)
1644 {
1645 // ignore the original cell
1646 if (primeCells[cellNum] != cellId)
1647 {
1648 // are all the remaining points in the cell ?
1649 for (allFound=1, i=1; i < numPts && allFound; i++)
1650 {
1651 ptId = ptIds->GetId(i);
1652 int numCurrent = this->Links->GetNcells(ptId);
1653 vtkIdType *currentCells = this->Links->GetCells(ptId);
1654 oneFound = 0;
1655 for (j = 0; j < numCurrent; j++)
1656 {
1657 if (primeCells[cellNum] == currentCells[j])
1658 {
1659 oneFound = 1;
1660 break;
1661 }
1662 }
1663 if (!oneFound)
1664 {
1665 allFound = 0;
1666 }
1667 }
1668 if (allFound)
1669 {
1670 cellIds->InsertNextId(primeCells[cellNum]);
1671 }
1672 }
1673 }
1674 }
1675
IsEdge(vtkIdType p1,vtkIdType p2)1676 int vtkPolyData::IsEdge(vtkIdType p1, vtkIdType p2)
1677 {
1678 unsigned short int ncells;
1679 vtkIdType cellType;
1680 vtkIdType npts;
1681 vtkIdType i, j;
1682 vtkIdType *cells, *pts;
1683
1684 this->GetPointCells(p1,ncells,cells);
1685 for (i=0; i<ncells; i++)
1686 {
1687 cellType = this->GetCellType(cells[i]);
1688 switch (cellType)
1689 {
1690 case VTK_EMPTY_CELL: case VTK_VERTEX: case VTK_POLY_VERTEX: case VTK_LINE: case VTK_POLY_LINE:
1691 break;
1692 case VTK_TRIANGLE:
1693 if ( this->IsPointUsedByCell(p2,cells[i]) )
1694 {
1695 return 1;
1696 }
1697 break;
1698 case VTK_QUAD:
1699 this->GetCellPoints(cells[i],npts,pts);
1700 for (j=0; j<npts-1; j++)
1701 {
1702 if (((pts[j]==p1)&&(pts[j+1]==p2))||((pts[j]==p2)&&(pts[j+1]==p1)))
1703 {
1704 return 1;
1705 }
1706 }
1707 if (((pts[0]==p1)&&(pts[npts-1]==p2))||((pts[0]==p2)&&(pts[npts-1]==p1)))
1708 {
1709 return 1;
1710 }
1711 break;
1712 case VTK_TRIANGLE_STRIP:
1713 this->GetCellPoints(cells[i],npts,pts);
1714 for (j=0; j<npts-2; j++)
1715 {
1716 if ((((pts[j]==p1)&&(pts[j+1]==p2))||((pts[j]==p2)&&(pts[j+1]==p1)))||
1717 (((pts[j]==p1)&&(pts[j+2]==p2))||((pts[j]==p2)&&(pts[j+2]==p1))))
1718 {
1719 return 1;
1720 }
1721 }
1722 if (((pts[npts-2]==p1)&&(pts[npts-1]==p2))||((pts[npts-2]==p2)&&(pts[npts-1]==p1)))
1723 {
1724 return 1;
1725 }
1726 break;
1727 default:
1728 this->GetCellPoints(cells[i],npts,pts);
1729 for (j=0; j<npts; j++)
1730 {
1731 if (p1==pts[j])
1732 {
1733 if ((pts[(j-1+npts)%npts]==p2)||(pts[(j+1)%npts]==p2))
1734 {
1735 return 1;
1736 }
1737 }
1738 }
1739 }
1740 }
1741 return 0;
1742 }
1743
1744 //----------------------------------------------------------------------------
1745
GetActualMemorySize()1746 unsigned long vtkPolyData::GetActualMemorySize()
1747 {
1748 unsigned long size=this->vtkPointSet::GetActualMemorySize();
1749 if ( this->Verts )
1750 {
1751 size += this->Verts->GetActualMemorySize();
1752 }
1753 if ( this->Lines )
1754 {
1755 size += this->Lines->GetActualMemorySize();
1756 }
1757 if ( this->Polys )
1758 {
1759 size += this->Polys->GetActualMemorySize();
1760 }
1761 if ( this->Strips )
1762 {
1763 size += this->Strips->GetActualMemorySize();
1764 }
1765 if ( this->Cells )
1766 {
1767 size += this->Cells->GetActualMemorySize();
1768 }
1769 if ( this->Links )
1770 {
1771 size += this->Links->GetActualMemorySize();
1772 }
1773 return size;
1774 }
1775
1776 //----------------------------------------------------------------------------
ShallowCopy(vtkDataObject * dataObject)1777 void vtkPolyData::ShallowCopy(vtkDataObject *dataObject)
1778 {
1779 vtkPolyData *polyData = vtkPolyData::SafeDownCast(dataObject);
1780 if (this == polyData)
1781 return;
1782
1783 if ( polyData != NULL )
1784 {
1785 this->SetVerts(polyData->GetVerts());
1786 this->SetLines(polyData->GetLines());
1787 this->SetPolys(polyData->GetPolys());
1788 this->SetStrips(polyData->GetStrips());
1789
1790 // I do not know if this is correct but.
1791 if (this->Cells)
1792 {
1793 this->Cells->UnRegister(this);
1794 }
1795 this->Cells = polyData->Cells;
1796 if (this->Cells)
1797 {
1798 this->Cells->Register(this);
1799 }
1800
1801 if (this->Links)
1802 {
1803 this->Links->Delete();
1804 }
1805 this->Links = polyData->Links;
1806 if (this->Links)
1807 {
1808 this->Links->Register(this);
1809 }
1810 }
1811
1812 // Do superclass
1813 this->vtkPointSet::ShallowCopy(dataObject);
1814 }
1815
1816 //----------------------------------------------------------------------------
DeepCopy(vtkDataObject * dataObject)1817 void vtkPolyData::DeepCopy(vtkDataObject *dataObject)
1818 {
1819 // Do superclass
1820 // We have to do this BEFORE we call BuildLinks, else there are no points
1821 // to build the links on (the parent DeepCopy copies the points)
1822 this->vtkPointSet::DeepCopy(dataObject);
1823
1824 vtkPolyData *polyData = vtkPolyData::SafeDownCast(dataObject);
1825
1826 if ( polyData != NULL )
1827 {
1828 vtkCellArray *ca;
1829 ca = vtkCellArray::New();
1830 ca->DeepCopy(polyData->GetVerts());
1831 this->SetVerts(ca);
1832 ca->Delete();
1833
1834 ca = vtkCellArray::New();
1835 ca->DeepCopy(polyData->GetLines());
1836 this->SetLines(ca);
1837 ca->Delete();
1838
1839 ca = vtkCellArray::New();
1840 ca->DeepCopy(polyData->GetPolys());
1841 this->SetPolys(ca);
1842 ca->Delete();
1843
1844 ca = vtkCellArray::New();
1845 ca->DeepCopy(polyData->GetStrips());
1846 this->SetStrips(ca);
1847 ca->Delete();
1848
1849 if ( this->Cells )
1850 {
1851 this->Cells->UnRegister(this);
1852 this->Cells = NULL;
1853 }
1854 if (polyData->Cells)
1855 {
1856 this->BuildCells();
1857 }
1858
1859 if ( this->Links )
1860 {
1861 this->Links->UnRegister(this);
1862 this->Links = NULL;
1863 }
1864 if (polyData->Links)
1865 {
1866 this->BuildLinks();
1867 }
1868 }
1869 }
1870
RemoveGhostCells(int level)1871 void vtkPolyData::RemoveGhostCells(int level)
1872 {
1873 // Get a pointer to the cell ghost level array.
1874 vtkUnsignedCharArray* temp = vtkUnsignedCharArray::SafeDownCast(
1875 this->CellData->GetArray("vtkGhostLevels"));
1876 if (temp == NULL)
1877 {
1878 vtkDebugMacro("Could not find cell ghost level array.");
1879 return;
1880 }
1881 if (temp->GetNumberOfComponents() != 1 ||
1882 temp->GetNumberOfTuples() < this->GetNumberOfCells())
1883 {
1884 vtkErrorMacro("Poorly formed ghost level array.");
1885 return;
1886 }
1887 unsigned char* cellGhostLevels = temp->GetPointer(0);
1888
1889 vtkIdType numCells = this->GetNumberOfCells();
1890
1891 vtkIntArray *types = vtkIntArray::New();
1892 types->SetNumberOfValues(numCells);
1893
1894 for (vtkIdType i = 0; i < numCells; i++)
1895 {
1896 types->SetValue(i, this->GetCellType(i));
1897 }
1898
1899 this->DeleteCells();
1900
1901 // we have to make new copies of Verts, Lines, Polys
1902 // and Strips since they may be shared with other polydata
1903 vtkSmartPointer<vtkCellArray> verts;
1904 if(this->Verts)
1905 {
1906 verts = this->Verts;
1907 verts->InitTraversal();
1908 this->Verts->UnRegister(this);
1909 this->Verts = vtkCellArray::New();
1910 }
1911
1912 vtkSmartPointer<vtkCellArray> lines;
1913 if(this->Lines)
1914 {
1915 lines = this->Lines;
1916 lines->InitTraversal();
1917 this->Lines->UnRegister(this);
1918 this->Lines = vtkCellArray::New();
1919 }
1920
1921 vtkSmartPointer<vtkCellArray> polys;
1922 if(this->Polys)
1923 {
1924 polys = this->Polys;
1925 polys->InitTraversal();
1926 this->Polys->UnRegister(this);
1927 this->Polys = vtkCellArray::New();
1928 }
1929
1930 vtkSmartPointer<vtkCellArray> strips;
1931 if(this->Strips)
1932 {
1933 strips = this->Strips;
1934 strips->InitTraversal();
1935 this->Strips->UnRegister(this);
1936 this->Strips = vtkCellArray::New();
1937 }
1938
1939 vtkCellData *newCellData = vtkCellData::New();
1940 newCellData->CopyAllocate(this->CellData, numCells);
1941
1942 vtkIdType *pts, n;
1943
1944 int cellId;
1945
1946 for (vtkIdType i = 0; i < numCells; i++)
1947 {
1948 int type = types->GetValue(i);
1949
1950 if (type == VTK_VERTEX || type == VTK_POLY_VERTEX)
1951 {
1952 verts->GetNextCell(n, pts);
1953
1954 if (int(cellGhostLevels[i]) < level)
1955 {
1956 cellId = this->InsertNextCell(type, n, pts);
1957 newCellData->CopyData(this->CellData, i, cellId);
1958 }
1959 }
1960 else if (type == VTK_LINE || type == VTK_POLY_LINE)
1961 {
1962 lines->GetNextCell(n, pts);
1963
1964 if (int(cellGhostLevels[i]) < level)
1965 {
1966 cellId = this->InsertNextCell(type, n, pts);
1967 newCellData->CopyData(this->CellData, i, cellId);
1968 }
1969 }
1970 else if (type == VTK_POLYGON || type == VTK_TRIANGLE || type == VTK_QUAD)
1971 {
1972 polys->GetNextCell(n, pts);
1973
1974 if (int(cellGhostLevels[i]) < level)
1975 {
1976 cellId = this->InsertNextCell(type, n, pts);
1977 newCellData->CopyData(this->CellData, i, cellId);
1978 }
1979 }
1980 else if (type == VTK_TRIANGLE_STRIP)
1981 {
1982 strips->GetNextCell(n, pts);
1983
1984 if (int(cellGhostLevels[i]) < level)
1985 {
1986 cellId = this->InsertNextCell(type, n, pts);
1987 newCellData->CopyData(this->CellData, i, cellId);
1988 }
1989 }
1990 }
1991
1992 newCellData->Squeeze();
1993
1994 this->CellData->ShallowCopy(newCellData);
1995 newCellData->Delete();
1996
1997 types->Delete();
1998
1999 // If there are no more ghost levels, then remove all arrays.
2000 if (level <= 1)
2001 {
2002 this->CellData->RemoveArray("vtkGhostLevels");
2003 this->PointData->RemoveArray("vtkGhostLevels");
2004 }
2005
2006 this->Squeeze();
2007 }
2008 //----------------------------------------------------------------------------
RemoveDeletedCells()2009 void vtkPolyData::RemoveDeletedCells()
2010 {
2011 if (!this->Cells)
2012 {
2013 return;
2014 }
2015
2016 vtkNew<vtkPolyData> oldData;
2017 oldData->ShallowCopy(this);
2018 this->DeleteCells();
2019
2020 if(this->Verts)
2021 {
2022 this->Verts->UnRegister(this);
2023 this->Verts = vtkCellArray::New();
2024 }
2025 if(this->Lines)
2026 {
2027 this->Lines->UnRegister(this);
2028 this->Lines = vtkCellArray::New();
2029 }
2030 if(this->Polys)
2031 {
2032 this->Polys->UnRegister(this);
2033 this->Polys = vtkCellArray::New();
2034 }
2035 if(this->Strips)
2036 {
2037 this->Strips->UnRegister(this);
2038 this->Strips = vtkCellArray::New();
2039 }
2040
2041 this->CellData->CopyAllocate(oldData->GetCellData());
2042
2043 const vtkIdType numCells = oldData->GetNumberOfCells();
2044 vtkCell *cell;
2045 vtkIdType cellId;
2046 vtkIdList *pointIds;
2047 int type;
2048 for (vtkIdType i = 0; i < numCells; i++)
2049 {
2050 type = oldData->GetCellType(i);
2051
2052 if (type != VTK_EMPTY_CELL)
2053 {
2054 cell = oldData->GetCell(i);
2055 pointIds = cell->GetPointIds();
2056 cellId = this->InsertNextCell(type, pointIds);
2057 this->CellData->CopyData(oldData->GetCellData(), i, cellId);
2058 }
2059 }
2060
2061 this->CellData->Squeeze();
2062 }
2063 //----------------------------------------------------------------------------
GetData(vtkInformation * info)2064 vtkPolyData* vtkPolyData::GetData(vtkInformation* info)
2065 {
2066 return info? vtkPolyData::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
2067 }
2068
2069 //----------------------------------------------------------------------------
GetData(vtkInformationVector * v,int i)2070 vtkPolyData* vtkPolyData::GetData(vtkInformationVector* v, int i)
2071 {
2072 return vtkPolyData::GetData(v->GetInformationObject(i));
2073 }
2074
2075 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)2076 void vtkPolyData::PrintSelf(ostream& os, vtkIndent indent)
2077 {
2078 this->Superclass::PrintSelf(os,indent);
2079
2080 os << indent << "Number Of Vertices: " << this->GetNumberOfVerts() << "\n";
2081 os << indent << "Number Of Lines: " << this->GetNumberOfLines() << "\n";
2082 os << indent << "Number Of Polygons: " << this->GetNumberOfPolys() << "\n";
2083 os << indent << "Number Of Triangle Strips: " << this->GetNumberOfStrips() << "\n";
2084
2085 os << indent << "Number Of Pieces: " << this->GetNumberOfPieces() << endl;
2086 os << indent << "Piece: " << this->GetPiece() << endl;
2087 os << indent << "Ghost Level: " << this->GetGhostLevel() << endl;
2088 }
2089
2090
2091 //----------------------------------------------------------------------------
GetScalarFieldCriticalIndex(vtkIdType pointId,vtkDataArray * scalarField)2092 int vtkPolyData::GetScalarFieldCriticalIndex (vtkIdType pointId,
2093 vtkDataArray *scalarField)
2094 {
2095 /*
2096 * implements scalar field critical point classification for manifold
2097 * 2D meshes.
2098 */
2099
2100 /*
2101 * returned value:
2102 * -4: no such field
2103 * -3: attribute check failed
2104 * -2: non 2-manifold star
2105 * -1: regular point
2106 * 0: minimum
2107 * 1: saddle
2108 * 2: maximum
2109 */
2110
2111 bool is_min = true, is_max = true;
2112 vtkIdList *starTriangleList = vtkIdList::New(),
2113 *lowerLinkPointList = vtkIdList::New(),
2114 *upperLinkPointList = vtkIdList::New(),
2115 *pointList = NULL;
2116 double pointFieldValue = scalarField->GetComponent(pointId, 0),
2117 neighborFieldValue = 0;
2118
2119 if(this->GetNumberOfPoints() != scalarField->GetSize())
2120 return vtkPolyData::ERR_INCORRECT_FIELD;
2121
2122 /* make sure the connectivity is built */
2123 if(!this->Links) this->BuildLinks();
2124
2125 /* build the lower and upper links */
2126 this->GetPointCells(pointId, starTriangleList);
2127 int starNb = starTriangleList->GetNumberOfIds();
2128 for(int i = 0; i < starNb; i++)
2129 {
2130 vtkCell *c = this->GetCell(starTriangleList->GetId(i));
2131 pointList = c->GetPointIds();
2132 int pointNb = pointList->GetNumberOfIds();
2133 if(pointNb != 3)
2134 {
2135 starTriangleList->Delete();
2136 lowerLinkPointList->Delete();
2137 upperLinkPointList->Delete();
2138 return vtkPolyData::ERR_NON_MANIFOLD_STAR;
2139 }
2140
2141 for(int j = 0; j < pointNb; j++)
2142 {
2143 vtkIdType currentPointId = pointList->GetId(j);
2144
2145 /* quick check for extrema */
2146 neighborFieldValue = scalarField->GetComponent(currentPointId, 0);
2147 if((currentPointId != pointId)&&(neighborFieldValue == pointFieldValue))
2148 {
2149 /* simulation of simplicity (Edelsbrunner et al. ACM ToG 1990) */
2150 if(currentPointId > pointId)
2151 {
2152 is_max = false;
2153 upperLinkPointList->InsertUniqueId(currentPointId);
2154 }
2155 if(currentPointId < pointId)
2156 {
2157 is_min = false;
2158 lowerLinkPointList->InsertUniqueId(currentPointId);
2159 }
2160 }
2161 else
2162 {
2163 if(neighborFieldValue > pointFieldValue)
2164 {
2165 is_max = false;
2166 upperLinkPointList->InsertUniqueId(currentPointId);
2167 }
2168 if(neighborFieldValue < pointFieldValue)
2169 {
2170 is_min = false;
2171 lowerLinkPointList->InsertUniqueId(currentPointId);
2172 }
2173 }
2174 }
2175 }
2176
2177 if((is_max)||(is_min))
2178 {
2179 starTriangleList->Delete();
2180 lowerLinkPointList->Delete();
2181 upperLinkPointList->Delete();
2182 if(is_max) return vtkPolyData::MAXIMUM;
2183 if(is_min) return vtkPolyData::MINIMUM;
2184 }
2185
2186 /*
2187 * is the vertex really regular?
2188 * (lower and upper links are BOTH simply connected)
2189 */
2190 int visitedPointNb = 0, stackBottom = 0,
2191 lowerLinkPointNb = lowerLinkPointList->GetNumberOfIds(),
2192 upperLinkPointNb = upperLinkPointList->GetNumberOfIds();
2193
2194 /* first, check lower link's simply connectedness */
2195 vtkIdList *stack = vtkIdList::New();
2196 stack->InsertUniqueId(lowerLinkPointList->GetId(0));
2197 vtkIdType currentPointId = stack->GetId(stackBottom), nextPointId = -1;
2198 do
2199 {
2200 stackBottom++;
2201 vtkIdList *triangleList = vtkIdList::New();
2202 this->GetPointCells(currentPointId, triangleList);
2203 int triangleNb = triangleList->GetNumberOfIds();
2204
2205 for(int i = 0; i < triangleNb; i++)
2206 {
2207 vtkCell *c = this->GetCell(triangleList->GetId(i));
2208 pointList = c->GetPointIds();;
2209 int pointNb = pointList->GetNumberOfIds();
2210
2211 if(pointList->IsId(pointId) >= 0)
2212 {
2213 // those two triangles are in the star of pointId
2214 int j = 0;
2215 do
2216 {
2217 nextPointId = pointList->GetId(j);
2218 j++;
2219 }while(((nextPointId == pointId)
2220 ||(nextPointId == currentPointId))&&(j < pointNb ));
2221 }
2222
2223 if(lowerLinkPointList->IsId(nextPointId) >= 0)
2224 {
2225 stack->InsertUniqueId(nextPointId);
2226 }
2227
2228 }
2229
2230 triangleList->Delete();
2231 visitedPointNb++;
2232
2233 currentPointId = stack->GetId(stackBottom), nextPointId = -1;
2234
2235 }while(stackBottom < stack->GetNumberOfIds());
2236
2237 if(visitedPointNb != lowerLinkPointNb)
2238 {
2239 // the lower link is not simply connected, then it's a saddle
2240 stack->Delete();
2241 starTriangleList->Delete();
2242 lowerLinkPointList->Delete();
2243 upperLinkPointList->Delete();
2244 return vtkPolyData::SADDLE;
2245 }
2246
2247 /*
2248 * then, check upper link's simply connectedness.
2249 * BOTH need to be checked if the 2-manifold has boundary components.
2250 */
2251 stackBottom = 0;
2252 visitedPointNb = 0;
2253 stack->Delete();
2254 stack = vtkIdList::New();
2255 stack->InsertUniqueId(upperLinkPointList->GetId(0));
2256 currentPointId = stack->GetId(stackBottom), nextPointId = -1;
2257 do
2258 {
2259 stackBottom++;
2260 vtkIdList *triangleList = vtkIdList::New();
2261 this->GetPointCells(currentPointId, triangleList);
2262 int triangleNb = triangleList->GetNumberOfIds();
2263
2264 for(int i = 0; i < triangleNb; i++)
2265 {
2266 vtkCell *c = this->GetCell(triangleList->GetId(i));
2267 pointList = c->GetPointIds();
2268 int pointNb = pointList->GetNumberOfIds();
2269
2270 if(pointList->IsId(pointId) >= 0)
2271 {
2272 // those two triangles are in the star of pointId
2273 int j = 0;
2274 do
2275 {
2276 nextPointId = pointList->GetId(j);
2277 j++;
2278 }while(((nextPointId == pointId)
2279 ||(nextPointId == currentPointId))&&(j < pointNb));
2280 }
2281
2282 if(upperLinkPointList->IsId(nextPointId) >= 0)
2283 {
2284 stack->InsertUniqueId(nextPointId);
2285 }
2286 }
2287
2288 triangleList->Delete();
2289 visitedPointNb++;
2290
2291 currentPointId = stack->GetId(stackBottom), nextPointId = -1;
2292 }while(stackBottom < stack->GetNumberOfIds());
2293
2294 if(visitedPointNb != upperLinkPointNb)
2295 {
2296 // the upper link is not simply connected, then it's a saddle
2297 stack->Delete();
2298 starTriangleList->Delete();
2299 lowerLinkPointList->Delete();
2300 upperLinkPointList->Delete();
2301 return vtkPolyData::SADDLE;
2302 }
2303
2304 /* else it's necessarily a regular point (only 4 cases in 2D)*/
2305 stack->Delete();
2306 starTriangleList->Delete();
2307 lowerLinkPointList->Delete();
2308 upperLinkPointList->Delete();
2309 return vtkPolyData::REGULAR_POINT;
2310 }
2311
2312 //----------------------------------------------------------------------------
GetScalarFieldCriticalIndex(vtkIdType pointId,const char * fieldName)2313 int vtkPolyData::GetScalarFieldCriticalIndex (vtkIdType pointId,
2314 const char* fieldName)
2315 {
2316 /*
2317 * returned value:
2318 * -4: no such field
2319 * -3: attribute check failed
2320 * -2: non 2-manifold star
2321 * -1: regular point
2322 * 0: minimum
2323 * 1: saddle
2324 * 2: maximum
2325 */
2326
2327 int fieldId = 0;
2328
2329 vtkPointData *pointData = this->GetPointData();
2330 vtkDataArray *scalarField = pointData->GetArray(fieldName, fieldId);
2331
2332 if(!scalarField) return vtkPolyData::ERR_NO_SUCH_FIELD;
2333
2334 return this->GetScalarFieldCriticalIndex(pointId, scalarField);
2335
2336 }
2337
2338 //----------------------------------------------------------------------------
GetScalarFieldCriticalIndex(vtkIdType pointId,int fieldId)2339 int vtkPolyData::GetScalarFieldCriticalIndex (vtkIdType pointId, int fieldId)
2340 {
2341 /*
2342 * returned value:
2343 * -4: no such field
2344 * -3: attribute check failed
2345 * -2: non 2-manifold star
2346 * -1: regular point
2347 * 0: minimum
2348 * 1: saddle
2349 * 2: maximum
2350 */
2351
2352 vtkPointData *pointData = this->GetPointData();
2353 vtkDataArray *scalarField = pointData->GetArray(fieldId);
2354
2355 if(!scalarField) return vtkPolyData::ERR_NO_SUCH_FIELD;
2356
2357 return this->GetScalarFieldCriticalIndex(pointId, scalarField);
2358 }
2359