1 /*=========================================================================
4 Module: $RCSfile: vtkImplicitPolyData.cpp,v $
6 Date: $Date: 2003/07/12 11:22:38 $
7 Version: $Revision: 1.1.1.1 $
9 Copyright (c) 2002 Denis Shamonin
10 Section Computational Science
11 University of Amsterdam
12 Kruislaan 403, 1098 SJ Amsterdam
15 E-mail : dshamoni@science.uva.nl
16 URL : http://www.science.uva.nl/~dshamoni/
20 This software is distributed WITHOUT ANY WARRANTY; without even
21 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
22 PURPOSE. See the above copyright notice for more information.
24 =========================================================================
26 - Needs to be restructured in line with vtk principles of on demand
27 execution. Eg BuildLinks and BuildLocator on first call to Evaluate*?.
28 Handle input modification correctly etc.
29 - Drop internal triangle filter and just check cell type as encountered?.
30 - Get working with CellLocator. Currently crashes every time, although
31 a large number of cells are located successfully. Too hard to debug,
32 maybe try a tiny dataset.
34 PLEASE SEND ME YOUR UPDATES, BUG FIXES! at dshamoni@science.uva.nl
35 =========================================================================*/
37 #include "vtkImplicitPolyData.h"
38 #include "vtkPolygon.h"
41 vtkImplicitPolyData::vtkImplicitPolyData()
43 this->NoGradient
[0] = 0.0;
44 this->NoGradient
[1] = 0.0;
45 this->NoGradient
[2] = 1.0;
50 this->poly
= vtkPolygon::New();
52 this->EvaluateBoundsSet
=0;
53 this->Tolerance
= 10.0;
56 void vtkImplicitPolyData::SetInput(vtkPolyData
*input
)
58 if( this->input
!= input
)
60 vtkDebugMacro( <<" setting Input to " << (void *)input
);
62 // use a tringle filter on the polydata input
63 // this is done to filter out lines and vertices to leave only
64 // polygons which are required by this algorithm for cell normals
65 if( this->tri
== NULL
)
67 this->tri
= vtkTriangleFilter::New();
68 this->tri
->PassVertsOff();
69 this->tri
->PassLinesOff();
71 this->tri
->SetInput( input
);
74 this->input
= this->tri
->GetOutput();
75 this->input
->BuildLinks(); // to enable calls to GetPointCells
76 this->NoValue
= this->input
->GetLength();
78 if( this->locator
!= NULL
) this->locator
->Delete();
79 locator
= PointLocator::New();
80 this->locator
->SetDataSet( this->input
);
81 // if( this->EvaluateBoundsSet ) // experimental
82 // this->locator->SetEvaluateBounds( this->EvaluateBounds );
83 this->locator
->BuildLocator();
85 if( this->cells
!= NULL
) this->cells
->Delete();
86 this->cells
= vtkIdList::New();
87 this->cells
->SetNumberOfIds( this->input
->GetNumberOfCells() );
89 this->poly
= vtkPolygon::New();
94 // used to extend bounds of point locator
95 void vtkImplicitPolyData::SetEvaluateBounds( double eBounds
[6] )
100 this->EvaluateBounds
[i
] = eBounds
[i
];
103 this->EvaluateBoundsSet
= 1;
106 unsigned long vtkImplicitPolyData::GetMTime()
108 unsigned long mTime
=this->vtkImplicitFunction::GetMTime();
109 unsigned long inputMTime
;
111 if ( this->input
!= NULL
)
113 this->input
->Update ();
114 inputMTime
= this->input
->GetMTime();
115 mTime
= ( inputMTime
> mTime
? inputMTime
: mTime
);
122 vtkImplicitPolyData::~vtkImplicitPolyData()
124 if( this->tri
!= NULL
) this->tri
->Delete();
125 if( this->locator
!= NULL
) this->locator
->Delete();
126 if( this->poly
!= NULL
) this->poly
->Delete();
127 if( this->cells
!= NULL
) this->cells
->Delete();
130 // Evaluate for point x[3].
131 // Method using combination of implicit planes
132 double vtkImplicitPolyData::EvaluateFunction(double x
[3])
134 // See if data set with polygons has been specified
135 if( this->input
== NULL
|| input
->GetNumberOfCells() == 0 )
137 vtkErrorMacro(<<"No polygons to evaluate function!");
138 return this->NoValue
;
144 double dot
, ret
=-VTK_LARGE_FLOAT
, cNormal
[3], closestPoint
[3];
146 // get point id of closest point in data set according Tolerance
147 pid
= this->locator
->FindClosestPointWithinRadius(Tolerance
,x
,dist
);
148 if(( pid
!= -1 ) && (dist
< Tolerance
))
150 this->input
->GetPoint( pid
, closestPoint
);
152 // get cells it belongs to
153 this->input
->GetPointCells( pid
, cells
);
155 for( cellNum
=0; cellNum
<cells
->GetNumberOfIds(); cellNum
++ )
157 cell
= this->input
->GetCell( cells
->GetId( cellNum
) );
160 poly
->ComputeNormal( cell
->GetPoints(), cNormal
);
162 dot
= ( cNormal
[0]*(x
[0]-closestPoint
[0]) +
163 cNormal
[1]*(x
[1]-closestPoint
[1]) +
164 cNormal
[2]*(x
[2]-closestPoint
[2]) );
166 if( dot
> ret
) ret
= dot
;
170 if( ret
== -VTK_LARGE_FLOAT
) ret
= NoValue
;
174 // Evaluate function gradient at point x[3].
175 void vtkImplicitPolyData::EvaluateGradient( double x
[3], double n
[3] )
178 // See if data set with polygons has been specified
179 if( this->input
== NULL
|| input
->GetNumberOfCells() == 0 )
181 vtkErrorMacro(<<"No polygons to evaluate gradient!");
182 for( i
=0; i
<3; i
++ ) n
[i
] = this->NoGradient
[i
];
189 double dot
, ret
=-VTK_LARGE_FLOAT
, cNormal
[3], closestPoint
[3];
191 // get point id of closest point in data set according Tolerance
192 pid
= this->locator
->FindClosestPointWithinRadius(Tolerance
,x
,dist
);
193 if(( pid
!= -1 ) && (dist
< Tolerance
))
195 this->input
->GetPoint( pid
, closestPoint
);
197 // get cells it belongs to
198 this->input
->GetPointCells( pid
, cells
);
200 for( cellNum
=0; cellNum
<cells
->GetNumberOfIds(); cellNum
++ )
202 cell
= this->input
->GetCell( cells
->GetId( cellNum
) );
205 poly
->ComputeNormal( cell
->GetPoints(), cNormal
);
207 dot
= ( cNormal
[0]*(x
[0]-closestPoint
[0]) +
208 cNormal
[1]*(x
[1]-closestPoint
[1]) +
209 cNormal
[2]*(x
[2]-closestPoint
[2]) );
213 for( i
=0; i
<3; i
++ ) n
[i
] = cNormal
[i
];
219 if( ret
== -VTK_LARGE_FLOAT
)
221 for( i
=0; i
<3; i
++ ) n
[i
] = this->NoGradient
[i
];
225 void vtkImplicitPolyData::PrintSelf(ostream
& os
, vtkIndent indent
)
227 vtkImplicitFunction::PrintSelf(os
,indent
);
229 os
<< indent
<< "No polydata Value: " << this->NoValue
<< "\n";
230 os
<< indent
<< "No polydata Gradient: (" << this->NoGradient
[0] << ", "
231 << this->NoGradient
[1] << ", " << this->NoGradient
[2] << ")\n";
235 os
<< indent
<< "Input : " << this->input
<< "\n";
239 os
<< indent
<< "Input : (none)\n";
242 os
<< indent
<< "Tolerance: " << this->Tolerance
<< "\n";