model classes Re: wxWindows test

Pablo d'Angelo pablo.dangelo at web.de
Fri Apr 25 17:01:37 BST 2003


Hi!

On Fri, 25 Apr 2003, Juha Helminen wrote:

> I played a bit more with wxWindows to see how it works -- dialogs can be
> made and buttons connected to events... This
> http://www.nic.fi/~juhe/ptopengui/files/ example do not make anything
> usefull -- you can load project file (.pto) and can check if it is correct.
>
> I suppose that unix makefile works, it's not tested after last changes.
>
> Next step is to use data structures and read images. Do you have ideas
> how to devide project/GUI so that it's easier to maintain?

I have just reached a more or less useable  state on the project classes
(the thing I called model before).

Basically I've got a Panorama class that contains the whole panorama
state, images, image parameters, control points, lens settings etc.

it offers get/set methods to its images/control points etc.

whenever something in the model is changed, interested parties
(widgets that view some aspect of the model) will be notified, so that
they can update their view (by using the getXXX style acessor
functions).

If something need to be changed, this will go though command objects.

Command objects basically encapsulate one or more Panorama::setXXX
function calls. They also store enough information to undo the change.
when the command objects are used for all changes, it is easy to
implement an undo functionality.

my base command object:
---------------
    /** default panorama cmd, provides undo with mementos.
     */
    class PanoCommand : public Command
    {
    public:
        PanoCommand(Panorama & p)
            : pano(p)
            { };
        
        virtual ~PanoCommand()
            {
            };

        /** save the panorama state before our changes*/
        virtual void execute()
            {
                memento = pano.getMemento();
            };
            
        /** set the saved state. 
         *  
         *  the derived class must call PanoComand::execute() in its
         *  execute() method to save the state.
         */
        virtual void undo()
            {
                pano.setMemento(memento);
            }
        virtual std::string getName() const = 0;
    protected:
        Panorama & pano;
        PanoramaMemento memento;
    };
---------------


The following is an example how I can create an stitch two images with
my current model classes:

****************

    vector<Command*> cmds;  // this would be a history widget that
                            // allows the user to undo stuff, but this
                            // is jsut a test case from my test suite
                            // for the model

    // the command will be created by whatever widgets we have to
    // change the panorama.
    vector<string> images;
    images.push_back("pics/test1.jpg");
    images.push_back("pics/test2.jpg");
    cmds.push_back(new AddImagesCmd(pano,images));
    
    cmds.push_back(new AddCtrlPointCmd(pano, ControlPoint(0,621,534, 0,607,268, ControlPoint::X)));
    cmds.push_back(new AddCtrlPointCmd(pano, ControlPoint(0,1127,408, 1,210,377)));
    cmds.push_back(new AddCtrlPointCmd(pano, ControlPoint(0,1303,585, 1,387,559)));
    cmds.push_back(new AddCtrlPointCmd(pano, ControlPoint(0,1475,573, 1,551,546)));
    cmds.push_back(new AddCtrlPointCmd(pano, ControlPoint(0,1479,434, 1,557,413)));
    cmds.push_back(new AddCtrlPointCmd(pano, ControlPoint(0,988,405, 1,59,405)));
    cmds.push_back(new AddCtrlPointCmd(pano, ControlPoint(1,804,213, 1,814,394, ControlPoint::X)));

    // create optimier settings (default is to optimize y,r,p)
    OptimizeVector optSettings;
    optSettings.push_back(OptimizerSettings());
    optSettings.push_back(OptimizerSettings());
    // set output settings;
    PanoramaOptions output;
    output.outfile = "cmdtest.jpg";
    output.width = 1000;
    output.height = 500;
    output.HFOV = 130;
    output.projectionFormat = PanoramaOptions::CYLINDRICAL;

    cmds.push_back(new OptimizeCmd(pano, optSettings, output));
    
    cmds.push_back(new StitchCmd(pano, output));
    
    // execute all commands
    for (vector<Command*>::iterator it = cmds.begin(); it != cmds.end(); ++it) {
        DEBUG_DEBUG("executing cmd: " << (*it)->getName());
        (*it)->execute();
    }

***************

This creates the cmdtest.jpg image, and it looks actually really nice.

The GUI will be composed of multiple widget that can all display some
part of the Panorama model. for example a control point list view.

The listview will be part of the Control Point editor dialog. this
dialog will receive change events and remove/insert the control points
when the model is changed, or the user switches the images.

I'll finish writing the model thing and I'll put it into the hugin cvs
later.


The Panorama model will have a function to set/get the internal state
(as used by the command object above). This PanoramaMemento (the
design pattern is called like this ;) could also offer functions to
write/read it to/from a file.

I've used an xml file format with hugin, but had to throw out the qt
xml functions to make it generic. any preference for the file format?
xml or pano tools based. I'd like to use an xml based format, its
easier to extend than the panorama tools based one.

ciao
  Pablo
--
http://wurm.wohnheim.uni-ulm.de/~redman/
Please use PGP


More information about the ptX mailing list