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