1 // -*- c-basic-offset: 4 -*-
2 /** @file PanoramaData.h
3  *
4  *  @author Pablo d'Angelo <pablo.dangelo@web.de>
5  *
6  *  $Id$
7  *
8  * !! from Panorama.h 1947
9  *
10  *  This is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2 of the License, or (at your option) any later version.
14  *
15  *  This software is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public
21  *  License along with this software. If not, see
22  *  <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #ifndef _PANORAMA_H
27 #define _PANORAMA_H
28 
29 // if this file is preprocessed for SWIG, we want to ignore
30 // all the header inclusions that follow:
31 
32 #ifndef _HSI_IGNORE_SECTION
33 
34 #include <hugin_shared.h>
35 #include <vector>
36 #include <set>
37 #include <iostream>
38 
39 #include <hugin_math/Matrix3.h>
40 #include <panodata/PanoramaVariable.h>
41 #include <panodata/SrcPanoImage.h>
42 #include <panodata/ControlPoint.h>
43 #include <panodata/Lens.h>
44 #include <panodata/PanoramaOptions.h>
45 
46 #endif // _HSI_IGNORE_SECTION
47 
48 namespace HuginBase {
49 
50 ///
51 typedef std::set<unsigned int> UIntSet;
52 
53 ///
54 typedef std::vector<unsigned int> UIntVector;
55 
56 typedef std::vector<UIntSet> UIntSetVector;
57 
58 /** Model for a panorama.
59  *
60  *  This class contains the properties of a panorama
61  *  That is:
62  *       - images
63  *       - variables that can be optimized.
64  *       - links between image variables
65  *       - control points
66  *       - properites of the output panorama.
67  *
68  *  view and controller classes can get information about these
69  *  with the getXXX Functions.
70  *
71  *  Images and Control points are numbered, and const references are
72  *  handed out.  this means that all interaction will be based on
73  *  image or control point numbers. The references are not stable,
74  *  they might disappear when other functions of this class are
75  *  called, so its best to get a new reference whenever you need the object.
76  *
77  *  This also means that the whole object is not threadsafe and concurrent
78  *  access has to be synchronized from the outside.
79  *
80  */
81 class IMPEX PanoramaData
82 {
83 
84 public:
85 
86     ///
~PanoramaData()87     virtual ~PanoramaData() {};
88 
89 
90     /* get a subset of the panorama
91     *
92     *  This returns a panorama that contains only the images specified by \imgs
93     *  Useful for operations on a subset of the panorama
94     */
95 //  virtual Panorama getSubset(const UIntSet& imgs) const;
96 
97     /* duplicate the panorama
98     *
99     *  returns a copy of the pano state, except for the listeners.
100     */
101 //  virtual Panorama duplicate() const;
102 
103     ///
104     virtual PanoramaData* getNewSubset(const UIntSet& imgs) const =0;
105 
106     ///
107     virtual PanoramaData* getNewCopy() const =0;
108 
109     virtual PanoramaData* getUnlinkedSubset(UIntSetVector& imageGroups) const = 0;
110 
111 // -- Data Access --
112 
113 // = images =
114 
115     /// number of images.
116     virtual std::size_t getNrOfImages() const =0;
117 
118     /// get a panorama image, counting starts with 0
119     virtual const SrcPanoImage& getImage(std::size_t nr) const =0;
120 
121     /// set a panorama image, counting starts with 0
122     virtual void setImage(std::size_t nr, const SrcPanoImage & img) =0;
123 
124     /// the the number for a specific image
125 //    virtual unsigned int getImageNr(const PanoImage * image) const =0;
126 
127     /** add an Image to the panorama
128     *
129     *  The Image must be initialized, the Lens must exist.
130     *
131     */
132     virtual unsigned int addImage(const SrcPanoImage& img) =0;
133 
134     /** creates an image, from filename, and a Lens, if needed */
135 //    virtual int addImageAndLens(const std::string & filename) =0;
136 
137     /** add an Image to the panorama
138     *  @return image number
139     */
140 //  virtual unsigned int addImage(const std::string & filename) =0;
141 
142     /** remove an Image.
143         *
144         *  also deletes/updates all associated control points.
145         */
146     virtual void removeImage(unsigned int nr) =0;
147 
148     /** swap images.
149         *
150         *  swaps the images, image @p img1 becomes @p img2 and the other way round
151         */
152     virtual void swapImages(unsigned int img1, unsigned int img2) =0;
153 
154     /** moves images.
155         *
156         * moves the image from pos1 to pos2
157         */
158     virtual void moveImage(size_t img1, size_t img2) =0;
159 
160     /// get a complete description of a source image
161     virtual SrcPanoImage getSrcImage(unsigned imgNr) const =0;
162 
163     /** set input image parameters
164      * TODO: Propagate changes to linked images.
165     */
166     virtual void setSrcImage(unsigned int nr, const SrcPanoImage & img) =0;
167 
168     /** set a new image filename
169     *
170     *  It is assumed that it is of the same size
171     *  as the old image.
172     *
173     */
174     virtual void setImageFilename(unsigned int img, const std::string & fname) =0;
175 
176     /** mark an image as active or inactive.
177     *
178     *  This is only a flag, that can be turned on or off.
179     *  If an image is marked active, then it should
180     *  be used for optimizing and stitching.
181     *
182     *  However, this is not done automatically. One has
183     *  to use getActiveImages() to get the numbers of the
184     *  active images, and pass these to the respective
185     *  functions that do the stitching or optimisation
186     */
187     virtual  void activateImage(unsigned int imgNr, bool active=true) =0;
188 
189     /** get active images */
190     virtual  UIntSet getActiveImages() const =0;
191 
192         /* Link image variable functions. Used to group image variables which
193          * should share the same value. The initial value is the one kept by
194          * the image with number sourceImgNr.
195          */
196 #define image_variable( name, type, default_value ) \
197         virtual void linkImageVariable##name(unsigned int sourceImgNr, unsigned int destImgNr) =0;
198 #include "image_variables.h"
199 #undef image_variable
200 
201         /* Unlink image variable functions. Makes a image variable independant
202          * of the other images.
203          */
204 #define image_variable( name, type, default_value ) \
205         virtual void unlinkImageVariable##name(unsigned int imgNr) =0;
206 #include "image_variables.h"
207 #undef image_variable
208 
209 
210 // = CPs =
211 
212     /// number of control points
213     virtual  std::size_t getNrOfCtrlPoints() const =0;
214 
215     /// get a control point, counting starts with 0
216     virtual const ControlPoint & getCtrlPoint(std::size_t nr) const =0;
217 
218     /// get all control point of this Panorama
219     virtual const CPVector & getCtrlPoints() const =0;
220 
221     /** return all control points for a given image. */
222     virtual std::vector<unsigned int> getCtrlPointsForImage(unsigned int imgNr) const =0;
223 
224     /** set all control points (Ippei: Is this supposed to be 'add' method?) */
225     virtual void setCtrlPoints(const CPVector & points) =0;
226 
227     /** add a new control point.*/
228     virtual unsigned int addCtrlPoint(const ControlPoint & point) =0;
229 
230     /** remove a control point.
231     */
232     virtual void removeCtrlPoint(unsigned int pNr) =0;
233 
234     /** removes duplicates control points
235         */
236     virtual void removeDuplicateCtrlPoints() =0;
237 
238     /** change a control Point.
239     */
240     virtual void changeControlPoint(unsigned int pNr, const ControlPoint & point) =0;
241 
242     /// get the number of a control point
243 //  virtual unsigned int getCtrlPointNr(const ControlPoint * point) const =0;
244 
245     /** get the next unused line number for t3, ... control point creation */
246     virtual int getNextCPTypeLineNumber() const =0;
247 
248     /** assign new mode line numbers, if required */
249     virtual void updateLineCtrlPoints() =0;
250 
251 
252     /** update control points distances.
253     *
254     *  updates control distances and position in final panorama
255     *  usually used to set the changes from the optimization.
256     *  The control points must be the same as in
257     */
258     virtual void updateCtrlPointErrors(const CPVector & controlPoints) =0;
259 
260     /** update control points for a subset of images.
261     *
262     *  Usually, the control point subset is created using subset()
263     *  The number and ordering and control points must not be changed
264     *  between the call to subset() and this function.
265     */
266     virtual void updateCtrlPointErrors(const UIntSet & imgs, const CPVector & cps) =0;
267 
268 // = Variables =
269 /*   TODO most of this section needs fixing. The image variables are now stored
270  *        in SrcPanoImage objects, the PanoramaData object should just duplicate
271  *        the changes across all images sharing variables.
272  *        We also need access to the links of the variables.
273  *        At some point, this functions should be removed. Do not create new
274  *        code using them. Instead, use getSrcImage.
275  */
276     /// get variables of this panorama
277     virtual VariableMapVector getVariables() const =0;
278 
279     /** get variables of an image
280     *
281     *   Depreciated: Please use SrcPanoImage objects for variable access.
282     *
283     * @todo remove when not used.
284     *
285     * Note: no longer returns a reference as the no variable map with the
286     * correct values exists, now we use individual member variables in
287     * SrcPanoImage.
288     */
289     virtual const VariableMap getImageVariables(unsigned int imgNr) const =0;
290 
291     /** Set the variables.
292     *
293     *  Usually used when the optimizer results should be applied.
294     *
295     */
296     virtual void updateVariables(const VariableMapVector & vars) =0;
297 
298     /** update variables for some specific images */
299     virtual void updateVariables(const UIntSet & imgs, const VariableMapVector & var) =0;
300 
301     /** Set variables for a single picture.
302     *
303     */
304     virtual void updateVariables(unsigned int imgNr, const VariableMap & var) =0;
305 
306     /** update a single variable
307     *
308     *  It updates other images when the variable is linked
309     */
310     virtual void updateVariable(unsigned int imgNr, const Variable &var) =0;
311 
312     /** update the global white balace of the panorama by multiplying
313      * the red and blue factor of each image with given factors
314      */
315     virtual void updateWhiteBalance(double redFactor, double blueFactor) =0;
316 
317 // = Optimise Vector =
318 
319     /** return the optimize settings stored inside panorama */
320     virtual const OptimizeVector & getOptimizeVector() const =0;
321 
322     /** set optimize setting */
323     virtual void setOptimizeVector(const OptimizeVector & optvec) =0;
324 
325 
326     /** returns optimizer master switch */
327     virtual const int getOptimizerSwitch() const =0;
328     /** set optimizer master switch */
329     virtual void setOptimizerSwitch(const int newSwitch) =0;
330 
331     /** return the photometric optimizer master switch */
332     virtual const int getPhotometricOptimizerSwitch() const =0;
333     /** sets the photometric optimizer master switch */
334     virtual void setPhotometricOptimizerSwitch(const int newSwitch) =0;
335 
336 // = Panorama options =
337 
338     /** returns the options for this panorama */
339     virtual const PanoramaOptions & getOptions() const =0;
340 
341     /** set new output settings
342      *  This is not used directly for optimizing/stiching, but it can
343      *  be feed into runOptimizer() and runStitcher().
344      */
345     virtual void setOptions(const PanoramaOptions & opt) =0;
346 
347 
348 
349 // -- script interface --
350 
351    /** read after optimization, fills in control point errors.
352     *
353     *  @param set of image numbers that where used during by
354     *         printPanoramaScript().
355     *  @param vars will be set the the optimzied variables
356     *  @param ctrlPoints will contain the controlpoints, with distance
357     *         information
358     *
359     *  @return false on error (could not read optimizer output, parse error)
360     */
361     virtual void parseOptimizerScript(std::istream & i,
362                               const UIntSet & imgs,
363                               VariableMapVector & imgVars,
364                               CPVector & ctrlPoints) const =0;
365 
366     /// create an optimizer script
367     virtual void printPanoramaScript(std::ostream & o,
368                              const OptimizeVector & optvars,
369                              const PanoramaOptions & options,
370                              const UIntSet & imgs,
371                              bool forPTOptimizer,
372                              const std::string & stripPrefix="") const =0;
373 
374     /// create the stitcher script
375     virtual void printStitcherScript(std::ostream & o,
376                              const PanoramaOptions & target,
377                              const UIntSet & imgs) const =0;
378 
379 
380 // -- maintainance --
381 
382 public:
383     /// tells the data container to perform some maintainance if neccesary
384     virtual void changeFinished() =0;
385 
386     /// mark image change for maintainance
387     virtual void imageChanged(unsigned int imgNr) =0;
388     /** set complete mask list for image with number */
389     virtual void updateMasksForImage(unsigned int imgNr, MaskPolygonVector newMasks)=0;
390     /** updates all active masks
391       *
392       * this is necessary after variables of *one* image has changed,
393       * because positive masks have to be updated
394       */
395     virtual void updateMasks(bool convertPosMaskToNeg=false)=0;
396     /** transfers given mask from image imgNr to all targetImgs
397         */
398     virtual void transferMask(MaskPolygon mask,unsigned int imgNr, const UIntSet& targetImgs)=0;
399     /** updates the optimize vector according to master switches */
400     virtual void updateOptimizeVector()=0;
401     /** returns set of reference image and images linked with reference images */
402     virtual std::set<size_t> getRefImages()=0;
403     /** checks if yaw/pitch/roll of reference image can be check,
404         * it depends on number and type of control points */
405     virtual void checkRefOptStatus(bool& linkRefImgsYaw, bool& linkRefImgsPitch, bool& linkRefImgsRoll)=0;
406 
407 };
408 
409 
410 
411 /** this handler class will receive change events from the Panorama.
412 *
413 *  Maybe a fine grained event interface is better, but it can be
414 *  added later.
415 */
416 class PanoramaObserver
417 {
418     public:
419 
420         ///
~PanoramaObserver()421         virtual ~PanoramaObserver() {};
422 
423         /** Notification about a Panorama change.
424         *
425         *  This function will always be called, even when the
426         *  change could be handled by panoramaImageAdded() or
427         *  other notify functions.
428         *
429         *  This allows lazy observers to just listen to
430         *  panoramaChanged().
431         *
432         */
433         virtual void panoramaChanged(Panorama &pano) =0;
434 
435         /** notifies about changes to images
436         *
437         *  Images might have been added/removed. to find out
438         *  how many images are still there, use Panorama::getNrOfImages.
439         *
440         *  @param pano the panorama object that changed
441         *  @param changed set of changed images
442         *
443         */
444         virtual void panoramaImagesChanged(Panorama& pano,
445                                            const UIntSet& changed) =0;
446 
447 
448 };
449 
450 
451 /** Memento class for a PanoramaData object
452 *
453 *  Preserves the internal state of a PanoramaData.
454 *  Used when other objects need to get/set the state without
455 *  knowing anything about the internals.
456 *
457 */
458 class IMPEX PanoramaDataMemento
459 {
460     protected:
461         /// force pure abstract behaviour
PanoramaDataMemento()462         PanoramaDataMemento() {};
463 
464     public:
465         ///
~PanoramaDataMemento()466         virtual ~PanoramaDataMemento() {};
467 };
468 
469 
470 ///
471 class IMPEX ManagedPanoramaData : public PanoramaData
472 {
473     public:
474 
475         ///
~ManagedPanoramaData()476         virtual ~ManagedPanoramaData() {};
477 
478 
479         // -- Observing --
480 
481     public:
482         /** add a panorama observer.
483         *
484         *  It will recieve all change messages.
485         *  An observer can only be added once. if its added twice,
486         *  the second addObserver() will have no effect.
487         */
488         virtual void addObserver(PanoramaObserver *o) =0;
489 
490         /** remove a panorama observer.
491         *
492         *  Observers must be removed before they are destroyed,
493         *  else Panorama will try to notify them after they have been
494         *  destroyed
495         *
496         *  @return true if observer was known, false otherwise.
497         */
498         virtual bool removeObserver(PanoramaObserver *observer) =0;
499 
500         /** remove all panorama observers.
501         *
502         *  @warning this is a hack. it must not be used on normal Panorama's.
503         */
504         virtual void clearObservers() =0;
505 
506         /** notify observers about changes in this class
507         *
508         *  This needs to be called explicitly by somebody after
509         *  changes have been made.
510         *  Allows to compress multiple changes into one notification.
511         */
512         virtual void changeFinished() =0;
513 
514         /** clear dirty flag. call after load, save or new project */
515         virtual void clearDirty() =0;
516 
517         /** mark image for change notification.
518         *
519         *  Does not send the notification, this is left
520         *  to changedFinished()
521         */
522         virtual void imageChanged(unsigned int imgNr) =0;
523 
524 
525         // -- Memento interface --
526 
527     public:
528         /// get the internal state
529         virtual PanoramaDataMemento* getNewMemento() const =0;
530 
531         /// set the internal state
532         virtual bool setMementoToCopyOf(const PanoramaDataMemento* const memento) =0;
533 
534 
535         // -- Optimization Status --
536 
537     public:
538         /** true if control points or lens variables
539         *  have been changed after the last optimisation
540         */
541         virtual bool needsOptimization() =0;
542 
543         ///
544         virtual void markAsOptimized(bool optimized=true) =0;
545 
546 };
547 
548 
549 } // namespace
550 
551 
552 
553 
554 #endif // _PANORAMA_H
555