2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2012 enGits GmbH +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 /*=========================================================================
26 Module: $RCSfile: vtkImplicitPolyData.cpp,v $
28 Date: $Date: 2003/07/12 11:22:38 $
29 Version: $Revision: 1.1.1.1 $
31 Copyright (c) 2002 Denis Shamonin
32 Section Computational Science
33 University of Amsterdam
34 Kruislaan 403, 1098 SJ Amsterdam
37 E-mail : dshamoni@science.uva.nl
38 URL : http://www.science.uva.nl/~dshamoni/
42 This software is distributed WITHOUT ANY WARRANTY; without even
43 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
44 PURPOSE. See the above copyright notice for more information.
46 =========================================================================
48 - Needs to be restructured in line with vtk principles of on demand
49 execution. Eg BuildLinks and BuildLocator on first call to Evaluate*?.
50 Handle input modification correctly etc.
51 - Drop internal triangle filter and just check cell type as encountered?.
52 - Get working with CellLocator. Currently crashes every time, although
53 a large number of cells are located successfully. Too hard to debug,
54 maybe try a tiny dataset.
56 PLEASE SEND ME YOUR UPDATES, BUG FIXES! at dshamoni@science.uva.nl
57 =========================================================================*/
59 #include "vtkImplicitPolyData.h"
60 #include "vtkPolygon.h"
63 vtkImplicitPolyData::vtkImplicitPolyData()
65 this->NoGradient
[0] = 0.0;
66 this->NoGradient
[1] = 0.0;
67 this->NoGradient
[2] = 1.0;
72 this->poly
= vtkPolygon::New();
74 this->EvaluateBoundsSet
=0;
75 this->Tolerance
= 10.0;
78 void vtkImplicitPolyData::SetInput(vtkPolyData
*input
)
80 if( this->input
!= input
)
82 vtkDebugMacro( <<" setting Input to " << (void *)input
);
84 // use a tringle filter on the polydata input
85 // this is done to filter out lines and vertices to leave only
86 // polygons which are required by this algorithm for cell normals
87 if( this->tri
== NULL
)
89 this->tri
= vtkTriangleFilter::New();
90 this->tri
->PassVertsOff();
91 this->tri
->PassLinesOff();
93 this->tri
->SetInput( input
);
96 this->input
= this->tri
->GetOutput();
97 this->input
->BuildLinks(); // to enable calls to GetPointCells
98 this->NoValue
= this->input
->GetLength();
100 if( this->locator
!= NULL
) this->locator
->Delete();
101 locator
= PointLocator::New();
102 this->locator
->SetDataSet( this->input
);
103 // if( this->EvaluateBoundsSet ) // experimental
104 // this->locator->SetEvaluateBounds( this->EvaluateBounds );
105 this->locator
->BuildLocator();
107 if( this->cells
!= NULL
) this->cells
->Delete();
108 this->cells
= vtkIdList::New();
109 this->cells
->SetNumberOfIds( this->input
->GetNumberOfCells() );
111 this->poly
= vtkPolygon::New();
116 // used to extend bounds of point locator
117 void vtkImplicitPolyData::SetEvaluateBounds( double eBounds
[6] )
122 this->EvaluateBounds
[i
] = eBounds
[i
];
125 this->EvaluateBoundsSet
= 1;
128 unsigned long vtkImplicitPolyData::GetMTime()
130 unsigned long mTime
=this->vtkImplicitFunction::GetMTime();
131 unsigned long inputMTime
;
133 if ( this->input
!= NULL
)
135 this->input
->Update ();
136 inputMTime
= this->input
->GetMTime();
137 mTime
= ( inputMTime
> mTime
? inputMTime
: mTime
);
144 vtkImplicitPolyData::~vtkImplicitPolyData()
146 if( this->tri
!= NULL
) this->tri
->Delete();
147 if( this->locator
!= NULL
) this->locator
->Delete();
148 if( this->poly
!= NULL
) this->poly
->Delete();
149 if( this->cells
!= NULL
) this->cells
->Delete();
152 // Evaluate for point x[3].
153 // Method using combination of implicit planes
154 double vtkImplicitPolyData::EvaluateFunction(double x
[3])
156 // See if data set with polygons has been specified
157 if( this->input
== NULL
|| input
->GetNumberOfCells() == 0 )
159 vtkErrorMacro(<<"No polygons to evaluate function!");
160 return this->NoValue
;
166 double dot
, ret
=-VTK_LARGE_FLOAT
, cNormal
[3], closestPoint
[3];
168 // get point id of closest point in data set according Tolerance
169 pid
= this->locator
->FindClosestPointWithinRadius(Tolerance
,x
,dist
);
170 if(( pid
!= -1 ) && (dist
< Tolerance
))
172 this->input
->GetPoint( pid
, closestPoint
);
174 // get cells it belongs to
175 this->input
->GetPointCells( pid
, cells
);
177 for( cellNum
=0; cellNum
<cells
->GetNumberOfIds(); cellNum
++ )
179 cell
= this->input
->GetCell( cells
->GetId( cellNum
) );
182 poly
->ComputeNormal( cell
->GetPoints(), cNormal
);
184 dot
= ( cNormal
[0]*(x
[0]-closestPoint
[0]) +
185 cNormal
[1]*(x
[1]-closestPoint
[1]) +
186 cNormal
[2]*(x
[2]-closestPoint
[2]) );
188 if( dot
> ret
) ret
= dot
;
192 if( ret
== -VTK_LARGE_FLOAT
) ret
= NoValue
;
196 // Evaluate function gradient at point x[3].
197 void vtkImplicitPolyData::EvaluateGradient( double x
[3], double n
[3] )
200 // See if data set with polygons has been specified
201 if( this->input
== NULL
|| input
->GetNumberOfCells() == 0 )
203 vtkErrorMacro(<<"No polygons to evaluate gradient!");
204 for( i
=0; i
<3; i
++ ) n
[i
] = this->NoGradient
[i
];
211 double dot
, ret
=-VTK_LARGE_FLOAT
, cNormal
[3], closestPoint
[3];
213 // get point id of closest point in data set according Tolerance
214 pid
= this->locator
->FindClosestPointWithinRadius(Tolerance
,x
,dist
);
215 if(( pid
!= -1 ) && (dist
< Tolerance
))
217 this->input
->GetPoint( pid
, closestPoint
);
219 // get cells it belongs to
220 this->input
->GetPointCells( pid
, cells
);
222 for( cellNum
=0; cellNum
<cells
->GetNumberOfIds(); cellNum
++ )
224 cell
= this->input
->GetCell( cells
->GetId( cellNum
) );
227 poly
->ComputeNormal( cell
->GetPoints(), cNormal
);
229 dot
= ( cNormal
[0]*(x
[0]-closestPoint
[0]) +
230 cNormal
[1]*(x
[1]-closestPoint
[1]) +
231 cNormal
[2]*(x
[2]-closestPoint
[2]) );
235 for( i
=0; i
<3; i
++ ) n
[i
] = cNormal
[i
];
241 if( ret
== -VTK_LARGE_FLOAT
)
243 for( i
=0; i
<3; i
++ ) n
[i
] = this->NoGradient
[i
];
247 void vtkImplicitPolyData::PrintSelf(ostream
& os
, vtkIndent indent
)
249 vtkImplicitFunction::PrintSelf(os
,indent
);
251 os
<< indent
<< "No polydata Value: " << this->NoValue
<< "\n";
252 os
<< indent
<< "No polydata Gradient: (" << this->NoGradient
[0] << ", "
253 << this->NoGradient
[1] << ", " << this->NoGradient
[2] << ")\n";
257 os
<< indent
<< "Input : " << this->input
<< "\n";
261 os
<< indent
<< "Input : (none)\n";
264 os
<< indent
<< "Tolerance: " << this->Tolerance
<< "\n";