1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkFocalPlaneContourRepresentation.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 "vtkFocalPlaneContourRepresentation.h"
16 #include "vtkHandleRepresentation.h"
17 #include "vtkCoordinate.h"
18 #include "vtkRenderer.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkBox.h"
21 #include "vtkInteractorObserver.h"
22 #include "vtkMath.h"
23 #include "vtkFocalPlanePointPlacer.h"
24 #include "vtkContourLineInterpolator.h"
25 #include "vtkLine.h"
26 #include "vtkCamera.h"
27 #include "vtkPolyData.h"
28 #include "vtkCellArray.h"
29
30 #include <vector>
31 #include <set>
32 #include <algorithm>
33 #include <iterator>
34
35
36 //----------------------------------------------------------------------
vtkFocalPlaneContourRepresentation()37 vtkFocalPlaneContourRepresentation::vtkFocalPlaneContourRepresentation()
38 {
39 this->PointPlacer = vtkFocalPlanePointPlacer::New();
40 }
41
42 //----------------------------------------------------------------------
~vtkFocalPlaneContourRepresentation()43 vtkFocalPlaneContourRepresentation::~vtkFocalPlaneContourRepresentation()
44 {
45 }
46
47 //----------------------------------------------------------------------
48 // Compute the world position from the display position for this given
49 // point using the renderer.
GetIntermediatePointWorldPosition(int n,int idx,double point[3])50 int vtkFocalPlaneContourRepresentation::GetIntermediatePointWorldPosition(int n,
51 int idx,
52 double point[3])
53 {
54 if ( n < 0 ||
55 static_cast<unsigned int>(n) >= this->Internal->Nodes.size() )
56 {
57 return 0;
58 }
59
60 if ( idx < 0 ||
61 static_cast<unsigned int>(idx) >= this->Internal->Nodes[n]->Points.size() )
62 {
63 return 0;
64 }
65
66 double p[4], fp[4], z, dispPos[2];
67 this->Renderer->GetActiveCamera()->GetFocalPoint(fp);
68 vtkInteractorObserver::ComputeWorldToDisplay(this->Renderer,
69 fp[0], fp[1], fp[2], fp);
70 z = fp[2];
71
72 dispPos[0] = this->Internal->Nodes[n]->Points[idx]->NormalizedDisplayPosition[0];
73 dispPos[1] = this->Internal->Nodes[n]->Points[idx]->NormalizedDisplayPosition[1];
74 this->Renderer->NormalizedDisplayToDisplay( dispPos[0], dispPos[1] );
75
76 vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer,
77 dispPos[0], dispPos[1], z, p);
78
79 point[0] = p[0];
80 point[1] = p[1];
81 point[2] = p[2];
82
83 return 1;
84 }
85
86 //----------------------------------------------------------------------
87 // Compute the world position from the display position for this given
88 // point using the renderer.
GetIntermediatePointDisplayPosition(int n,int idx,double point[3])89 int vtkFocalPlaneContourRepresentation::GetIntermediatePointDisplayPosition(int n,
90 int idx,
91 double point[3])
92 {
93 if ( n < 0 ||
94 static_cast<unsigned int>(n) >= this->Internal->Nodes.size() )
95 {
96 return 0;
97 }
98
99 if ( idx < 0 ||
100 static_cast<unsigned int>(idx) >= this->Internal->Nodes[n]->Points.size() )
101 {
102 return 0;
103 }
104
105 point[0] = this->Internal->Nodes[n]->Points[idx]->NormalizedDisplayPosition[0];
106 point[1] = this->Internal->Nodes[n]->Points[idx]->NormalizedDisplayPosition[1];
107 this->Renderer->NormalizedDisplayToDisplay( point[0], point[1] );
108
109 return 1;
110 }
111
112 //----------------------------------------------------------------------
GetNthNodeDisplayPosition(int n,double displayPos[2])113 int vtkFocalPlaneContourRepresentation::GetNthNodeDisplayPosition(
114 int n, double displayPos[2] )
115 {
116 if ( n < 0 ||
117 static_cast<unsigned int>(n) >= this->Internal->Nodes.size() )
118 {
119 return 0;
120 }
121
122 displayPos[0] = this->Internal->Nodes[n]->NormalizedDisplayPosition[0];
123 displayPos[1] = this->Internal->Nodes[n]->NormalizedDisplayPosition[1];
124 this->Renderer->NormalizedDisplayToDisplay( displayPos[0], displayPos[1] );
125
126 return 1;
127 }
128
129 //----------------------------------------------------------------------
GetNthNodeWorldPosition(int n,double worldPos[3])130 int vtkFocalPlaneContourRepresentation::GetNthNodeWorldPosition(
131 int n, double worldPos[3] )
132 {
133 if ( n < 0 ||
134 static_cast<unsigned int>(n) >= this->Internal->Nodes.size() )
135 {
136 return 0;
137 }
138
139 double p[4], fp[4], z, dispPos[2];
140 this->Renderer->GetActiveCamera()->GetFocalPoint(fp);
141 vtkInteractorObserver::ComputeWorldToDisplay(this->Renderer,
142 fp[0], fp[1], fp[2], fp);
143 z = fp[2];
144 dispPos[0] = this->Internal->Nodes[n]->NormalizedDisplayPosition[0];
145 dispPos[1] = this->Internal->Nodes[n]->NormalizedDisplayPosition[1];
146 this->Renderer->NormalizedDisplayToDisplay( dispPos[0], dispPos[1] );
147 vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer,
148 dispPos[0], dispPos[1], z, p);
149
150 worldPos[0] = p[0];
151 worldPos[1] = p[1];
152 worldPos[2] = p[2];
153
154 return 1;
155 }
156
157 //----------------------------------------------------------------------
158 void vtkFocalPlaneContourRepresentation
UpdateContourWorldPositionsBasedOnDisplayPositions()159 ::UpdateContourWorldPositionsBasedOnDisplayPositions()
160 {
161 double p[4], fp[4], z, dispPos[2];
162 this->Renderer->GetActiveCamera()->GetFocalPoint(fp);
163 vtkInteractorObserver::ComputeWorldToDisplay(this->Renderer,
164 fp[0], fp[1], fp[2], fp);
165 z = fp[2];
166
167 for(unsigned int i=0;i<this->Internal->Nodes.size();i++)
168 {
169
170 dispPos[0] = this->Internal->Nodes[i]->NormalizedDisplayPosition[0];
171 dispPos[1] = this->Internal->Nodes[i]->NormalizedDisplayPosition[1];
172 this->Renderer->NormalizedDisplayToDisplay( dispPos[0], dispPos[1] );
173
174 vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer,
175 dispPos[0], dispPos[1], z, p);
176
177 this->Internal->Nodes[i]->WorldPosition[0] = p[0];
178 this->Internal->Nodes[i]->WorldPosition[1] = p[1];
179 this->Internal->Nodes[i]->WorldPosition[2] = p[2];
180
181 for (unsigned int j=0;j<this->Internal->Nodes[i]->Points.size();j++)
182 {
183 dispPos[0] = this->Internal->Nodes[i]->Points[j]->NormalizedDisplayPosition[0];
184 dispPos[1] = this->Internal->Nodes[i]->Points[j]->NormalizedDisplayPosition[1];
185 this->Renderer->NormalizedDisplayToDisplay( dispPos[0], dispPos[1] );
186
187 vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer,
188 dispPos[0], dispPos[1], z, p);
189
190 this->Internal->Nodes[i]->Points[j]->WorldPosition[0] = p[0];
191 this->Internal->Nodes[i]->Points[j]->WorldPosition[1] = p[1];
192 this->Internal->Nodes[i]->Points[j]->WorldPosition[2] = p[2];
193 }
194 }
195 }
196
197 //---------------------------------------------------------------------
UpdateContour()198 int vtkFocalPlaneContourRepresentation::UpdateContour()
199 {
200 this->PointPlacer->UpdateInternalState();
201
202 if ( this->ContourBuildTime > this->Renderer->GetMTime() &&
203 this->ContourBuildTime > this->PointPlacer->GetMTime() )
204 {
205 // Contour does not need to be rebuilt
206 return 0;
207 }
208
209 // The representation maintains its true positions based on display positions.
210 // Sync the world positions in terms of the current display positions.
211 // The superclass will do the line interpolation etc from the world positions
212 //
213 // TODO:
214 // I don't want to rebuild the contour every time the renderer changes
215 // state. For instance there is no reason for me to re-do this when a W/L
216 // action is performed on the window. How do I know if relevant events have
217 // transpired like zoom or scale changes ?
218 // In the current state, the 'if' statement above is invariably true.
219 //
220 this->UpdateContourWorldPositionsBasedOnDisplayPositions();
221
222 unsigned int i;
223 for(i=0; (i+1)<this->Internal->Nodes.size(); i++)
224 {
225 this->UpdateLine(i, i+1);
226 }
227
228 if ( this->ClosedLoop )
229 {
230 this->UpdateLine( static_cast<int>(this->Internal->Nodes.size())-1, 0);
231 }
232 this->BuildLines();
233
234 this->ContourBuildTime.Modified();
235 return 1;
236 }
237
238 //----------------------------------------------------------------------
UpdateLines(int index)239 void vtkFocalPlaneContourRepresentation::UpdateLines( int index )
240 {
241 this->Superclass::UpdateLines(index);
242 }
243
244 //----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)245 void vtkFocalPlaneContourRepresentation::PrintSelf(ostream& os, vtkIndent indent)
246 {
247 this->Superclass::PrintSelf(os,indent);
248 }
249
250