00001
00002
00028 #include <config.h>
00029 #include "panoinc_WX.h"
00030 #include "panoinc.h"
00031 #include <time.h>
00032
00033 #include "base_wx/platform.h"
00034 #include "base_wx/wxPlatform.h"
00035 #include <vector>
00036 #include <map>
00037
00038 #include "hugin/ImagesPanel.h"
00039 #include "hugin/CommandHistory.h"
00040 #include "hugin/TextKillFocusHandler.h"
00041 #include "hugin/CPEditorPanel.h"
00042 #include "hugin/ImagesList.h"
00043 #include "hugin/MainFrame.h"
00044 #include "hugin/huginApp.h"
00045 #include "icpfind/AutoCtrlPointCreator.h"
00046 #include "hugin/config_defaults.h"
00047 #include "base_wx/MyProgressDialog.h"
00048 #include "base_wx/PTWXDlg.h"
00049 #include <PT/PTOptimise.h>
00050 #include "base_wx/LensTools.h"
00051 #include "hugin/ImagesTree.h"
00052 #include "panodata/OptimizerSwitches.h"
00053
00054 #include <panodata/StandardImageVariableGroups.h>
00055
00056 using namespace PT;
00057 using namespace hugin_utils;
00058 using namespace vigra;
00059 using namespace vigra_ext;
00060 using namespace std;
00061
00062 BEGIN_EVENT_TABLE(ImagesPanel, wxPanel)
00063 EVT_TREE_SEL_CHANGED(XRCID("images_tree_ctrl"), ImagesPanel::OnSelectionChanged )
00064 EVT_CHOICE ( XRCID("images_lens_type"), ImagesPanel::OnLensTypeChanged)
00065 EVT_CHOICE ( XRCID("images_group_mode"), ImagesPanel::OnGroupModeChanged)
00066 EVT_RADIOBOX ( XRCID("images_column_radiobox"), ImagesPanel::OnDisplayModeChanged)
00067 EVT_CHOICE ( XRCID("images_optimize_mode"), ImagesPanel::OnOptimizerSwitchChanged)
00068 EVT_CHOICE ( XRCID("images_photo_optimize_mode"), ImagesPanel::OnPhotometricOptimizerSwitchChanged)
00069 EVT_TEXT_ENTER ( XRCID("images_focal_length"), ImagesPanel::OnFocalLengthChanged)
00070 EVT_TEXT_ENTER ( XRCID("images_crop_factor"), ImagesPanel::OnCropFactorChanged)
00071 EVT_TEXT_ENTER ( XRCID("images_overlap"), ImagesPanel::OnMinimumOverlapChanged)
00072 EVT_TEXT_ENTER ( XRCID("images_maxev"), ImagesPanel::OnMaxEvDiffChanged)
00073 EVT_BUTTON ( XRCID("images_feature_matching"), ImagesPanel::CPGenerate)
00074 EVT_BUTTON ( XRCID("images_optimize"), ImagesPanel::OnOptimizeButton)
00075 EVT_BUTTON ( XRCID("images_photo_optimize"), ImagesPanel::OnPhotometricOptimizeButton)
00076 END_EVENT_TABLE()
00077
00078 ImagesPanel::ImagesPanel()
00079 {
00080 m_pano = 0;
00081 m_guiLevel=GUI_SIMPLE;
00082 }
00083
00084 bool ImagesPanel::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
00085 long style, const wxString& name)
00086 {
00087 if (! wxPanel::Create(parent, id, pos, size, style, name)) {
00088 return false;
00089 }
00090
00091 wxXmlResource::Get()->LoadPanel(this, wxT("images_panel"));
00092 wxPanel * panel = XRCCTRL(*this, "images_panel", wxPanel);
00093 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
00094 topsizer->Add(panel, 1, wxEXPAND, 0);
00095 SetSizer(topsizer);
00096
00097 m_images_tree = XRCCTRL(*this, "images_tree_ctrl", ImagesTreeCtrl);
00098 DEBUG_ASSERT(m_images_tree);
00099
00100 m_showImgNr = INT_MAX;
00101
00102 m_matchingButton = XRCCTRL(*this, "images_feature_matching", wxButton);
00103 DEBUG_ASSERT(m_matchingButton);
00104
00105 m_CPDetectorChoice = XRCCTRL(*this, "cpdetector_settings", wxChoice);
00106
00107
00108 m_smallImgCtrl = XRCCTRL(*this, "images_selected_image", wxStaticBitmap);
00109 DEBUG_ASSERT(m_smallImgCtrl);
00110
00111 m_empty.Create(0,0);
00112 m_smallImgCtrl->SetBitmap(m_empty);
00113
00114 m_lenstype = XRCCTRL(*this, "images_lens_type", wxChoice);
00115 DEBUG_ASSERT(m_lenstype);
00116 FillLensProjectionList(m_lenstype);
00117 m_lenstype->SetSelection(0);
00118
00119 m_focallength = XRCCTRL(*this, "images_focal_length", wxTextCtrl);
00120 DEBUG_ASSERT(m_focallength);
00121 m_focallength->PushEventHandler(new TextKillFocusHandler(this));
00122
00123 m_cropfactor = XRCCTRL(*this, "images_crop_factor", wxTextCtrl);
00124 DEBUG_ASSERT(m_cropfactor);
00125 m_cropfactor->PushEventHandler(new TextKillFocusHandler(this));
00126
00127 m_overlap = XRCCTRL(*this, "images_overlap", wxTextCtrl);
00128 DEBUG_ASSERT(m_overlap);
00129 m_overlap->PushEventHandler(new TextKillFocusHandler(this));
00130
00131 m_maxEv = XRCCTRL(*this, "images_maxev", wxTextCtrl);
00132 DEBUG_ASSERT(m_maxEv);
00133 m_maxEv->PushEventHandler(new TextKillFocusHandler(this));
00134
00135 FillGroupChoice();
00136
00137 wxTreeEvent ev;
00138 OnSelectionChanged(ev);
00139 DEBUG_TRACE("end");
00140
00141 m_optChoice = XRCCTRL(*this, "images_optimize_mode", wxChoice);
00142 DEBUG_ASSERT(m_optChoice);
00143
00144 m_optPhotoChoice = XRCCTRL(*this, "images_photo_optimize_mode", wxChoice);
00145 DEBUG_ASSERT(m_optPhotoChoice);
00146
00147 FillOptimizerChoice();
00148
00149 wxConfigBase* config=wxConfigBase::Get();
00150 m_degDigits = config->Read(wxT("/General/DegreeFractionalDigitsEdit"),3);
00151
00152 cpdetector_config.Read(config,huginApp::Get()->GetDataPath()+wxT("default.setting"));
00153
00154 cpdetector_config.Write(config);
00155 config->Flush();
00156 cpdetector_config.FillControl(m_CPDetectorChoice,true);
00157 Layout();
00158
00159 return true;
00160 }
00161
00162 void ImagesPanel::Init(Panorama * panorama)
00163 {
00164 m_pano = panorama;
00165 m_images_tree->Init(m_pano);
00166
00167 m_pano->addObserver(this);
00168 }
00169
00170 void DeleteClientData(wxChoice* cb)
00171 {
00172 for(size_t i = 0; i < cb->GetCount(); i++)
00173 {
00174 delete static_cast<int*>(cb->GetClientData(i));
00175 };
00176 };
00177
00178 ImagesPanel::~ImagesPanel()
00179 {
00180 DEBUG_TRACE("dtor");
00181 m_focallength->PopEventHandler(true);
00182 m_cropfactor->PopEventHandler(true);
00183 m_overlap->PopEventHandler(true);
00184 m_maxEv->PopEventHandler(true);
00185 m_pano->removeObserver(this);
00186 wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
00187 size_t sel=group->GetSelection();
00188 DeleteClientData(group);
00189 DeleteClientData(m_optChoice);
00190 DeleteClientData(m_optPhotoChoice);
00191 DEBUG_TRACE("dtor end");
00192 }
00193
00194
00195
00196
00197
00198
00199 void ImagesPanel::OnSize( wxSizeEvent & e )
00200 {
00201 int winWidth, winHeight;
00202 GetClientSize(&winWidth, &winHeight);
00203 DEBUG_INFO( "image panel: " << winWidth <<"x"<< winHeight );
00204 UpdatePreviewImage();
00205
00206 e.Skip();
00207 }
00208
00209 void ImagesPanel::panoramaChanged(PT::Panorama & pano)
00210 {
00211
00212 int optSwitch=m_pano->getOptimizerSwitch();
00213 int found=wxNOT_FOUND;
00214 for(size_t i=0;i<m_optChoice->GetCount();i++)
00215 {
00216 if(optSwitch==*static_cast<int*>(m_optChoice->GetClientData(i)))
00217 {
00218 found=i;
00219 break;
00220 };
00221 };
00222 if(found==wxNOT_FOUND)
00223 {
00224 GlobalCmdHist::getInstance().addCommand(
00225 new PT::UpdateOptimizerSwitchCmd(*m_pano, 0)
00226 );
00227 }
00228 else
00229 {
00230 m_optChoice->SetSelection(found);
00231 };
00232
00233
00234 optSwitch=m_pano->getPhotometricOptimizerSwitch();
00235 found=wxNOT_FOUND;
00236 for(size_t i=0;i<m_optPhotoChoice->GetCount();i++)
00237 {
00238 if(optSwitch==*static_cast<int*>(m_optPhotoChoice->GetClientData(i)))
00239 {
00240 found=i;
00241 break;
00242 };
00243 };
00244 if(found==wxNOT_FOUND)
00245 {
00246 GlobalCmdHist::getInstance().addCommand(
00247 new PT::UpdatePhotometricOptimizerSwitchCmd(*m_pano, 0)
00248 );
00249 }
00250 else
00251 {
00252 m_optPhotoChoice->SetSelection(found);
00253 };
00254 const PanoramaOptions opts=m_pano->getOptions();
00255 m_overlap->SetValue(hugin_utils::doubleTowxString(opts.outputStacksMinOverlap,3));
00256 m_maxEv->SetValue(hugin_utils::doubleTowxString(opts.outputLayersExposureDiff,2));
00257 }
00258
00259 void ImagesPanel::panoramaImagesChanged(PT::Panorama &pano, const PT::UIntSet & _imgNr)
00260 {
00261 DEBUG_TRACE("");
00262
00263
00264 const UIntSet & selected = m_images_tree->GetSelectedImages();
00265 DEBUG_DEBUG("nr of sel Images: " << selected.size());
00266 if (pano.getNrOfImages() == 0)
00267 {
00268 DisableImageCtrls();
00269 m_matchingButton->Disable();
00270 }
00271 else
00272 {
00273 m_matchingButton->Enable();
00274 wxTreeEvent ev;
00275 OnSelectionChanged(ev);
00276 };
00277
00278 XRCCTRL(*this, "images_optimize", wxButton)->Enable(pano.getNrOfImages()>0);
00279 XRCCTRL(*this, "images_photo_optimize", wxButton)->Enable(pano.getNrOfImages()>1);
00280 }
00281
00282
00283
00285 void ImagesPanel::CPGenerate(wxCommandEvent & e)
00286 {
00287 UIntSet selImg = m_images_tree->GetSelectedImages();
00288
00289 wxString progName=cpdetector_config.settings[m_CPDetectorChoice->GetSelection()].GetProg().Lower();
00290 if ((selImg.size()==0) || (selImg.size()==1 && progName.Find(wxT("linefind"))==wxNOT_FOUND))
00291 {
00292
00293 selImg.clear();
00294 fill_set(selImg,0,m_pano->getNrOfImages()-1);
00295 }
00296
00297 if (selImg.size() == 0)
00298 {
00299 return;
00300 }
00301
00302 wxConfigBase* config=wxConfigBase::Get();
00303 long nFeatures = HUGIN_ASS_NCONTROLPOINTS;
00304 #if wxCHECK_VERSION(2,9,4)
00305 if(wxGetKeyState(WXK_COMMAND))
00306 #else
00307 if(wxGetKeyState(WXK_CONTROL))
00308 #endif
00309 {
00310 nFeatures = config->Read(wxT("/MainFrame/nControlPoints"), HUGIN_ASS_NCONTROLPOINTS);
00311 nFeatures = wxGetNumberFromUser(
00312 _("Enter maximal number of control points per image pair"),
00313 _("Points per Overlap"),
00314 _("Control point detector option"),
00315 nFeatures, 1, 10000
00316 );
00317 if(nFeatures<1)
00318 {
00319 return;
00320 };
00321 config->Write(wxT("/MainFrame/nControlPoints"), nFeatures);
00322 }
00323 else
00324 {
00325 nFeatures = config->Read(wxT("/Assistant/nControlPoints"), HUGIN_ASS_NCONTROLPOINTS);
00326 };
00327
00328 AutoCtrlPointCreator matcher;
00329 CPVector cps = matcher.automatch(cpdetector_config.settings[m_CPDetectorChoice->GetSelection()],
00330 *m_pano, selImg, nFeatures,this);
00331 wxString msg;
00332 wxMessageBox(wxString::Format(_("Added %lu control points"), (unsigned long) cps.size()), _("Control point detector result"),wxOK|wxICON_INFORMATION,this);
00333 GlobalCmdHist::getInstance().addCommand(
00334 new PT::AddCtrlPointsCmd(*m_pano, cps)
00335 );
00336
00337 };
00338
00339 void ImagesPanel::OnSelectionChanged(wxTreeEvent & e)
00340 {
00341 const UIntSet & sel = m_images_tree->GetSelectedImages();
00342 DEBUG_DEBUG("selected Images: " << sel.size());
00343 if (sel.size() == 0)
00344 {
00345
00346 DisableImageCtrls();
00347 }
00348 else
00349 {
00350
00351 EnableImageCtrls();
00352 const SrcPanoImage& img=m_pano->getImage(*sel.begin());
00353 bool identical_projection=true;
00354 SrcPanoImage::Projection proj=img.getProjection();
00355 double focallength=SrcPanoImage::calcFocalLength(img.getProjection(),img.getHFOV(),
00356 img.getExifCropFactor(),img.getSize());;
00357 double cropFactor=img.getExifCropFactor();
00358 for(UIntSet::const_iterator it=sel.begin(); it!=sel.end(); it++)
00359 {
00360 const SrcPanoImage& img2=m_pano->getImage(*it);
00361 if(proj!=img2.getProjection())
00362 {
00363 identical_projection=false;
00364 };
00365 double focallength2 = SrcPanoImage::calcFocalLength(img2.getProjection(),img2.getHFOV(),
00366 img2.getExifCropFactor(),img2.getSize());
00367 if(focallength>0 && fabs(focallength-focallength2)>0.05)
00368 {
00369 focallength=-1;
00370 };
00371 if(fabs(cropFactor-img2.getExifCropFactor())>0.1)
00372 {
00373 cropFactor=-1;
00374 };
00375 };
00376
00377 if(identical_projection)
00378 {
00379 SelectProjection(m_lenstype, proj);
00380 }
00381 else
00382 {
00383 m_lenstype->Select(wxNOT_FOUND);
00384 };
00385 if(focallength>0)
00386 {
00387 m_focallength->SetValue(hugin_utils::doubleTowxString(focallength,m_degDigits));
00388 }
00389 else
00390 {
00391 m_focallength->Clear();
00392 };
00393 if(cropFactor>0)
00394 {
00395 m_cropfactor->SetValue(doubleTowxString(cropFactor,m_degDigits));
00396 }
00397 else
00398 {
00399 m_cropfactor->Clear();
00400 };
00401
00402 if (sel.size() == 1)
00403 {
00404 ShowImage(*(sel.begin()));
00405 }
00406 else
00407 {
00408 m_smallImgCtrl->SetBitmap(m_empty);
00409 m_smallImgCtrl->GetParent()->Layout();
00410 m_smallImgCtrl->Refresh();
00411 };
00412 }
00413 }
00414
00415 void ImagesPanel::DisableImageCtrls()
00416 {
00417
00418 m_lenstype->Disable();
00419 m_focallength->Disable();
00420 m_cropfactor->Disable();
00421 m_smallImgCtrl->SetBitmap(m_empty);
00422 m_smallImgCtrl->GetParent()->Layout();
00423 m_smallImgCtrl->Refresh();
00424 }
00425
00426 void ImagesPanel::EnableImageCtrls()
00427 {
00428
00429 m_lenstype->Enable();
00430 m_focallength->Enable();
00431 m_cropfactor->Enable();
00432 }
00433
00434 void ImagesPanel::ShowImage(unsigned int imgNr)
00435 {
00436 m_showImgNr = imgNr;
00437 UpdatePreviewImage();
00438 }
00439
00440 void ImagesPanel::UpdatePreviewImage()
00441 {
00442 if (m_showImgNr < 0 || m_showImgNr >= m_pano->getNrOfImages())
00443 {
00444 return;
00445 }
00446 ImageCache::EntryPtr cacheEntry = ImageCache::getInstance().getSmallImageIfAvailable(
00447 m_pano->getImage(m_showImgNr).getFilename());
00448 if (!cacheEntry.get())
00449 {
00450
00451
00452
00453
00454 thumbnail_request = ImageCache::getInstance().requestAsyncSmallImage(
00455 m_pano->getImage(m_showImgNr).getFilename());
00456
00457 thumbnail_request->ready.connect(
00458 boost::bind(&ImagesPanel::UpdatePreviewImage, this));
00459 } else {
00460
00461 thumbnail_request = ImageCache::RequestPtr();
00462 wxImage img = imageCacheEntry2wxImage(cacheEntry);
00463
00464 double iRatio = img.GetWidth() / (double) img.GetHeight();
00465
00466 wxSize sz;
00467
00468
00469 sz = m_smallImgCtrl->GetContainingSizer()->GetSize();
00470 double sRatio = (double)sz.GetWidth() / sz.GetHeight();
00471 if (iRatio > sRatio) {
00472
00473 sz.SetHeight((int) (sz.GetWidth() / iRatio));
00474 } else {
00475
00476 sz.SetWidth((int) (sz.GetHeight() * iRatio));
00477 }
00478
00479
00480 sz.IncTo(wxSize(1,1));
00481 wxImage scaled = img.Scale(sz.GetWidth(),sz.GetHeight());
00482 m_smallImgCtrl->SetBitmap(wxBitmap(scaled));
00483 m_smallImgCtrl->GetParent()->Layout();
00484 m_smallImgCtrl->Refresh();
00485 }
00486 }
00487
00488 void ImagesPanel::ReloadCPDetectorSettings()
00489 {
00490 cpdetector_config.Read();
00491 cpdetector_config.FillControl(m_CPDetectorChoice,true);
00492 m_CPDetectorChoice->InvalidateBestSize();
00493 m_CPDetectorChoice->GetParent()->Layout();
00494 Refresh();
00495 };
00496
00497 void ImagesPanel::OnLensTypeChanged (wxCommandEvent & e)
00498 {
00499 size_t var = GetSelectedProjection(m_lenstype);
00500 UIntSet images=m_images_tree->GetSelectedImages();
00501 if(images.size()>0)
00502 {
00503 const SrcPanoImage & img=m_pano->getImage(*(images.begin()));
00504 double focal_length = SrcPanoImage::calcFocalLength(img.getProjection(),img.getHFOV(),img.getExifCropFactor(),img.getSize());
00505 std::vector<PanoCommand*> commands;
00506 commands.push_back(new PT::ChangeImageProjectionCmd(*m_pano, images,(HuginBase::SrcPanoImage::Projection) var));
00507 commands.push_back(new PT::UpdateFocalLengthCmd(*m_pano, images, focal_length));
00508 GlobalCmdHist::getInstance().addCommand(
00509 new PT::CombinedPanoCommand(*m_pano, commands)
00510 );
00511 };
00512 };
00513
00514 void ImagesPanel::OnFocalLengthChanged(wxCommandEvent & e)
00515 {
00516 if (m_pano->getNrOfImages() == 0)
00517 {
00518 return;
00519 };
00520
00521 wxString text = m_focallength->GetValue();
00522 if(text.IsEmpty())
00523 {
00524 return;
00525 };
00526 double val;
00527 if (!str2double(text, val))
00528 {
00529 return;
00530 }
00531
00532 if (val<0.1)
00533 {
00534 wxBell();
00535 return;
00536 };
00537
00538 UIntSet images=m_images_tree->GetSelectedImages();
00539 const SrcPanoImage& srcImg=m_pano->getImage(*(images.begin()));
00540 if(srcImg.getProjection()==SrcPanoImage::FISHEYE_ORTHOGRAPHIC)
00541 {
00542 double hfov=srcImg.calcHFOV(srcImg.getProjection(), val, srcImg.getExifCropFactor(), srcImg.getSize());
00543 if(hfov>190)
00544 {
00545 if(wxMessageBox(
00546 wxString::Format(_("You have given a field of view of %.2f degrees.\n But the orthographic projection is limited to a field of view of 180 degress.\nDo you want still use that high value?"), hfov),
00547 #ifdef __WXMSW__
00548 _("Hugin"),
00549 #else
00550 wxT(""),
00551 #endif
00552 wxICON_EXCLAMATION | wxYES_NO)==wxNO)
00553 {
00554 wxTreeEvent dummy;
00555 OnSelectionChanged(dummy);
00556 return;
00557 };
00558 };
00559 };
00560 GlobalCmdHist::getInstance().addCommand(
00561 new PT::UpdateFocalLengthCmd(*m_pano, images, val)
00562 );
00563 }
00564
00565 void ImagesPanel::OnCropFactorChanged(wxCommandEvent & e)
00566 {
00567 if (m_pano->getNrOfImages() == 0)
00568 {
00569 return;
00570 };
00571
00572 wxString text = m_cropfactor->GetValue();
00573 if(text.IsEmpty())
00574 {
00575 return;
00576 };
00577 double val;
00578 if (!str2double(text, val))
00579 {
00580 return;
00581 }
00582
00583 if (val<0.1)
00584 {
00585 wxBell();
00586 return;
00587 };
00588
00589 UIntSet images=m_images_tree->GetSelectedImages();
00590 GlobalCmdHist::getInstance().addCommand(
00591 new PT::UpdateCropFactorCmd(*m_pano,images,val)
00592 );
00593 }
00594
00595 void ImagesPanel::OnMinimumOverlapChanged(wxCommandEvent & e)
00596 {
00597 wxString text = m_overlap->GetValue();
00598 if(text.IsEmpty())
00599 {
00600 return;
00601 };
00602 double val;
00603 if (!str2double(text, val))
00604 {
00605 return;
00606 }
00607 if(val<=0 || val>1)
00608 {
00609 wxMessageBox(_("The minimum overlap has to be greater than 0 and smaller than 1."),
00610 #ifdef _WINDOWS
00611 _("Hugin"),
00612 #else
00613 wxT(""),
00614 #endif
00615 wxOK | wxICON_INFORMATION, this);
00616 return;
00617 };
00618 PanoramaOptions opt=m_pano->getOptions();
00619 opt.outputStacksMinOverlap=val;
00620 GlobalCmdHist::getInstance().addCommand(
00621 new PT::SetPanoOptionsCmd(*m_pano,opt)
00622 );
00623 };
00624
00625 void ImagesPanel::OnMaxEvDiffChanged(wxCommandEvent& e)
00626 {
00627 wxString text = m_maxEv->GetValue();
00628 if(text.IsEmpty())
00629 {
00630 return;
00631 };
00632 double val;
00633 if (!str2double(text, val))
00634 {
00635 return;
00636 }
00637 if(val<0)
00638 {
00639 wxMessageBox(_("The maximum Ev difference has to be greater than 0."),
00640 #ifdef _WINDOWS
00641 _("Hugin"),
00642 #else
00643 wxT(""),
00644 #endif
00645 wxOK | wxICON_INFORMATION, this);
00646 return;
00647 };
00648 PanoramaOptions opt=m_pano->getOptions();
00649 opt.outputLayersExposureDiff=val;
00650 GlobalCmdHist::getInstance().addCommand(
00651 new PT::SetPanoOptionsCmd(*m_pano,opt)
00652 );
00653 };
00654
00655 void ImagesPanel::FillGroupChoice()
00656 {
00657 wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
00658 size_t sel=group->GetSelection();
00659 DeleteClientData(group);
00660 group->Clear();
00661 int* i=new int;
00662 *i=ImagesTreeCtrl::GROUP_NONE;
00663 group->Append(_("None"), i);
00664 i=new int;
00665 *i=ImagesTreeCtrl::GROUP_LENS;
00666 group->Append(_("Lens"), i);
00667 if(m_guiLevel>GUI_SIMPLE)
00668 {
00669 i=new int;
00670 *i=ImagesTreeCtrl::GROUP_STACK;
00671 group->Append(_("Stacks"), i);
00672 if(m_guiLevel==GUI_EXPERT)
00673 {
00674 i=new int;
00675 *i=ImagesTreeCtrl::GROUP_OUTPUTLAYERS;
00676 group->Append(_("Output layers"), i);
00677 i=new int;
00678 *i=ImagesTreeCtrl::GROUP_OUTPUTSTACK;
00679 group->Append(_("Output stacks"), i);
00680 };
00681 };
00682 if((m_guiLevel==GUI_ADVANCED && sel>2) || (m_guiLevel==GUI_SIMPLE && sel>1))
00683 {
00684 sel=0;
00685 };
00686 group->SetSelection(sel);
00687 wxCommandEvent dummy;
00688 OnGroupModeChanged(dummy);
00689 };
00690
00691 void ImagesPanel::FillOptimizerChoice()
00692 {
00693 DeleteClientData(m_optChoice);
00694 m_optChoice->Clear();
00695 int* i=new int;
00696 *i=HuginBase::OPT_PAIR;
00697 m_optChoice->Append(_("Positions (incremental, starting from anchor)"), i);
00698 i=new int;
00699 *i=HuginBase::OPT_POSITION;
00700 m_optChoice->Append(_("Positions (y,p,r)"), i);
00701 i=new int;
00702 *i=(HuginBase::OPT_POSITION | HuginBase::OPT_VIEW);
00703 m_optChoice->Append(_("Positions and View (y,p,r,v)"), i);
00704 i=new int;
00705 *i=(HuginBase::OPT_POSITION | HuginBase::OPT_BARREL);
00706 m_optChoice->Append(_("Positions and Barrel Distortion (y,p,r,b)"), i);
00707 i=new int;
00708 *i=(HuginBase::OPT_POSITION | HuginBase::OPT_VIEW | HuginBase::OPT_BARREL);
00709 m_optChoice->Append(_("Positions, View and Barrel (y,p,r,v,b)"), i);
00710 i=new int;
00711 *i=HuginBase::OPT_ALL;
00712 if(m_guiLevel==GUI_EXPERT)
00713 {
00714 m_optChoice->Append(_("Everything without translation"), i);
00715 }
00716 else
00717 {
00718 m_optChoice->Append(_("Everything"), i);
00719 };
00720 if(m_guiLevel==GUI_EXPERT)
00721 {
00722 i=new int;
00723 *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION);
00724 m_optChoice->Append(_("Positions and Translation (y,p,r,x,y,z)"), i);
00725 i=new int;
00726 *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION | HuginBase::OPT_VIEW);
00727 m_optChoice->Append(_("Positions, Translation and View (y,p,r,x,y,z,v)"), i);
00728 i=new int;
00729 *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION | HuginBase::OPT_BARREL);
00730 m_optChoice->Append(_("Positions, Translation and Barrel (y,p,r,x,y,z,b)"), i);
00731 i=new int;
00732 *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION | HuginBase::OPT_VIEW | HuginBase::OPT_BARREL);
00733 m_optChoice->Append(_("Positions, Translation, View and Barrel (y,p,r,x,y,z,v,b)"), i);
00734 };
00735 i=new int;
00736 *i=0;
00737 m_optChoice->Append(_("Custom parameters"), i);
00738
00739 DeleteClientData(m_optPhotoChoice);
00740 m_optPhotoChoice->Clear();
00741 i=new int;
00742 *i=(HuginBase::OPT_EXPOSURE | HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE);
00743 m_optPhotoChoice->Append(_("Low dynamic range"), i);
00744 i=new int;
00745 *i=(HuginBase::OPT_EXPOSURE | HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE | HuginBase::OPT_WHITEBALANCE);
00746 m_optPhotoChoice->Append(_("Low dynamic range, variable white balance"), i);
00747 if(m_guiLevel>GUI_SIMPLE)
00748 {
00749 i=new int;
00750 *i=(HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE);
00751 m_optPhotoChoice->Append(_("High dynamic range, fixed exposure"), i);
00752 i=new int;
00753 *i=(HuginBase::OPT_WHITEBALANCE | HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE);
00754 m_optPhotoChoice->Append(_("High dynamic range, variable white balance, fixed exposure"), i);
00755 };
00756 i=new int;
00757 *i=0;
00758 m_optPhotoChoice->Append(_("Custom parameters"), i);
00759 m_optChoice->GetParent()->Layout();
00760 Refresh();
00761 };
00762
00763 void ImagesPanel::OnGroupModeChanged(wxCommandEvent & e)
00764 {
00765 wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
00766 ImagesTreeCtrl::GroupMode mode=ImagesTreeCtrl::GroupMode(*static_cast<int*>(group->GetClientData(group->GetSelection())));
00767 m_images_tree->SetGroupMode(mode);
00768 XRCCTRL(*this, "images_text_overlap", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
00769 m_overlap->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
00770 m_overlap->Enable(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
00771 XRCCTRL(*this, "images_text_maxev", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
00772 m_maxEv->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
00773 m_maxEv->Enable(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
00774 Layout();
00775 Refresh();
00776 };
00777
00778 void ImagesPanel::OnDisplayModeChanged(wxCommandEvent & e)
00779 {
00780 wxRadioBox* display=XRCCTRL(*this,"images_column_radiobox", wxRadioBox);
00781 m_images_tree->SetDisplayMode((ImagesTreeCtrl::DisplayMode)display->GetSelection());
00782 };
00783
00784 void ImagesPanel::OnOptimizerSwitchChanged(wxCommandEvent &e)
00785 {
00786 int optSwitch=*static_cast<int*>(m_optChoice->GetClientData(m_optChoice->GetSelection()));
00787 if(optSwitch!=m_pano->getOptimizerSwitch())
00788 {
00789 GlobalCmdHist::getInstance().addCommand(
00790 new PT::UpdateOptimizerSwitchCmd(*m_pano,optSwitch)
00791 );
00792 };
00793 };
00794
00795 void ImagesPanel::OnPhotometricOptimizerSwitchChanged(wxCommandEvent &e)
00796 {
00797 int optSwitch=*static_cast<int*>(m_optPhotoChoice->GetClientData(m_optPhotoChoice->GetSelection()));
00798 if(optSwitch!=m_pano->getPhotometricOptimizerSwitch())
00799 {
00800 GlobalCmdHist::getInstance().addCommand(
00801 new PT::UpdatePhotometricOptimizerSwitchCmd(*m_pano,optSwitch)
00802 );
00803 };
00804 };
00805
00806 void ImagesPanel::SetGuiLevel(GuiLevel newGuiLevel)
00807 {
00808 m_guiLevel=newGuiLevel;
00809 m_images_tree->SetGuiLevel(newGuiLevel);
00810 FillGroupChoice();
00811 FillOptimizerChoice();
00812 wxStaticText* textlabel=XRCCTRL(*this, "images_mode_text", wxStaticText);
00813 switch(m_guiLevel)
00814 {
00815 case GUI_SIMPLE:
00816 textlabel->SetLabel(_("Simple interface"));
00817 break;
00818 case GUI_ADVANCED:
00819 textlabel->SetLabel(_("Advanced interface"));
00820 break;
00821 case GUI_EXPERT:
00822 textlabel->SetLabel(_("Expert interface"));
00823 break;
00824 };
00825 textlabel->GetParent()->Layout();
00826 textlabel->Refresh();
00827 panoramaChanged(*m_pano);
00828 };
00829
00830 void ImagesPanel::OnOptimizeButton(wxCommandEvent &e)
00831 {
00832 MainFrame::Get()->OnOptimize(e);
00833 };
00834
00835 void ImagesPanel::OnPhotometricOptimizeButton(wxCommandEvent &e)
00836 {
00837 MainFrame::Get()->OnPhotometricOptimize(e);
00838 };
00839
00840 IMPLEMENT_DYNAMIC_CLASS(ImagesPanel, wxPanel)
00841
00842 ImagesPanelXmlHandler::ImagesPanelXmlHandler()
00843 : wxXmlResourceHandler()
00844 {
00845 AddWindowStyles();
00846 }
00847
00848 wxObject *ImagesPanelXmlHandler::DoCreateResource()
00849 {
00850 XRC_MAKE_INSTANCE(cp, ImagesPanel)
00851
00852 cp->Create(m_parentAsWindow,
00853 GetID(),
00854 GetPosition(), GetSize(),
00855 GetStyle(wxT("style")),
00856 GetName());
00857
00858 SetupWindow( cp);
00859 return cp;
00860 }
00861
00862 bool ImagesPanelXmlHandler::CanHandle(wxXmlNode *node)
00863 {
00864 return IsOfClass(node, wxT("ImagesPanel"));
00865 }
00866
00867 IMPLEMENT_DYNAMIC_CLASS(ImagesPanelXmlHandler, wxXmlResourceHandler)