1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkCellLocatorStrategy.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 "vtkCellLocatorStrategy.h"
16 
17 #include "vtkAbstractCellLocator.h"
18 #include "vtkCell.h"
19 #include "vtkGenericCell.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPointSet.h"
22 
23 //------------------------------------------------------------------------------
24 vtkStandardNewMacro(vtkCellLocatorStrategy);
25 
26 //------------------------------------------------------------------------------
vtkCellLocatorStrategy()27 vtkCellLocatorStrategy::vtkCellLocatorStrategy()
28 {
29   // You may ask, why this OwnsLocator rigamarole. The reason is because the
30   // reference counting garbage collecter gets confused when the locator,
31   // point set, and strategy are all mixed together; resulting in memory
32   // leaks etc.
33   this->OwnsLocator = false;
34   this->CellLocator = nullptr;
35 }
36 
37 //------------------------------------------------------------------------------
~vtkCellLocatorStrategy()38 vtkCellLocatorStrategy::~vtkCellLocatorStrategy()
39 {
40   if (this->OwnsLocator && this->CellLocator != nullptr)
41   {
42     this->CellLocator->Delete();
43     this->CellLocator = nullptr;
44   }
45 }
46 
47 //------------------------------------------------------------------------------
SetCellLocator(vtkAbstractCellLocator * cL)48 void vtkCellLocatorStrategy::SetCellLocator(vtkAbstractCellLocator* cL)
49 {
50   if (cL != this->CellLocator)
51   {
52     if (this->CellLocator != nullptr && this->OwnsLocator)
53     {
54       this->CellLocator->Delete();
55     }
56 
57     this->CellLocator = cL;
58 
59     if (cL != nullptr)
60     {
61       cL->Register(this);
62     }
63 
64     this->OwnsLocator = true;
65     this->Modified();
66   }
67 }
68 
69 //------------------------------------------------------------------------------
Initialize(vtkPointSet * ps)70 int vtkCellLocatorStrategy::Initialize(vtkPointSet* ps)
71 {
72   // See whether anything has changed. If not, just return.
73   if (this->PointSet != nullptr && ps == this->PointSet && this->MTime < this->InitializeTime)
74   {
75     return 1;
76   }
77 
78   // Set up the point set; return on failure.
79   if (this->Superclass::Initialize(ps) == 0)
80   {
81     return 0;
82   }
83 
84   // Use the point set's cell locator preferentially. If no cell locator,
85   // then we need to create one. If one is specified here in the strategy,
86   // use that. If not, then used the point set's default build cell locator
87   // method.
88   vtkAbstractCellLocator* psCL = ps->GetCellLocator();
89   if (psCL == nullptr)
90   {
91     if (this->CellLocator != nullptr && this->OwnsLocator)
92     {
93       this->CellLocator->SetDataSet(ps);
94       this->CellLocator->BuildLocator();
95     }
96     else
97     {
98       ps->BuildCellLocator();
99       psCL = ps->GetCellLocator();
100       this->CellLocator = psCL;
101       this->OwnsLocator = false;
102     }
103   }
104   else
105   {
106     this->CellLocator = psCL;
107     this->OwnsLocator = false;
108   }
109 
110   this->InitializeTime.Modified();
111 
112   return 1;
113 }
114 
115 //------------------------------------------------------------------------------
FindCell(double x[3],vtkCell * cell,vtkGenericCell * gencell,vtkIdType cellId,double tol2,int & subId,double pcoords[3],double * weights)116 vtkIdType vtkCellLocatorStrategy::FindCell(double x[3], vtkCell* cell, vtkGenericCell* gencell,
117   vtkIdType cellId, double tol2, int& subId, double pcoords[3], double* weights)
118 {
119   // If we are given a starting cell, try that.
120   if (cell && (cellId >= 0))
121   {
122     double closestPoint[3];
123     double dist2;
124     if ((cell->EvaluatePosition(x, closestPoint, subId, pcoords, dist2, weights) == 1) &&
125       (dist2 <= tol2))
126     {
127       return cellId;
128     }
129   }
130 
131   // Okay cache miss, try the cell locator
132   subId = 0; // The cell locator FindCell API should return subId.
133   return this->CellLocator->FindCell(x, tol2, gencell, pcoords, weights);
134 }
135 
136 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)137 void vtkCellLocatorStrategy::PrintSelf(ostream& os, vtkIndent indent)
138 {
139   this->Superclass::PrintSelf(os, indent);
140 
141   os << indent << "CellLocator: " << this->CellLocator << "\n";
142 }
143