Hugin trunk 0.1
Loading...
Searching...
No Matches
ImageVariableGroup.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
24#include <hugin_utils/utils.h>
25
26#include "ImageVariableGroup.h"
27
28namespace HuginBase
29{
30
31ConstImageVariableGroup::ConstImageVariableGroup(std::set<ImageVariableEnum> variables,
32 const PanoramaData & pano)
33 : m_variables (variables),
34 m_pano (pano)
35{
36 // work out the initial image number to part number matching.
38}
39
43
44unsigned int ConstImageVariableGroup::getPartNumber(unsigned int imageNr) const
45{
46 DEBUG_ASSERT(imageNr < m_image_part_numbers.size());
48 return m_image_part_numbers[imageNr];
49}
50
52{
54 for (unsigned int imgNr = 0; imgNr<m_image_part_numbers.size(); ++imgNr)
55 {
56 result[m_image_part_numbers[imgNr]].insert(imgNr);
57 };
58 return result;
59}
60
62 std::size_t part) const
63{
64 /* Variables can be linked in strange ways, but this ignores most of that.
65 * For the sake of the user interface, a variable should be linked across
66 * all images in the part, or not linked across any images in a part. This
67 * function returns true in the first case and false in the second, but is
68 * a bit weird about any other cases:
69 * If the first image in the part has links in this variable, true is
70 * returned.
71 * If the second image in the part has no links in this variable, false is
72 * returned.
73 * If there is only one image in this part, true is returned.
74 * This is just to make it fast. We could check explicitly for one of the
75 * cases above, but they are probably all that is used.
76 */
77
78 // Have we found a unlinked image previously?
79 bool found_first = false;
80 switch (variable)
81 {
82#define image_variable( name, type, default_value )\
83 case IVE_##name:\
84 for (std::size_t imageNr = 0; imageNr < m_pano.getNrOfImages(); imageNr++)\
85 {\
86 if (m_image_part_numbers[imageNr] == part)\
87 {\
88 if (!found_first)\
89 {\
90 found_first = true;\
91 if (m_pano.getImage(imageNr).name##isLinked())\
92 {\
93 return true;\
94 }\
95 } else {\
96 return false;\
97 }\
98 }\
99 }\
100 break;
101#include "image_variables.h"
102#undef image_variable
103 }
104 // only one image found:
105 return true;
106}
107
109 unsigned int partNr)
110{
112 // find all images in the requested part.
113 for (unsigned int i = 0; i < m_image_part_numbers.size(); i++)
114 {
116 {
117 // unlink the variable
118 switch (variable)
119 {
120#define image_variable( name, type, default_value )\
121 case IVE_##name:\
122 m_pano.unlinkImageVariable##name(i);\
123 break;
124#include "image_variables.h"
125#undef image_variable
126 }
127 }
128 }
130}
131
137
139 unsigned int partNr)
140{
142 // find all images in the requested part.
143 bool found_first_image = false;
145 for (unsigned int i = 0; i < m_image_part_numbers.size(); i++)
146 {
148 {
149 // make a note of the first image.
151 {
153 found_first_image = true;
154 continue;
155 }
156 // for the other images, link the variable to the first image.
157 switch (variable)
158 {
159#define image_variable( name, type, default_value )\
160 case IVE_##name:\
161 m_pano.linkImageVariable##name(first_image_number, i);\
162 break;
163#include "image_variables.h"
164#undef image_variable
165 }
166 }
167 }
169}
170
176
177void ImageVariableGroup::switchParts (unsigned int imageNr, unsigned int partNr)
178{
179 if (partNr == m_image_part_numbers[imageNr])
180 {
181 // We're asked to switch an image to its own part, achieving nothing:
182 return;
183 }
184 DEBUG_TRACE("Switching image " << imageNr << " to part " << partNr);
185 if (partNr > m_num_parts)
186 {
187 DEBUG_ERROR( "Request to switch an image to a nonexistent part." );
188 return;
189 }
190 // find an image in this part.
191 unsigned int part_image_index;
193
194 // Decide which variables to link.
195 // Find which variables are linked in the other image.
196 std::set<ImageVariableEnum> linked_variables;
197 for(std::set<ImageVariableEnum>::iterator i = m_variables.begin(); i != m_variables.end(); ++i)
198 {
199 switch (*i)
200 {
201#define image_variable( name, type, default_value ) \
202 case IVE_##name: \
203 if(m_pano.getImage(part_image_index).name##isLinked())\
204 {\
205 linked_variables.insert(IVE_##name);\
206 }\
207 break;
208#include "image_variables.h"
209#undef image_variable
210 }
211 }
212
213 // If none share links, link them all. The image must be the only one of its
214 // part.
215 bool singular = linked_variables.empty();
216 if (singular)
217 {
219 }
220
221 // unlink the image from the part it originally was part off.
222 for(std::set<ImageVariableEnum>::iterator i = m_variables.begin(); i != m_variables.end(); ++i)
223 {
224 switch (*i)
225 {
226#define image_variable( name, type, default_value ) \
227 case IVE_##name: \
228 m_pano.unlinkImageVariable##name(imageNr);\
229 break;
230#include "image_variables.h"
231#undef image_variable
232 }
233 }
234
235 // link the variables
236 for(std::set<ImageVariableEnum>::iterator i = linked_variables.begin(); i != linked_variables.end(); ++i)
237 {
238 switch (*i)
239 {
240 /* part_image_index and imageNr must be different, since if they
241 * were the same, the image would have already been in the
242 * correct part. This was the first thing we checked.
243 */
244#define image_variable( name, type, default_value ) \
245 case IVE_##name: \
246 m_pano.linkImageVariable##name(part_image_index, imageNr);\
247 break;
248#include "image_variables.h"
249#undef image_variable
250 }
251 }
252
253 // Changing the links inherits variable values from the new lens, so the
254 // variable values may have changed and the linking certainly has.
255 m_pano.imageChanged(imageNr);
256
257 // update the mapping of image numbers to part numbers.
259}
260
262{
263 return m_num_parts;
264}
265
270
272{
273 DEBUG_TRACE("")
274 // Find links.
275 m_image_part_numbers.clear();
276 if (m_pano.getNrOfImages() == 0)
277 {
278 // no images.
279 m_num_parts = 0;
280 return;
281 }
282 /* We will keep a list of parts, containing the image number of the first
283 * image that uses that part. When we want to find if another image is in
284 * a part, we can then check if it is linked to any images in the list.
285 */
286 std::vector<std::size_t> parts_first_image;
287 // image 0 always has part 0
288 parts_first_image.push_back(0);
289 m_image_part_numbers.push_back(0);
290 for (std::size_t i = 1; i < m_pano.getNrOfImages(); i++)
291 {
292 // find a part for this image.
293 /* We use parts_first_image.size() as a flag to determine when the
294 * images is not linked to any part we have previously found, as it
295 * will be the part number when we are done. */
296 std::size_t part_number = parts_first_image.size();;
297 for (std::size_t j = 0; j < parts_first_image.size(); j++)
298 {
299 // check each variable in the group
300 for (std::set<ImageVariableEnum>::const_iterator k = m_variables.begin();
301 (k != m_variables.end()) && (part_number != j); ++k)
302 {
303 switch (*k)
304 {
308#define image_variable( name, type, default_value ) \
309 case IVE_##name:\
310 if (m_pano.getImage(i).name##isLinkedWith(m_pano.getImage(parts_first_image[j]))) \
311 part_number = j;\
312 break;
313#include "image_variables.h"
314#undef image_variable
315 }
316 }
317 }
318 // We should have a suitable part number for now.
320 // If this is a new part, keep this image number to check links.
321 if (part_number == parts_first_image.size())
322 {
323 parts_first_image.push_back(i);
324 }
325 }
326 // set the number of parts
328
329}
330
331} // HuginBase namespace
Declare the ImageVariableGroup and ImageVariableGroupObserver classes.
std::size_t getNumberOfParts() const
get the number of parts.
void setPartNumbers()
Set the part numbers in m_image_part_numbers, and notify observers of changes.
void updatePartNumbers()
Update the part numbers, call this when the panorama changes.
bool getVarLinkedInPart(ImageVariableEnum variable, std::size_t part) const
Get the linked status of a particular variable for a given part number.
ConstImageVariableGroup(std::set< ImageVariableEnum > variables, const PanoramaData &pano)
constructor
unsigned int getPartNumber(unsigned int imageNr) const
Get a part number from an image number.
std::vector< unsigned int > m_image_part_numbers
The part numbers for each image.
UIntSetVector getPartsSet() const
return a vector which contains a HuginBase::UIntSet for each group with the corresponding images numb...
const PanoramaData & m_pano
The panorama this group works on.
std::set< ImageVariableEnum > m_variables
The set of variables which make up this group.
void switchParts(unsigned int ImageNr, unsigned int partNr)
switch a given image to a different part number.
void unlinkVariableImage(ImageVariableEnum variable, unsigned int imageNr)
unlink one the variables across the part containing a given image.
void unlinkVariablePart(ImageVariableEnum variable, unsigned int partNr)
unlink one of the variables across a given part.
void linkVariableImage(ImageVariableEnum variable, unsigned int imageNr)
link one of the variables across a part containing a given image
void linkVariablePart(ImageVariableEnum variable, unsigned int partNr)
link one of the variables across a given part
Model for a panorama.
virtual void imageChanged(unsigned int imgNr)=0
mark image change for maintainance
virtual std::size_t getNrOfImages() const =0
number of images.
#define DEBUG_ERROR(msg)
Definition utils.h:76
#define DEBUG_ASSERT(cond)
Definition utils.h:80
#define DEBUG_TRACE(msg)
Definition utils.h:67
This file specifies what image variables SrcPanoImg should have.
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
Definition wxcms.cpp:39
std::vector< UIntSet > UIntSetVector
std::set< unsigned int > UIntSet
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