1 // -*- c-basic-offset: 4 -*-
2 /** @file PreviewLayoutLinesTool.h
3  *
4  *  @author James Legg
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 #ifndef PREVIEW_LAYOUT_LINES_TOOL_H
23 #define PREVIEW_LAYOUT_LINES_TOOL_H
24 
25 #include "Tool.h"
26 #include <vector>
27 #include <hugin_math/hugin_math.h>
28 #include "GreatCircles.h"
29 
30 class GLPreviewFrame;
31 
32 /** The PreviewLayoutLinesTool handles the lines connecting images in the layout
33  * view of the fast preview.
34  *
35  * These are its functions:
36  * -# Draw the coloured lines indicating control point error behind the images.
37  * -# Draw the grey lines for images overlapping that share no control points.
38  * -# Interprate clicks on lines and load up the relevant pair in the control
39  *    point tab.
40  * .
41  *
42  * @todo Update line information when control point information changes, and
43  * only when it changes. The main preview system doesn't redraw when control
44  * points change. This should save on the draw time, since we don't always
45  * need to examine the control points to draw the preview.
46  */
47 class PreviewLayoutLinesTool : public Tool, public HuginBase::PanoramaObserver
48 {
49 public:
50     explicit PreviewLayoutLinesTool(ToolHelper *helper);
51     ~PreviewLayoutLinesTool();
52 
53     /** This just sets a flag when the panorama is changed.
54      * When we next redraw, we recalculate the statistics for the lines if the
55      * flag is set.
56      */
57     void panoramaChanged(HuginBase::Panorama &pano);
58     void panoramaImagesChanged(HuginBase::Panorama&, const HuginBase::UIntSet&);
59 
60     /// Start using the PreviewLayoutLinesTool.
61     void Activate();
62 
63     /** Revaluate the lines under the mouse pointer when it moves.
64      */
65     virtual void MouseMoveEvent(double x, double y, wxMouseEvent & e);
66 
67     /** Capture clicks on lines, and load up the relavent images in the control
68      * point tab.
69      */
70     void MouseButtonEvent(wxMouseEvent & e);
71 
72     /** Draw all the lines between images that indicate the quality and quantity
73      * of control points.
74      */
75     void BeforeDrawImagesEvent();
76 
77     bool BeforeDrawImageEvent(unsigned int image);
78 
79     /** Draw a border over the images when a line is hilighted, similar to the
80      * identify tool.
81      */
82     void AfterDrawImagesEvent();
83 private:
84 
85     //user has clicked and is holding left button while near a line
86     bool m_holdOnNear;
87 
88     /// Flag set to true to update statistics next redraw
89     bool m_updateStatistics;
90     /// OpenGL texture names for the border highlight.
91     unsigned int m_rectangleBorderTex;
92 
93     /// The location on the panorama that the middle of the images map to.
94     std::vector<hugin_utils::FDiff2D> m_imageCentres;
95 
96     /// The spherical coordinates of the middle of the images.
97     std::vector<hugin_utils::FDiff2D> m_imageCentresSpherical;
98 
99     /// The transformations used to make the image centres.
100     std::vector<HuginBase::PTools::Transform *> m_transforms;
101 
102 
103     /** A class to store information about each line that will be drawn.
104      */
105     class LineDetails
106     {
107     public:
108         /// index of images for this line
109         unsigned int image1, image2;
110         LineDetails();
111         /// the number of control points between these images
112         unsigned int numberOfControlPoints;
113         /// the error of the control point with the greatest error between these images
114         double worstError;
115         /// the total of all the control point errors between these images
116         double totalError;
117         /** false if the line should be used, true if it shouldn't.
118          * A dud image is not drawn, and should never be the nearest line to the
119          * mouse.
120          */
121         bool dud;
122 
123         GreatCircleArc arc;
124 
125         /** Draw a line in the preview for this pair of images.
126          *
127          * If the line is a dud, no line is drawn.
128          *
129          * - It is coloured grey and 1 pixel thick if there are no control points.
130          * - The width of the line is max {1 px + NumberOfControlPoints / 5, 5}.
131          * - The colour of a line with control points is dependant on the maximum
132          * error and selection:
133          *   - Red if the error is greater than or equal to 20.
134          *   - Red - Orange - Yellow if the error is between 5 and 20
135          *   - Yellow - Green if the error is less than 5.
136          *   - All lines are drawn white instead if it is the selected line.
137          * @param highlight Prelight for nearest line. Draws the line white when
138          * true, otherwise use a colour based on error.
139          */
140         void draw(bool highlight);
141 
142         /** Get the square of the distance from the arc to some panorama coordinate.
143          * The point is normally the mouse location in the panorama.
144          */
145         float getDistance(hugin_utils::FDiff2D point);
146     };
147 
148     /// A container for the line information.
149     std::vector<LineDetails> m_lines;
150 
151     /// The index of nearest line to the mouse position
152     unsigned int m_nearestLine;
153 
154     /// True if we should highlight the nearest line to the mouse position.
155     bool m_useNearestLine;
156 
157     /// Update the line information
158     void updateLineInformation();
159 
160     /// Update the locations of the image centres.
161     void updateImageCentres();
162 
163     /// Draw a border for an image.
164     void drawIdentificationBorder(unsigned int image);
165 };
166 
167 #endif
168 
169