1 // -*- c-basic-offset: 4 -*-
2 /** @file OverviewOutlinesTool.cpp
3 *
4 * @author Darko Makreshanski
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this software. If not, see
18 * <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #ifdef _WIN32
23 #include "wx/msw/wrapwin.h"
24 #endif
25 #include <GL/glew.h>
26 #ifdef __WXMAC__
27 #include <OpenGL/gl.h>
28 #include <OpenGL/glu.h>
29 #else
30 #include <GL/gl.h>
31 #include <GL/glu.h>
32 #endif
33 #ifdef __APPLE__
34 #include <GLUT/glut.h>
35 #endif
36
37 #include "OverviewOutlinesTool.h"
38 #include "GLViewer.h"
39
40 #include "GreatCircles.h"
41 #include <cfloat>
42
43 const double OverviewOutlinesTool::res=10;
44 const double OverviewOutlinesTool::mindist=2;
45
OverviewOutlinesTool(ToolHelper * helper,GLViewer * viewer)46 OverviewOutlinesTool::OverviewOutlinesTool(ToolHelper * helper, GLViewer * viewer) : thelper(helper),
47 dirty_meshes(true), preview(viewer),
48 display_list_number_canvas(glGenLists(1)),
49 display_list_number_crop(glGenLists(1)),
50 display_list_number_canvas_outline(glGenLists(1)),
51 display_list_number_crop_outline(glGenLists(1))
52 {
53 thelper->GetPanoramaPtr()->addObserver(this);
54 }
55
~OverviewOutlinesTool()56 OverviewOutlinesTool::~OverviewOutlinesTool()
57 {
58 }
59
panoramaChanged(HuginBase::Panorama & pano)60 void OverviewOutlinesTool::panoramaChanged(HuginBase::Panorama &pano)
61 {
62
63 dirty_meshes = true;
64 thelper->GetVisualizationStatePtr()->ForceRequireRedraw();
65
66 }
67
68
69 struct Rec {
RecRec70 Rec(double left, double top, double right, double bottom) : left(left), top(top), right(right), bottom(bottom) {}
RecRec71 Rec() : left(0), top(0), right(0), bottom(0) {}
72 double left;
73 double top;
74 double right;
75 double bottom;
76 };
77
78 //#define WIREFRAME
79
Activate()80 void PanosphereOverviewOutlinesTool::Activate()
81 {
82 static_cast<PanosphereOverviewToolHelper*>(helper)->NotifyMe(PanosphereOverviewToolHelper::DRAW_OVER_IMAGES_FRONT, this);
83 static_cast<PanosphereOverviewToolHelper*>(helper)->NotifyMe(PanosphereOverviewToolHelper::DRAW_OVER_IMAGES_BACK, this);
84 // helper->NotifyMe(ToolHelper::DRAW_OVER_IMAGES, this);
85 helper->NotifyMe(ToolHelper::MARK_DIRTY, this);
86 }
87
88
Activate()89 void PlaneOverviewOutlinesTool::Activate()
90 {
91 (helper)->NotifyMe(ToolHelper::DRAW_OVER_IMAGES, this);
92 helper->NotifyMe(ToolHelper::MARK_DIRTY, this);
93 }
94
AfterDrawImagesEvent()95 void PlaneOverviewOutlinesTool::AfterDrawImagesEvent()
96 {
97 draw();
98 }
99
AfterDrawImagesBackEvent()100 void PanosphereOverviewOutlinesTool::AfterDrawImagesBackEvent()
101 {
102 draw();
103 }
104
AfterDrawImagesFrontEvent()105 void PanosphereOverviewOutlinesTool::AfterDrawImagesFrontEvent()
106 {
107 draw();
108 }
109
drawBackground()110 void PanosphereOverviewOutlinesTool::drawBackground()
111 {
112
113 double radius = static_cast<PanosphereOverviewVisualizationState*>(helper->GetVisualizationStatePtr())->getSphereRadius();
114 GLUquadric* grid = gluNewQuadric();
115 gluSphere(grid, radius+1,40,20);
116
117 }
118
MarkDirty()119 void PanosphereOverviewOutlinesTool::MarkDirty()
120 {
121 dirty_meshes = true;
122 }
123
drawBackground()124 void PlaneOverviewOutlinesTool::drawBackground()
125 {
126
127 glBegin(GL_QUADS);
128
129 double end = 1000000;
130
131 glVertex3f(-end, end, 0);
132 glVertex3f( end, end, 0);
133 glVertex3f( end,-end, 0);
134 glVertex3f(-end,-end, 0);
135
136 glEnd();
137
138 }
139
MarkDirty()140 void PlaneOverviewOutlinesTool::MarkDirty()
141 {
142 dirty_meshes = true;
143 }
144
draw()145 void OverviewOutlinesTool::draw()
146 {
147
148 if (!(preview->m_visualization_state)) {
149 return;
150 }
151
152
153 if (dirty_meshes) {
154
155 // std::cout << "outlines after draw images\n";
156 // vigra::Rect2D trect = preview->m_visualization_state->GetVisibleArea();
157 // double hscale, wscale;
158 // hscale = (float) thelper->GetVisualizationStatePtr()->GetOptions()->getHeight() / (float) preview->m_visualization_state->GetOptions()->getHeight();
159 // wscale = (float) thelper->GetVisualizationStatePtr()->GetOptions()->getWidth() / (float) preview->m_visualization_state->GetOptions()->getWidth();
160 // std::cerr << "outlines " << hscale << " " << wscale << std::endl;
161 // std::cerr << "outlines " << trect.left() << " " << trect.top() << " " << trect.right() << " " << trect.bottom() << std::endl;
162 // vigra::Rect2D rect(trect.left() * wscale, trect.top() * hscale, trect.right() * wscale, trect.bottom() * hscale);
163 // std::cerr << "outlines " << rect.left() << " " << rect.top() << " " << rect.right() << " " << rect.bottom() << std::endl;
164
165 vigra::Rect2D rect = preview->m_visualization_state->GetVisibleArea();
166
167 glNewList(display_list_number_canvas,GL_COMPILE);
168 DrawRect(rect.left(), rect.top(), rect.right(), rect.bottom(),false);
169 glEndList();
170 glNewList(display_list_number_canvas_outline,GL_COMPILE);
171 DrawRect(rect.left(), rect.top(), rect.right(), rect.bottom(),true, 4.0);
172 glEndList();
173
174 vigra::Rect2D roi = thelper->GetViewStatePtr()->GetOptions()->getROI();
175 glNewList(display_list_number_crop,GL_COMPILE);
176 DrawRect(roi.left(), roi.top(), roi.right(), roi.bottom(),false);
177 glEndList();
178 glNewList(display_list_number_crop_outline,GL_COMPILE);
179 DrawRect(roi.left(), roi.top(), roi.right(), roi.bottom(),true, 2.0);
180 glEndList();
181
182 dirty_meshes = false;
183
184 // std::cout << "outlines adi " << rect.left() << " " << rect.top() << " " << rect.right() << " " << rect.bottom() << std::endl;
185 // std::cout << "outlines adi " << roi.left() << " " << roi.top() << " " << roi.right() << " " << roi.bottom() << std::endl;
186 }
187
188 if (thelper->GetVisualizationStatePtr()->RequireRecalculateViewport()) {
189
190 vigra::Rect2D rect = preview->m_visualization_state->GetVisibleArea();
191 glNewList(display_list_number_canvas_outline,GL_COMPILE);
192 DrawRect(rect.left(), rect.top(), rect.right(), rect.bottom(),true, 4.0);
193 glEndList();
194
195 vigra::Rect2D roi = thelper->GetViewStatePtr()->GetOptions()->getROI();
196 glNewList(display_list_number_crop_outline,GL_COMPILE);
197 DrawRect(roi.left(), roi.top(), roi.right(), roi.bottom(),true, 2.0);
198 glEndList();
199
200 }
201
202
203 glDisable(GL_TEXTURE_2D);
204
205 glEnable(GL_BLEND);
206 glColor4f(0, 0, 0, 0.50f);
207 glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
208 drawBackground();
209
210
211 glColor4f(1.0f, 1.0f, 1.0f, 0.20f);
212 glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
213 glCallList(display_list_number_canvas);
214
215 // std::cout << "outlines " << roi.left() << " " << roi.top() << " " << roi.right() << " " << roi.bottom() << std::endl;
216
217 glColor4f(1.0f, 1.0f, 1.0f, 0.66f);
218 glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
219 glCallList(display_list_number_crop);
220
221 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
222 glColor4f(0.8f, 0.8f, 0.8f, 0.5f);
223 glCallList(display_list_number_canvas_outline);
224 glColor4f(0.8f, 0.8f, 0.8f, 0.6f);
225 glCallList(display_list_number_crop_outline);
226
227 glEnable(GL_TEXTURE_2D);
228 glDisable(GL_BLEND);
229 glColor4f(1,1,1,1);
230
231 }
232
DrawRect(double left,double top,double right,double bottom,bool outline,double line_width)233 void OverviewOutlinesTool::DrawRect(double left, double top, double right, double bottom, bool outline, double line_width)
234 {
235
236 vigra::Size2D size = thelper->GetVisualizationStatePtr()->GetOptions()->getSize();
237 double mlength = (size->y > size->x) ? size->y : size->x;
238
239 double fov = thelper->GetVisualizationStatePtr()->GetOptions()->getHFOV();
240
241 //since res was initially estimated for size of 360x100;
242 //TODO make res scale dependent
243 double tres = res * mlength / fov;
244 double tmindist = mindist * mlength / fov;
245
246 // std::cerr << "outlines " << mlength << std::endl;
247 // std::cerr << "outlines " << right << std::endl;
248
249 double safety = 1;
250 left += safety;
251 top += safety;
252 right -= safety;
253 bottom -= safety;
254
255 HuginBase::PTools::Transform transform;
256 HuginBase::SrcPanoImage image;
257 // image.setSize(vigra::Size2D(360,180));
258 image.setSize(size);
259 image.setHFOV(fov);
260 switch(thelper->GetVisualizationStatePtr()->GetOptions()->getProjection()) {
261 case HuginBase::PanoramaOptions::EQUIRECTANGULAR:
262 image.setProjection(HuginBase::BaseSrcPanoImage::EQUIRECTANGULAR);
263 break;
264 case HuginBase::PanoramaOptions::RECTILINEAR:
265 image.setProjection(HuginBase::BaseSrcPanoImage::RECTILINEAR);
266 break;
267 default:
268 DEBUG_ERROR("OverviewOutlinesTools: unknown projection")
269 break;
270 }
271
272 transform.createTransform(image, *(preview->m_visualization_state->GetOptions()));
273
274 HuginBase::PanoramaOptions::ProjectionFormat proj = thelper->GetViewStatePtr()->GetOptions()->getProjection();
275
276 switch(proj) {
277
278 case HuginBase::PanoramaOptions::SINUSOIDAL:
279 case HuginBase::PanoramaOptions::LAMBERT:
280 case HuginBase::PanoramaOptions::LAMBERT_AZIMUTHAL:
281 case HuginBase::PanoramaOptions::HAMMER_AITOFF:
282 case HuginBase::PanoramaOptions::FULL_FRAME_FISHEYE:
283 case HuginBase::PanoramaOptions::ALBERS_EQUAL_AREA_CONIC:
284 case HuginBase::PanoramaOptions::ORTHOGRAPHIC:
285 case HuginBase::PanoramaOptions::EQUISOLID:
286 case HuginBase::PanoramaOptions::THOBY_PROJECTION:
287
288 {
289
290 //in this case just the divide the base rectangle by a certain amount of steps
291
292 float steps = 40;
293
294 double wstep = (float)(right - left) / steps;
295 double hstep = (float)(bottom - top) / steps;
296
297 for(int w = 0 ; w < steps ; w++) {
298 for(int h = 0 ; h < steps ; h++) {
299
300 //if outline is needed just consider edge cases
301 if (outline) {
302 if (!(w == 0 || h == 0 || w == steps - 1 || steps - 1)) {
303 continue;
304 }
305 }
306
307 Rect rec(left + w * wstep, top + h * hstep, left + (w+1) * wstep, top + (h+1)* hstep);
308 Rect tr = rec.transformImgCoord(&transform);
309
310 //this section should be added to avoid certain problems with these projections
311 //(just disregard edges with lengths larger than some value with respect to the radius of the sphere)
312 //TODO this was commented when support for mosaic plane was added, make this work again
313 // double edge1 = (tr.val[0][0]-tr.val[1][0])*(tr.val[0][0]-tr.val[1][0]) + (tr.val[0][1]-tr.val[1][1])*(tr.val[0][1]-tr.val[1][1]);
314 // double edge2 = (tr.val[1][0]-tr.val[2][0])*(tr.val[1][0]-tr.val[2][0]) + (tr.val[1][1]-tr.val[2][1])*(tr.val[1][1]-tr.val[2][1]);
315 // double edge3 = (tr.val[2][0]-tr.val[3][0])*(tr.val[2][0]-tr.val[3][0]) + (tr.val[2][1]-tr.val[3][1])*(tr.val[2][1]-tr.val[3][1]);
316 // double edge4 = (tr.val[3][0]-tr.val[0][0])*(tr.val[3][0]-tr.val[0][0]) + (tr.val[3][1]-tr.val[0][1])*(tr.val[3][1]-tr.val[0][1]);
317
318 // double maxlimit = (radius/2.0)*(radius/2.0);
319 // if (
320 // proj == HuginBase::PanoramaOptions::SINUSOIDAL ||
321 // proj == HuginBase::PanoramaOptions::ALBERS_EQUAL_AREA_CONIC
322 // )
323 // if (edge1 > maxlimit || edge2 > maxlimit || edge3 > maxlimit || edge4 > maxlimit) {
324 // continue;
325 // }
326
327 if (outline) {
328
329 // glBegin(GL_LINES);
330 bool edges[4] = {false,false,false,false};
331 if (w == 0) {
332 edges[0] = true;
333 }
334 if (w == steps - 1) {
335 edges[2] = true;
336 }
337 if (h == 0) {
338 edges[3] = true;
339 }
340 if (h == steps - 1) {
341 edges[1] = true;
342 }
343 for (int i = 0 ; i < 4 ; i++) {
344 if (edges[i]) {
345
346
347 //draw a line with the help of the GreatCircles class so that a mesh is drawn instead of just a line
348 int plus = i+1;
349 if (plus == 4) plus = 0;
350 hugin_utils::FDiff2D cd1(tr.val[i][0], tr.val[i][1]);
351 hugin_utils::FDiff2D cd2(tr.val[plus][0], tr.val[plus][1]);
352 GreatCircleArc::LineSegment line;
353 line.vertices[0] = cd1;
354 line.vertices[1] = cd2;
355 line.doGL(line_width, thelper->GetVisualizationStatePtr());
356
357
358 // for (int j = 0 ; j < 2 ; j++) {
359 // int plus = i+j;
360 // if (plus == 4) plus = 0;
361 // double x,y,z;
362 // double tx,ty;
363 // tx = tr.val[plus][0];
364 // ty = tr.val[plus][1];
365 //// ty = ty - 90;
366 //// tx = tx - 180;
367 //// ty *= -1;
368 //// double x,y,z;
369 //// MeshManager::MeshInfo::Coord3D coord = MeshManager::PanospheOverviewMeshInfo::Convert(x,y,z,tx,ty,radius);
370 // hugin_utils::FDiff2D cd(tx,ty);
371 // MeshManager::MeshInfo::Coord3D coord = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd);
372 // glVertex3f(coord.x,coord.y,coord.z);
373 // }
374
375 }
376 }
377 // glEnd();
378
379 } else {
380
381 //in this case draw the mesh
382
383 #ifdef WIREFRAME
384 glBegin(GL_LINE_LOOP);
385 #else
386 glBegin(GL_POLYGON);
387 #endif
388 for (int s = 0 ; s < 4 ; s++) {
389 double tx,ty;
390 tx = tr.val[s][0];
391 ty = tr.val[s][1];
392 // ty = ty - 90;
393 // tx = tx - 180;
394 // ty *= -1;
395 hugin_utils::FDiff2D cd(tx,ty);
396 MeshManager::MeshInfo::Coord3D coord = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd);
397 glVertex3f(coord.x,coord.y,coord.z);
398 }
399 glEnd();
400
401 }
402
403 }
404 }
405
406 }
407
408 break;
409
410 case HuginBase::PanoramaOptions::RECTILINEAR:
411 case HuginBase::PanoramaOptions::EQUIRECTANGULAR:
412 case HuginBase::PanoramaOptions::CYLINDRICAL:
413 case HuginBase::PanoramaOptions::STEREOGRAPHIC:
414 case HuginBase::PanoramaOptions::MERCATOR:
415 case HuginBase::PanoramaOptions::TRANSVERSE_MERCATOR:
416 case HuginBase::PanoramaOptions::MILLER_CYLINDRICAL:
417 case HuginBase::PanoramaOptions::PANINI:
418 case HuginBase::PanoramaOptions::EQUI_PANINI:
419 case HuginBase::PanoramaOptions::BIPLANE:
420 case HuginBase::PanoramaOptions::TRIPLANE:
421 case HuginBase::PanoramaOptions::GENERAL_PANINI:
422 case HuginBase::PanoramaOptions::ARCHITECTURAL:
423
424 //stack to keep the rectangles to be divided
425 std::vector<Rec> stack;
426
427 stack.push_back(Rec(left,top,right,bottom));
428 //if outline needs to be obtained, after each rectangle another rectangle is pushed back
429 if (outline) {
430 stack.push_back(Rec(true, true, true, true));
431 }
432
433 while(!stack.empty()) {
434
435 Rec edge;
436 if (outline) {
437 edge = stack[stack.size() - 1];
438 stack.pop_back();
439 }
440
441 Rec top_rec = stack[stack.size() - 1];
442 stack.pop_back();
443
444 if (outline) {
445 if (!(edge.left || edge.top || edge.right || edge.bottom )) {
446 continue;
447 }
448 }
449
450 Rect rect(top_rec.left, top_rec.top, top_rec.right, top_rec.bottom);
451
452 Rect tr = rect.transformImgCoord(&transform);
453
454 double edge1 = (tr.val[0][0]-tr.val[1][0])*(tr.val[0][0]-tr.val[1][0]) + (tr.val[0][1]-tr.val[1][1])*(tr.val[0][1]-tr.val[1][1]);
455 double edge2 = (tr.val[1][0]-tr.val[2][0])*(tr.val[1][0]-tr.val[2][0]) + (tr.val[1][1]-tr.val[2][1])*(tr.val[1][1]-tr.val[2][1]);
456 double edge3 = (tr.val[2][0]-tr.val[3][0])*(tr.val[2][0]-tr.val[3][0]) + (tr.val[2][1]-tr.val[3][1])*(tr.val[2][1]-tr.val[3][1]);
457 double edge4 = (tr.val[3][0]-tr.val[0][0])*(tr.val[3][0]-tr.val[0][0]) + (tr.val[3][1]-tr.val[0][1])*(tr.val[3][1]-tr.val[0][1]);
458
459 // std::cout << "outlines " << top_rec.left << " " << top_rec.top << " " << top_rec.right << " " << top_rec.bottom << std::endl;
460 // std::cout << "outlines " << edge1 << " " << edge2 << " " << edge3 << " " << edge4 << std::endl;
461
462 // std::cout << "outlines " << tr.val[0][0] << " " << tr.val[0][1] << std::endl;
463 // std::cout << "outlines " << tr.val[1][0] << " " << tr.val[1][1] << std::endl;
464 // std::cout << "outlines " << tr.val[2][0] << " " << tr.val[2][1] << std::endl;
465 // std::cout << "outlines " << tr.val[3][0] << " " << tr.val[3][1] << std::endl;
466
467 double ressq = tres * tres;
468
469 bool divide_ver = false;
470 bool divide_hor = false;
471
472 //decide whether to divide the current rectangle
473 if (
474 (edge1 > ressq || edge3 > ressq)
475 &&
476 std::abs(top_rec.top - top_rec.bottom) > tmindist
477 ) {
478
479 divide_ver = true;
480
481 } else if (
482 (edge2 > ressq || edge4 > ressq)
483 &&
484 std::abs(top_rec.left - top_rec.right) > tmindist
485 ) {
486
487 divide_hor = true;
488
489 }
490
491 if (divide_ver) {
492
493 stack.push_back(Rec(top_rec.left,top_rec.top,top_rec.right,(top_rec.top+top_rec.bottom)/2.0));
494 if (outline) {
495 stack.push_back(Rec(edge.left, edge.top, edge.right, false));
496 }
497 stack.push_back(Rec(top_rec.left,(top_rec.top+top_rec.bottom)/2.0,top_rec.right,top_rec.bottom));
498 if (outline) {
499 stack.push_back(Rec(edge.left, false, edge.right, edge.bottom));
500 }
501 }
502
503 if (divide_hor) {
504
505 stack.push_back(Rec(top_rec.left,top_rec.top,(top_rec.left+top_rec.right)/2.0,top_rec.bottom));
506 if (outline) {
507 stack.push_back(Rec(edge.left, edge.top, false, edge.bottom));
508 }
509 stack.push_back(Rec((top_rec.left+top_rec.right)/2.0,top_rec.top,top_rec.right,top_rec.bottom));
510 if (outline) {
511 stack.push_back(Rec(false, edge.top, edge.right, edge.bottom));
512 }
513
514 }
515
516 if (!(divide_ver || divide_hor)) {
517
518 //draw it
519
520 if (outline) {
521 // glBegin(GL_LINES);
522 bool edges[4];
523 edges[0] = edge.left!=0;
524 edges[1] = edge.bottom!=0;
525 edges[2] = edge.right!=0;
526 edges[3] = edge.top!=0;
527 for (int i = 0 ; i < 4 ; i++) {
528 if (edges[i]) {
529 // std::cout << "outlines line!!" << i << "\n";
530 // std::cout << "outlines " << top_rec.left << " " << top_rec.top << " " << top_rec.right << " " << top_rec.bottom << std::endl;
531
532 int plus = i+1;
533 if (plus == 4) plus = 0;
534 hugin_utils::FDiff2D cd1(tr.val[i][0], tr.val[i][1]);
535 hugin_utils::FDiff2D cd2(tr.val[plus][0], tr.val[plus][1]);
536 GreatCircleArc::LineSegment line;
537 line.vertices[0] = cd1;
538 line.vertices[1] = cd2;
539 line.doGL(line_width, thelper->GetVisualizationStatePtr());
540
541 // MeshManager::MeshInfo::Coord3D coord1 = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd1);
542 // MeshManager::MeshInfo::Coord3D coord2 = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd2);
543 // glVertex3f(coord1.x,coord1.y,coord1.z);
544 // glVertex3f(coord2.x,coord2.y,coord2.z);
545
546
547 // for (int j = 0 ; j < 2 ; j++) {
548 // int plus = i+j;
549 // if (plus == 4) plus = 0;
550 // double x,y,z;
551 // double tx,ty;
552 // tx = tr.val[plus][0];
553 // ty = tr.val[plus][1];
554 //// ty = ty - 90;
555 //// tx = tx - 180;
556 //// ty *= -1;
557
558 //
559 // hugin_utils::FDiff2D cd(tx,ty);
560 // MeshManager::MeshInfo::Coord3D coord = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd);
561 // glVertex3f(coord.x,coord.y,coord.z);
562 // }
563 }
564 }
565 // glEnd();
566 } else {
567 #ifdef WIREFRAME
568 glBegin(GL_LINE_LOOP);
569 #else
570 glBegin(GL_POLYGON);
571 #endif
572 for (int s = 0 ; s < 4 ; s++) {
573 double tx,ty;
574 tx = tr.val[s][0];
575 ty = tr.val[s][1];
576 // ty = ty - 90;
577 // tx = tx - 180;
578 // ty *= -1;
579 hugin_utils::FDiff2D cd(tx,ty);
580 MeshManager::MeshInfo::Coord3D coord = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd);
581 glVertex3f(coord.x,coord.y,coord.z);
582 }
583 glEnd();
584 }
585 }
586
587 }
588
589 break;
590
591 }
592
593 }
594
595
596
597