1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImplicitSum.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 "vtkImplicitSum.h"
16
17 #include "vtkDoubleArray.h"
18 #include "vtkImplicitFunctionCollection.h"
19 #include "vtkObjectFactory.h"
20
21 #include <cmath>
22
23 vtkStandardNewMacro(vtkImplicitSum);
24
25 //----------------------------------------------------------------------------
26 // Constructor.
vtkImplicitSum()27 vtkImplicitSum::vtkImplicitSum()
28 {
29 this->FunctionList = vtkImplicitFunctionCollection::New();
30 this->Weights = vtkDoubleArray::New();
31 this->Weights->SetNumberOfComponents(1);
32 this->TotalWeight = 0.0;
33 this->NormalizeByWeight = 0;
34 }
35
36 //----------------------------------------------------------------------------
~vtkImplicitSum()37 vtkImplicitSum::~vtkImplicitSum()
38 {
39 this->FunctionList->Delete();
40 this->Weights->Delete();
41 }
42
43 //----------------------------------------------------------------------------
GetMTime()44 vtkMTimeType vtkImplicitSum::GetMTime()
45 {
46 vtkMTimeType fMtime;
47 vtkMTimeType mtime = this->vtkImplicitFunction::GetMTime();
48 vtkImplicitFunction *f;
49
50 fMtime = this->Weights->GetMTime();
51 if ( fMtime > mtime )
52 {
53 mtime = fMtime;
54 }
55
56 vtkCollectionSimpleIterator sit;
57 for (this->FunctionList->InitTraversal(sit);
58 (f=this->FunctionList->GetNextImplicitFunction(sit)); )
59 {
60 fMtime = f->GetMTime();
61 if ( fMtime > mtime )
62 {
63 mtime = fMtime;
64 }
65 }
66 return mtime;
67 }
68
69 //----------------------------------------------------------------------------
70 // Add another implicit function to the list of functions.
AddFunction(vtkImplicitFunction * f,double scale)71 void vtkImplicitSum::AddFunction(vtkImplicitFunction *f, double scale)
72 {
73 this->Modified();
74 this->FunctionList->AddItem(f);
75 this->Weights->InsertNextValue(scale);
76 this->CalculateTotalWeight();
77 }
78
79 //----------------------------------------------------------------------------
SetFunctionWeight(vtkImplicitFunction * f,double scale)80 void vtkImplicitSum::SetFunctionWeight(vtkImplicitFunction *f, double scale)
81 {
82 int loc = this->FunctionList->IsItemPresent(f);
83 if (! loc)
84 {
85 vtkWarningMacro("Function not found in function list");
86 return;
87 }
88 loc--; // IsItemPresent returns index+1.
89
90 if ( this->Weights->GetValue(loc) != scale )
91 {
92 this->Modified();
93 this->Weights->SetValue(loc, scale);
94 this->CalculateTotalWeight();
95 }
96 }
97
98 //----------------------------------------------------------------------------
RemoveAllFunctions()99 void vtkImplicitSum::RemoveAllFunctions()
100 {
101 this->Modified();
102 this->FunctionList->RemoveAllItems();
103 this->Weights->Initialize();
104 this->TotalWeight = 0.0;
105 }
106
107 //----------------------------------------------------------------------------
CalculateTotalWeight(void)108 void vtkImplicitSum::CalculateTotalWeight(void)
109 {
110 this->TotalWeight = 0.0;
111
112 for(int i = 0; i < this->Weights->GetNumberOfTuples(); ++i)
113 {
114 this->TotalWeight += this->Weights->GetValue(i);
115 }
116 }
117
118
119 //----------------------------------------------------------------------------
120 // Evaluate sum of implicit functions.
EvaluateFunction(double x[3])121 double vtkImplicitSum::EvaluateFunction(double x[3])
122 {
123 double sum = 0;
124 double c;
125 int i;
126 vtkImplicitFunction *f;
127 double *weights = this->Weights->GetPointer(0);
128
129 vtkCollectionSimpleIterator sit;
130 for (i = 0, this->FunctionList->InitTraversal(sit);
131 (f=this->FunctionList->GetNextImplicitFunction(sit)); i++)
132 {
133 c = weights[i];
134 if (c != 0.0)
135 {
136 sum += f->FunctionValue(x)*c;
137 }
138 }
139 if (this->NormalizeByWeight && this->TotalWeight != 0.0)
140 {
141 sum /= this->TotalWeight;
142 }
143 return sum;
144 }
145
146 //----------------------------------------------------------------------------
147 // Evaluate gradient of sum of functions (valid only if linear)
EvaluateGradient(double x[3],double g[3])148 void vtkImplicitSum::EvaluateGradient(double x[3], double g[3])
149 {
150 double c;
151 int i;
152 double gtmp[3];
153 vtkImplicitFunction *f;
154 double *weights = this->Weights->GetPointer(0);
155
156 g[0] = g[1] = g[2] = 0.0;
157 vtkCollectionSimpleIterator sit;
158 for (i = 0, this->FunctionList->InitTraversal(sit);
159 (f=this->FunctionList->GetNextImplicitFunction(sit)); i++)
160 {
161 c = weights[i];
162 if ( c != 0.0 )
163 {
164 f->FunctionGradient(x, gtmp);
165 g[0] += gtmp[0]*c;
166 g[1] += gtmp[1]*c;
167 g[2] += gtmp[2]*c;
168 }
169 }
170
171 if (this->NormalizeByWeight && this->TotalWeight != 0.0)
172 {
173 g[0] /= this->TotalWeight;
174 g[1] /= this->TotalWeight;
175 g[2] /= this->TotalWeight;
176 }
177 }
178
179 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)180 void vtkImplicitSum::PrintSelf(ostream& os, vtkIndent indent)
181 {
182 this->Superclass::PrintSelf(os,indent);
183
184 os << indent << "NormalizeByWeight: "
185 << (this->NormalizeByWeight ? "On\n" : "Off\n");
186
187 os << indent << "Function List:\n";
188 this->FunctionList->PrintSelf(os,indent.GetNextIndent());
189
190 os << indent << "Weights:\n";
191 this->Weights->PrintSelf(os,indent.GetNextIndent());
192 }
193