1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImplicitDataSet.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 "vtkImplicitDataSet.h"
16
17 #include "vtkCell.h"
18 #include "vtkDataArray.h"
19 #include "vtkDataSet.h"
20 #include "vtkGarbageCollector.h"
21 #include "vtkMath.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPointData.h"
24
25 vtkStandardNewMacro(vtkImplicitDataSet);
26 vtkCxxSetObjectMacro(vtkImplicitDataSet,DataSet,vtkDataSet);
27
28 // Construct an vtkImplicitDataSet with no initial dataset; the OutValue
29 // set to a large negative number; and the OutGradient set to (0,0,1).
vtkImplicitDataSet()30 vtkImplicitDataSet::vtkImplicitDataSet()
31 {
32 this->DataSet = NULL;
33
34 this->OutValue = -VTK_DOUBLE_MAX;
35
36 this->OutGradient[0] = 0.0;
37 this->OutGradient[1] = 0.0;
38 this->OutGradient[2] = 1.0;
39
40 this->Weights = NULL;
41 this->Size = 0;
42 }
43
~vtkImplicitDataSet()44 vtkImplicitDataSet::~vtkImplicitDataSet()
45 {
46 this->SetDataSet(NULL);
47 delete [] this->Weights;
48 }
49
50 // Evaluate the implicit function. This returns the interpolated scalar value
51 // at x[3].
EvaluateFunction(double x[3])52 double vtkImplicitDataSet::EvaluateFunction(double x[3])
53 {
54 vtkDataArray *scalars;
55 vtkCell *cell;
56 vtkIdType id;
57 int subId, i, numPts;
58 double pcoords[3], s;
59
60 if ( this->DataSet->GetMaxCellSize() > this->Size )
61 {
62 delete [] this->Weights;
63 this->Weights = new double[this->DataSet->GetMaxCellSize()];
64 this->Size = this->DataSet->GetMaxCellSize();
65 }
66
67 // See if a dataset has been specified
68 if ( !this->DataSet ||
69 !(scalars = this->DataSet->GetPointData()->GetScalars()) )
70 {
71 vtkErrorMacro(<<"Can't evaluate dataset!");
72 return this->OutValue;
73 }
74
75 // Find the cell that contains xyz and get it
76 cell = this->DataSet->FindAndGetCell(x,NULL,-1,VTK_DBL_EPSILON,subId,pcoords,this->Weights);
77
78 if (cell)
79 { // Interpolate the point data
80 numPts = cell->GetNumberOfPoints();
81 for (s=0.0, i=0; i < numPts; i++)
82 {
83 id = cell->PointIds->GetId(i);
84 s += scalars->GetComponent(id,0) * this->Weights[i];
85 }
86 return s;
87 }
88 else
89 { // use outside value
90 return this->OutValue;
91 }
92 }
93
GetMTime()94 unsigned long vtkImplicitDataSet::GetMTime()
95 {
96 unsigned long mTime=this->vtkImplicitFunction::GetMTime();
97 unsigned long DataSetMTime;
98
99 if ( this->DataSet != NULL )
100 {
101 DataSetMTime = this->DataSet->GetMTime();
102 mTime = ( DataSetMTime > mTime ? DataSetMTime : mTime );
103 }
104
105 return mTime;
106 }
107
108
109 // Evaluate implicit function gradient.
EvaluateGradient(double x[3],double n[3])110 void vtkImplicitDataSet::EvaluateGradient(double x[3], double n[3])
111 {
112 vtkDataArray *scalars;
113 vtkCell *cell;
114 vtkIdType id;
115 int subId, i, numPts;
116 double pcoords[3];
117
118 if ( this->DataSet->GetMaxCellSize() > this->Size )
119 {
120 delete [] this->Weights;
121 this->Weights = new double[this->DataSet->GetMaxCellSize()];
122 this->Size = this->DataSet->GetMaxCellSize();
123 }
124
125 // See if a dataset has been specified
126 if ( !this->DataSet ||
127 !(scalars = this->DataSet->GetPointData()->GetScalars()) )
128 {
129 vtkErrorMacro(<<"Can't evaluate gradient!");
130 for ( i=0; i < 3; i++ )
131 {
132 n[i] = this->OutGradient[i];
133 }
134 return;
135 }
136
137 // Find the cell that contains xyz and get it
138 cell = this->DataSet->FindAndGetCell(x,NULL,-1,VTK_DBL_EPSILON,subId,pcoords,this->Weights);
139
140 if (cell)
141 { // Interpolate the point data
142 numPts = cell->GetNumberOfPoints();
143
144 for ( i=0; i < numPts; i++ ) //Weights used to hold scalar values
145 {
146 id = cell->PointIds->GetId(i);
147 this->Weights[i] = scalars->GetComponent(id,0);
148 }
149 cell->Derivatives(subId, pcoords, this->Weights, 1, n);
150 }
151
152 else
153 { // use outside value
154 for ( i=0; i < 3; i++ )
155 {
156 n[i] = this->OutGradient[i];
157 }
158 }
159 }
160
PrintSelf(ostream & os,vtkIndent indent)161 void vtkImplicitDataSet::PrintSelf(ostream& os, vtkIndent indent)
162 {
163 this->Superclass::PrintSelf(os,indent);
164
165 os << indent << "Out Value: " << this->OutValue << "\n";
166 os << indent << "Out Gradient: (" << this->OutGradient[0] << ", "
167 << this->OutGradient[1] << ", " << this->OutGradient[2] << ")\n";
168
169 if ( this->DataSet )
170 {
171 os << indent << "Data Set: " << this->DataSet << "\n";
172 }
173 else
174 {
175 os << indent << "Data Set: (none)\n";
176 }
177 }
178
179 //----------------------------------------------------------------------------
ReportReferences(vtkGarbageCollector * collector)180 void vtkImplicitDataSet::ReportReferences(vtkGarbageCollector* collector)
181 {
182 this->Superclass::ReportReferences(collector);
183 // These filters share our input and are therefore involved in a
184 // reference loop.
185 vtkGarbageCollectorReport(collector, this->DataSet, "DataSet");
186 }
187