Hugin trunk 0.1
Loading...
Searching...
No Matches
OverviewOutlinesTool.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
22#ifdef _WIN32
23#include "wx/msw/wrapwin.h"
24#endif
25
26#include "hugin_config.h"
27#if defined HAVE_EPOXY && HAVE_EPOXY
28#include <epoxy/gl.h>
29#ifdef __WXMAC__
30#include <OpenGL/glu.h>
31#else
32#include <GL/glu.h>
33#endif
34#else
35#include <GL/glew.h>
36#ifdef __WXMAC__
37#include <OpenGL/gl.h>
38#include <OpenGL/glu.h>
39#else
40#include <GL/gl.h>
41#include <GL/glu.h>
42#endif
43#endif
44#ifdef __APPLE__
45 #include <GLUT/glut.h>
46#endif
47
49#include "GLViewer.h"
50
51#include "GreatCircles.h"
52#include <cfloat>
53
54const double OverviewOutlinesTool::res=10;
56
58 dirty_meshes(true), preview(viewer),
59 display_list_number_canvas(glGenLists(1)),
60 display_list_number_crop(glGenLists(1)),
61 display_list_number_canvas_outline(glGenLists(1)),
62 display_list_number_crop_outline(glGenLists(1))
63{
65}
66
70
78
79
80struct Rec {
81 Rec(double left, double top, double right, double bottom) : left(left), top(top), right(right), bottom(bottom) {}
82 Rec() : left(0), top(0), right(0), bottom(0) {}
83 double left;
84 double top;
85 double right;
86 double bottom;
87};
88
89//#define WIREFRAME
90
92{
95// helper->NotifyMe(ToolHelper::DRAW_OVER_IMAGES, this);
97}
98
99
105
110
115
120
122{
123
124 double radius = static_cast<PanosphereOverviewVisualizationState*>(helper->GetVisualizationStatePtr())->getSphereRadius();
125 GLUquadric* grid = gluNewQuadric();
126 gluSphere(grid, radius+1,40,20);
127
128}
129
134
136{
137
139
140 double end = 1000000;
141
142 glVertex3f(-end, end, 0);
143 glVertex3f( end, end, 0);
144 glVertex3f( end,-end, 0);
145 glVertex3f(-end,-end, 0);
146
147 glEnd();
148
149}
150
155
157{
158
160 return;
161 }
162
163
164 if (dirty_meshes) {
165
166// std::cout << "outlines after draw images\n";
167// vigra::Rect2D trect = preview->m_visualization_state->GetVisibleArea();
168// double hscale, wscale;
169// hscale = (float) thelper->GetVisualizationStatePtr()->GetOptions()->getHeight() / (float) preview->m_visualization_state->GetOptions()->getHeight();
170// wscale = (float) thelper->GetVisualizationStatePtr()->GetOptions()->getWidth() / (float) preview->m_visualization_state->GetOptions()->getWidth();
171// std::cerr << "outlines " << hscale << " " << wscale << std::endl;
172// std::cerr << "outlines " << trect.left() << " " << trect.top() << " " << trect.right() << " " << trect.bottom() << std::endl;
173// vigra::Rect2D rect(trect.left() * wscale, trect.top() * hscale, trect.right() * wscale, trect.bottom() * hscale);
174// std::cerr << "outlines " << rect.left() << " " << rect.top() << " " << rect.right() << " " << rect.bottom() << std::endl;
175
177
179 DrawRect(rect.left(), rect.top(), rect.right(), rect.bottom(),false);
180 glEndList();
182 DrawRect(rect.left(), rect.top(), rect.right(), rect.bottom(),true, 4.0);
183 glEndList();
184
185 vigra::Rect2D roi = thelper->GetViewStatePtr()->GetOptions()->getROI();
187 DrawRect(roi.left(), roi.top(), roi.right(), roi.bottom(),false);
188 glEndList();
190 DrawRect(roi.left(), roi.top(), roi.right(), roi.bottom(),true, 2.0);
191 glEndList();
192
193 dirty_meshes = false;
194
195// std::cout << "outlines adi " << rect.left() << " " << rect.top() << " " << rect.right() << " " << rect.bottom() << std::endl;
196// std::cout << "outlines adi " << roi.left() << " " << roi.top() << " " << roi.right() << " " << roi.bottom() << std::endl;
197 }
198
200
203 DrawRect(rect.left(), rect.top(), rect.right(), rect.bottom(),true, 4.0);
204 glEndList();
205
206 vigra::Rect2D roi = thelper->GetViewStatePtr()->GetOptions()->getROI();
208 DrawRect(roi.left(), roi.top(), roi.right(), roi.bottom(),true, 2.0);
209 glEndList();
210
211 }
212
213
215
217 glColor4f(0, 0, 0, 0.50f);
220
221
222 glColor4f(1.0f, 1.0f, 1.0f, 0.20f);
225
226// std::cout << "outlines " << roi.left() << " " << roi.top() << " " << roi.right() << " " << roi.bottom() << std::endl;
227
228 glColor4f(1.0f, 1.0f, 1.0f, 0.66f);
231
233 glColor4f(0.8f, 0.8f, 0.8f, 0.5f);
235 glColor4f(0.8f, 0.8f, 0.8f, 0.6f);
237
240 glColor4f(1,1,1,1);
241
242}
243
244void OverviewOutlinesTool::DrawRect(double left, double top, double right, double bottom, bool outline, double line_width)
245{
246
247 vigra::Size2D size = thelper->GetVisualizationStatePtr()->GetOptions()->getSize();
248 double mlength = (size->y > size->x) ? size->y : size->x;
249
251
252 //since res was initially estimated for size of 360x100;
253 //TODO make res scale dependent
254 double tres = res * mlength / fov;
255 double tmindist = mindist * mlength / fov;
256
257// std::cerr << "outlines " << mlength << std::endl;
258// std::cerr << "outlines " << right << std::endl;
259
260 double safety = 1;
261 left += safety;
262 top += safety;
263 right -= safety;
264 bottom -= safety;
265
268// image.setSize(vigra::Size2D(360,180));
269 image.setSize(size);
270 image.setHFOV(fov);
274 break;
276 image.setProjection(HuginBase::BaseSrcPanoImage::RECTILINEAR);
277 break;
278 default:
279 DEBUG_ERROR("OverviewOutlinesTools: unknown projection")
280 break;
281 }
282
284
286
287 switch(proj) {
288
298
299 {
300
301 //in this case just the divide the base rectangle by a certain amount of steps
302
303 float steps = 40;
304
305 double wstep = (float)(right - left) / steps;
306 double hstep = (float)(bottom - top) / steps;
307
308 for(int w = 0 ; w < steps ; w++) {
309 for(int h = 0 ; h < steps ; h++) {
310
311 //if outline is needed just consider edge cases
312 if (outline) {
313 if (!(w == 0 || h == 0 || w == steps - 1 || steps - 1)) {
314 continue;
315 }
316 }
317
318 Rect rec(left + w * wstep, top + h * hstep, left + (w+1) * wstep, top + (h+1)* hstep);
319 Rect tr = rec.transformImgCoord(&transform);
320
321 //this section should be added to avoid certain problems with these projections
322 //(just disregard edges with lengths larger than some value with respect to the radius of the sphere)
323 //TODO this was commented when support for mosaic plane was added, make this work again
324 // 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]);
325 // 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]);
326 // 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]);
327 // 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]);
328
329// double maxlimit = (radius/2.0)*(radius/2.0);
330// if (
331// proj == HuginBase::PanoramaOptions::SINUSOIDAL ||
332// proj == HuginBase::PanoramaOptions::ALBERS_EQUAL_AREA_CONIC
333// )
334// if (edge1 > maxlimit || edge2 > maxlimit || edge3 > maxlimit || edge4 > maxlimit) {
335// continue;
336// }
337
338 if (outline) {
339
340// glBegin(GL_LINES);
341 bool edges[4] = {false,false,false,false};
342 if (w == 0) {
343 edges[0] = true;
344 }
345 if (w == steps - 1) {
346 edges[2] = true;
347 }
348 if (h == 0) {
349 edges[3] = true;
350 }
351 if (h == steps - 1) {
352 edges[1] = true;
353 }
354 for (int i = 0 ; i < 4 ; i++) {
355 if (edges[i]) {
356
357
358 //draw a line with the help of the GreatCircles class so that a mesh is drawn instead of just a line
359 int plus = i+1;
360 if (plus == 4) plus = 0;
361 hugin_utils::FDiff2D cd1(tr.val[i][0], tr.val[i][1]);
362 hugin_utils::FDiff2D cd2(tr.val[plus][0], tr.val[plus][1]);
364 line.vertices[0] = cd1;
365 line.vertices[1] = cd2;
367
368
369// for (int j = 0 ; j < 2 ; j++) {
370// int plus = i+j;
371// if (plus == 4) plus = 0;
372// double x,y,z;
373// double tx,ty;
374// tx = tr.val[plus][0];
375// ty = tr.val[plus][1];
381// hugin_utils::FDiff2D cd(tx,ty);
382// MeshManager::MeshInfo::Coord3D coord = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd);
383// glVertex3f(coord.x,coord.y,coord.z);
384// }
385
386 }
387 }
388// glEnd();
389
390 } else {
391
392 //in this case draw the mesh
393
394 #ifdef WIREFRAME
396 #else
398 #endif
399 for (int s = 0 ; s < 4 ; s++) {
400 double tx,ty;
401 tx = tr.val[s][0];
402 ty = tr.val[s][1];
403// ty = ty - 90;
404// tx = tx - 180;
405// ty *= -1;
409 }
410 glEnd();
411
412 }
413
414 }
415 }
416
417 }
418
419 break;
420
434
435 //stack to keep the rectangles to be divided
436 std::vector<Rec> stack;
437
438 stack.push_back(Rec(left,top,right,bottom));
439 //if outline needs to be obtained, after each rectangle another rectangle is pushed back
440 if (outline) {
441 stack.push_back(Rec(true, true, true, true));
442 }
443
444 while(!stack.empty()) {
445
446 Rec edge;
447 if (outline) {
448 edge = stack[stack.size() - 1];
449 stack.pop_back();
450 }
451
452 Rec top_rec = stack[stack.size() - 1];
453 stack.pop_back();
454
455 if (outline) {
456 if (!(edge.left || edge.top || edge.right || edge.bottom )) {
457 continue;
458 }
459 }
460
461 Rect rect(top_rec.left, top_rec.top, top_rec.right, top_rec.bottom);
462
463 Rect tr = rect.transformImgCoord(&transform);
464
465 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]);
466 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]);
467 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]);
468 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]);
469
470// std::cout << "outlines " << top_rec.left << " " << top_rec.top << " " << top_rec.right << " " << top_rec.bottom << std::endl;
471// std::cout << "outlines " << edge1 << " " << edge2 << " " << edge3 << " " << edge4 << std::endl;
472
473// std::cout << "outlines " << tr.val[0][0] << " " << tr.val[0][1] << std::endl;
474// std::cout << "outlines " << tr.val[1][0] << " " << tr.val[1][1] << std::endl;
475// std::cout << "outlines " << tr.val[2][0] << " " << tr.val[2][1] << std::endl;
476// std::cout << "outlines " << tr.val[3][0] << " " << tr.val[3][1] << std::endl;
477
478 double ressq = tres * tres;
479
480 bool divide_ver = false;
481 bool divide_hor = false;
482
483 //decide whether to divide the current rectangle
484 if (
485 (edge1 > ressq || edge3 > ressq)
486 &&
487 std::abs(top_rec.top - top_rec.bottom) > tmindist
488 ) {
489
490 divide_ver = true;
491
492 } else if (
493 (edge2 > ressq || edge4 > ressq)
494 &&
495 std::abs(top_rec.left - top_rec.right) > tmindist
496 ) {
497
498 divide_hor = true;
499
500 }
501
502 if (divide_ver) {
503
504 stack.push_back(Rec(top_rec.left,top_rec.top,top_rec.right,(top_rec.top+top_rec.bottom)/2.0));
505 if (outline) {
506 stack.push_back(Rec(edge.left, edge.top, edge.right, false));
507 }
508 stack.push_back(Rec(top_rec.left,(top_rec.top+top_rec.bottom)/2.0,top_rec.right,top_rec.bottom));
509 if (outline) {
510 stack.push_back(Rec(edge.left, false, edge.right, edge.bottom));
511 }
512 }
513
514 if (divide_hor) {
515
516 stack.push_back(Rec(top_rec.left,top_rec.top,(top_rec.left+top_rec.right)/2.0,top_rec.bottom));
517 if (outline) {
518 stack.push_back(Rec(edge.left, edge.top, false, edge.bottom));
519 }
520 stack.push_back(Rec((top_rec.left+top_rec.right)/2.0,top_rec.top,top_rec.right,top_rec.bottom));
521 if (outline) {
522 stack.push_back(Rec(false, edge.top, edge.right, edge.bottom));
523 }
524
525 }
526
527 if (!(divide_ver || divide_hor)) {
528
529 //draw it
530
531 if (outline) {
532// glBegin(GL_LINES);
533 bool edges[4];
534 edges[0] = edge.left!=0;
535 edges[1] = edge.bottom!=0;
536 edges[2] = edge.right!=0;
537 edges[3] = edge.top!=0;
538 for (int i = 0 ; i < 4 ; i++) {
539 if (edges[i]) {
540// std::cout << "outlines line!!" << i << "\n";
541// std::cout << "outlines " << top_rec.left << " " << top_rec.top << " " << top_rec.right << " " << top_rec.bottom << std::endl;
542
543 int plus = i+1;
544 if (plus == 4) plus = 0;
545 hugin_utils::FDiff2D cd1(tr.val[i][0], tr.val[i][1]);
546 hugin_utils::FDiff2D cd2(tr.val[plus][0], tr.val[plus][1]);
548 line.vertices[0] = cd1;
549 line.vertices[1] = cd2;
551
552// MeshManager::MeshInfo::Coord3D coord1 = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd1);
553// MeshManager::MeshInfo::Coord3D coord2 = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd2);
554// glVertex3f(coord1.x,coord1.y,coord1.z);
555// glVertex3f(coord2.x,coord2.y,coord2.z);
556
557
558// for (int j = 0 ; j < 2 ; j++) {
559// int plus = i+j;
560// if (plus == 4) plus = 0;
561// double x,y,z;
562// double tx,ty;
563// tx = tr.val[plus][0];
564// ty = tr.val[plus][1];
568
569//
570// hugin_utils::FDiff2D cd(tx,ty);
571// MeshManager::MeshInfo::Coord3D coord = thelper->GetVisualizationStatePtr()->GetMeshManager()->GetCoord3D(cd);
572// glVertex3f(coord.x,coord.y,coord.z);
573// }
574 }
575 }
576// glEnd();
577 } else {
578 #ifdef WIREFRAME
580 #else
582 #endif
583 for (int s = 0 ; s < 4 ; s++) {
584 double tx,ty;
585 tx = tr.val[s][0];
586 ty = tr.val[s][1];
587// ty = ty - 90;
588// tx = tx - 180;
589// ty *= -1;
593 }
594 glEnd();
595 }
596 }
597
598 }
599
600 break;
601
602 }
603
604}
605
606
607
Declare GreatCircles class.
A wxWidget to display the fast preview.
Definition GLViewer.h:52
VisualizationState * m_visualization_state
Definition GLViewer.h:71
Holds transformations for Image -> Pano and the other way.
void createTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
initialize pano->image transformation
const vigra::Rect2D & getROI() const
PanoramaOptions::ProjectionFormat getProjection() const
ProjectionFormat
Projection of final panorama.
vigra::Size2D getSize() const
get size of output image
Model for a panorama.
Definition Panorama.h:153
void addObserver(PanoramaObserver *o)
add a panorama observer.
All variables of a source image.
void setSize(vigra::Size2D val)
Set the image size in pixels.
a class to handle a 3D point
Definition MeshManager.h:94
virtual MeshInfo::Coord3D GetCoord3D(hugin_utils::FDiff2D &)=0
class to represent a single rectangle
Rect transformImgCoord(HuginBase::PTools::Transform *trans)
transform the rectangle's coordinates with a certain transform
OverviewOutlinesTool(ToolHelper *, GLViewer *preview)
unsigned int display_list_number_canvas_outline
virtual void panoramaChanged(HuginBase::Panorama &pano)
Notification about a Panorama change.
unsigned int display_list_number_crop
unsigned int display_list_number_crop_outline
unsigned int display_list_number_canvas
virtual void drawBackground()
drawing the background means drawing a mesh that covers the whole panorama for the purpose of darkeni...
void DrawRect(double left, double top, double right, double bottom, bool outline, double linewidth=1.0)
static const double mindist
static const double res
void Activate() override
Switch on a tool.
void drawBackground() override
drawing the background means drawing a mesh that covers the whole panorama for the purpose of darkeni...
void AfterDrawImagesFrontEvent() override
Draw using opengl anything after drawing the back face culled images.
void AfterDrawImagesBackEvent() override
Draw using opengl anything after drawing the front face culled images.
void drawBackground() override
drawing the background means drawing a mesh that covers the whole panorama for the purpose of darkeni...
void AfterDrawImagesEvent() override
Draw (using OpenGL) images above the others.
void Activate() override
Switch on a tool.
HuginBase::Panorama * GetPanoramaPtr()
void NotifyMe(Event event, Tool *tool)
ViewState * GetViewStatePtr()
VisualizationState * GetVisualizationStatePtr()
@ DRAW_OVER_IMAGES
Definition ToolHelper.h:82
ToolHelper * helper
The PreviewToolHelper that uses the same preview window and panorama as the tool should.
Definition Tool.h:109
HuginBase::PanoramaOptions * GetOptions()
MeshManager * GetMeshManager()
Definition ViewState.h:207
vigra::Rect2D GetVisibleArea()
Definition ViewState.h:222
virtual HuginBase::PanoramaOptions * GetOptions()
bool RequireRecalculateViewport()
#define DEBUG_ERROR(msg)
Definition utils.h:76
hugin_utils::FDiff2D vertices[2]
void doGL(double width, VisualizationState *state, LineSegment *preceding=NULL, LineSegment *proceeding=NULL) const
Draw a meshed line.
Rec(double left, double top, double right, double bottom)
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41