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