1 // -*- c-basic-offset: 4 -*-
2 /** @file wxLensDB.cpp
3  *
4  *  @brief dialogs for loading and saving information from/to lens database
5  *
6  *  @author T. Modes
7  *
8  */
9 
10 /*  This program 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  *  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 #include "panoinc_WX.h"
27 #include "panoinc.h"
28 #include "wxLensDB.h"
29 #include "lensdb/LensDB.h"
30 #include "platform.h"
31 #include "base_wx/wxPlatform.h"
32 #include "panodata/ImageVariableTranslate.h"
33 #include "panodata/ImageVariableGroup.h"
34 #include "base_wx/PanoCommand.h"
35 #include <set>
36 
37 /** dialog for loading lens parameter from lens database */
38 class LoadLensDBDialog : public wxDialog
39 {
40 public:
41     /** Constructor, read from xrc ressource; restore last uses settings, size and position */
42     explicit LoadLensDBDialog(wxWindow *parent);
43     void SetLensName(std::string lensname);
44     std::string GetLensName() const;
45     void SetFocalLength(double focal);
46     double GetFocalLength() const;
47     void SetAperture(double aperture);
48     double GetAperture() const;
49     void SetSubjectDistance(double distance);
50     double GetSubjectDistance() const;
51     bool GetLoadDistortion() const;
52     bool GetLoadVignetting() const;
53 
54 protected:
55     /** Saves current state of all checkboxes when closing dialog with Ok */
56     void OnOk(wxCommandEvent & e);
57     void OnCheckChanged(wxCommandEvent & e);
58 
59 private:
60     void FillLensList();
61     wxChoice *m_lenslist;
62     wxCheckBox *m_loadDistortion;
63     wxCheckBox *m_loadVignetting;
64     double m_focal;
65     double m_aperture;
66     double m_distance;
67     HuginBase::LensDB::LensList m_lensNames;
68     DECLARE_EVENT_TABLE()
69 };
70 
BEGIN_EVENT_TABLE(LoadLensDBDialog,wxDialog)71 BEGIN_EVENT_TABLE(LoadLensDBDialog,wxDialog)
72     EVT_BUTTON(wxID_OK, LoadLensDBDialog::OnOk)
73     EVT_CHOICE(XRCID("load_lens_lenschoice"), LoadLensDBDialog::OnCheckChanged)
74     EVT_CHECKBOX(XRCID("load_lens_distortion"), LoadLensDBDialog::OnCheckChanged)
75     EVT_CHECKBOX(XRCID("load_lens_vignetting"), LoadLensDBDialog::OnCheckChanged)
76 END_EVENT_TABLE()
77 
78 LoadLensDBDialog::LoadLensDBDialog(wxWindow *parent)
79 {
80     // load our children. some children might need special
81     // initialization. this will be done later.
82     wxXmlResource::Get()->LoadDialog(this, parent, wxT("load_lens_dlg"));
83 
84     //set parameters
85     wxConfigBase * config = wxConfigBase::Get();
86     // get display size
87     int dx,dy;
88     wxDisplaySize(&dx,&dy);
89     int w = config->Read(wxT("/LoadLensDialog/width"),-1l);
90     int h = config->Read(wxT("/LoadLensDialog/height"),-1l);
91     if (w>0 && w<=dx && h>0 && h<=dy)
92     {
93         SetClientSize(w,h);
94     }
95     else
96     {
97         Fit();
98     }
99     //position
100     int x = config->Read(wxT("/LoadLensDialog/positionX"),-1l);
101     int y = config->Read(wxT("/LoadLensDialog/positionY"),-1l);
102     if ( y >= 0 && x >= 0)
103     {
104         this->Move(x, y);
105     }
106     else
107     {
108         this->Move(0, 44);
109     };
110     bool b;
111     config->Read(wxT("/LoadLensDialog/loadDistortion"), &b, true);
112     m_loadDistortion = XRCCTRL(*this, "load_lens_distortion", wxCheckBox);
113     m_loadDistortion->SetValue(b);
114     config->Read(wxT("/LoadLensDialog/loadVignetting"), &b, true);
115     m_loadVignetting = XRCCTRL(*this, "load_lens_vignetting", wxCheckBox);
116     m_loadVignetting->SetValue(b);
117     m_lenslist=XRCCTRL(*this,"load_lens_lenschoice", wxChoice);
118     FillLensList();
119 };
120 
FillLensList()121 void LoadLensDBDialog::FillLensList()
122 {
123     if (HuginBase::LensDB::LensDB::GetSingleton().GetLensNames(true, true, false, m_lensNames))
124     {
125         wxArrayString lensnames;
126         for (HuginBase::LensDB::LensList::const_iterator it = m_lensNames.begin(); it != m_lensNames.end(); ++it)
127         {
128             wxString s((*it).c_str(), wxConvLocal);
129             wxString cam = s.AfterFirst(wxT('|'));
130             if (!cam.empty())
131             {
132                 s = wxString::Format(_("Camera %s (%s)"), cam.c_str(), s.BeforeFirst(wxT('|')).c_str());
133             };
134             lensnames.Add(s);
135         };
136         m_lenslist->Append(lensnames);
137     };
138 };
139 
SetLensName(std::string lensname)140 void LoadLensDBDialog::SetLensName(std::string lensname)
141 {
142     if (!lensname.empty() && !m_lensNames.empty())
143     {
144         HuginBase::LensDB::LensList::const_iterator it=std::find(m_lensNames.begin(), m_lensNames.end(), lensname);
145         if (it != m_lensNames.end())
146         {
147             m_lenslist->SetSelection(it - m_lensNames.begin());
148         };
149     };
150     wxCommandEvent dummy;
151     OnCheckChanged(dummy);
152 };
153 
GetLensName() const154 std::string LoadLensDBDialog::GetLensName() const
155 {
156     return m_lensNames[m_lenslist->GetSelection()];
157 };
158 
SetFocalLength(double focal)159 void LoadLensDBDialog::SetFocalLength(double focal)
160 {
161     m_focal=focal;
162     XRCCTRL(*this,"load_lens_focallength",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_focal,1));
163 };
164 
GetFocalLength() const165 double LoadLensDBDialog::GetFocalLength() const
166 {
167     return m_focal;
168 };
169 
SetAperture(double aperture)170 void LoadLensDBDialog::SetAperture(double aperture)
171 {
172     m_aperture=aperture;
173     XRCCTRL(*this,"load_lens_aperture",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_aperture,1));
174 };
175 
GetAperture() const176 double LoadLensDBDialog::GetAperture() const
177 {
178     return m_aperture;
179 };
180 
SetSubjectDistance(double distance)181 void LoadLensDBDialog::SetSubjectDistance(double distance)
182 {
183     m_distance=distance;
184     XRCCTRL(*this,"load_lens_distance",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_distance,0));
185 };
186 
GetSubjectDistance() const187 double LoadLensDBDialog::GetSubjectDistance() const
188 {
189     return m_distance;
190 };
191 
GetLoadDistortion() const192 bool LoadLensDBDialog::GetLoadDistortion() const
193 {
194     return m_loadDistortion->GetValue();
195 };
196 
GetLoadVignetting() const197 bool LoadLensDBDialog::GetLoadVignetting() const
198 {
199     return m_loadVignetting->GetValue();
200 };
201 
202 // utility functions
str2double(wxWindow * parent,wxString s,double & d)203 bool str2double(wxWindow* parent, wxString s, double & d)
204 {
205     if (!hugin_utils::stringToDouble(std::string(s.mb_str(wxConvLocal)), d))
206     {
207         wxMessageBox(wxString::Format(_("The input \"%s\" is not a valid number."),s.c_str()),_("Warning"), wxOK | wxICON_ERROR, parent);
208         return false;
209     }
210     return true;
211 }
212 
OnOk(wxCommandEvent & e)213 void LoadLensDBDialog::OnOk(wxCommandEvent & e)
214 {
215     if(!m_loadDistortion->GetValue() && !m_loadVignetting->GetValue())
216     {
217         return;
218     };
219     if(m_lenslist->GetSelection()==wxNOT_FOUND)
220     {
221         wxBell();
222         return;
223     };
224     if(!str2double(this,XRCCTRL(*this,"load_lens_focallength",wxTextCtrl)->GetValue(),m_focal))
225     {
226         return;
227     };
228     if(m_loadVignetting->GetValue())
229     {
230         wxString val = XRCCTRL(*this, "load_lens_aperture", wxTextCtrl)->GetValue().Trim();
231         if (val.empty())
232         {
233             m_aperture = 0;
234         }
235         else
236         {
237             if (!str2double(this, val, m_aperture))
238             {
239                 return;
240             };
241         };
242         val = XRCCTRL(*this, "load_lens_distance", wxTextCtrl)->GetValue().Trim();
243         if (val.empty())
244         {
245             m_distance = 0;
246         }
247         else
248         {
249             if (!str2double(this, val, m_distance))
250             {
251                 return;
252             };
253         };
254     };
255     //store selected options
256     wxConfigBase * config = wxConfigBase::Get();
257     wxSize sz = this->GetClientSize();
258     config->Write(wxT("/LoadLensDialog/width"), sz.GetWidth());
259     config->Write(wxT("/LoadLensDialog/height"), sz.GetHeight());
260     wxPoint ps = this->GetPosition();
261     config->Write(wxT("/LoadLensDialog/positionX"), ps.x);
262     config->Write(wxT("/LoadLensDialog/positionY"), ps.y);
263     config->Write(wxT("/LoadLensDialog/loadDistortion"),m_loadDistortion->GetValue());
264     config->Write(wxT("/LoadLensDialog/loadVignetting"),m_loadVignetting->GetValue());
265     config->Flush();
266     e.Skip();
267 };
268 
OnCheckChanged(wxCommandEvent & e)269 void LoadLensDBDialog::OnCheckChanged(wxCommandEvent & e)
270 {
271     int sel=m_lenslist->GetSelection();
272     XRCCTRL(*this,"wxID_OK",wxButton)->Enable(sel!=wxNOT_FOUND && (m_loadDistortion->GetValue() || m_loadVignetting->GetValue()));
273 };
274 
ApplyLensDBParameters(wxWindow * parent,HuginBase::Panorama * pano,HuginBase::UIntSet images,PanoCommand::PanoCommand * & cmd)275 bool ApplyLensDBParameters(wxWindow * parent, HuginBase::Panorama *pano, HuginBase::UIntSet images, PanoCommand::PanoCommand*& cmd)
276 {
277     LoadLensDBDialog dlg(parent);
278     const HuginBase::SrcPanoImage & img=pano->getImage(*images.begin());
279     dlg.SetLensName(img.getDBLensName());
280     dlg.SetFocalLength(img.getExifFocalLength());
281     dlg.SetAperture(img.getExifAperture());
282     dlg.SetSubjectDistance(img.getExifDistance());
283     if(dlg.ShowModal()==wxID_OK)
284     {
285         HuginBase::LensDB::LensDB & lensDB=HuginBase::LensDB::LensDB::GetSingleton();
286         const double focal=dlg.GetFocalLength();
287         const std::string lensname = dlg.GetLensName();
288         std::vector<PanoCommand::PanoCommand*> cmds;
289         HuginBase::BaseSrcPanoImage::Projection proj;
290         if(lensDB.GetProjection(lensname, proj))
291         {
292             cmds.push_back(new PanoCommand::ChangeImageProjectionCmd(*pano,images,proj));
293         };
294         vigra::Rect2D cropRect;
295         if(lensDB.GetCrop(lensname, focal, img.getSize(), cropRect))
296         {
297             cmds.push_back(new PanoCommand::ChangeImageCropModeCmd(*pano, images, img.isCircularCrop() ? HuginBase::BaseSrcPanoImage::CROP_CIRCLE : HuginBase::BaseSrcPanoImage::CROP_RECTANGLE));
298             cmds.push_back(new PanoCommand::ChangeImageCropRectCmd(*pano, images, cropRect));
299         };
300         //load lens distortion from database
301         if(dlg.GetLoadDistortion())
302         {
303             double hfov;
304             if (lensDB.GetFov(lensname, focal, hfov))
305             {
306                 // calculate FOV for given image, take different aspect ratios into account
307                 const double newFocal = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), hfov, img.getCropFactor(), vigra::Size2D(3000, 2000));
308                 const double newFov = HuginBase::SrcPanoImage::calcHFOV(img.getProjection(), newFocal, img.getCropFactor(), img.getSize());
309                 std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> linkedVariables;
310                 linkedVariables.insert(HuginBase::ImageVariableGroup::IVE_HFOV);
311                 cmds.push_back(new PanoCommand::ChangePartImagesLinkingCmd(*pano, images, linkedVariables,
312                     true,HuginBase::StandardImageVariableGroups::getLensVariables()));
313                 cmds.push_back(new PanoCommand::ChangeImageHFOVCmd(*pano, images, newFov));
314             };
315             std::vector<double> dist;
316             if(lensDB.GetDistortion(lensname, focal, dist))
317             {
318                 if (dist.size() == 3)
319                 {
320                     dist.push_back(1.0 - dist[0] - dist[1] - dist[2]);
321                     std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> linkedVariables;
322                     linkedVariables.insert(HuginBase::ImageVariableGroup::IVE_RadialDistortion);
323                     cmds.push_back(new PanoCommand::ChangePartImagesLinkingCmd(*pano, images, linkedVariables,
324                         true, HuginBase::StandardImageVariableGroups::getLensVariables()));
325                     cmds.push_back(new PanoCommand::ChangeImageRadialDistortionCmd(*pano, images, dist));
326                 };
327             };
328         };
329         if(dlg.GetLoadVignetting())
330         {
331             std::vector<double> vig;
332             if (lensDB.GetVignetting(lensname, focal, dlg.GetAperture(), dlg.GetSubjectDistance(), vig))
333             {
334                 if (vig.size() == 4)
335                 {
336                     std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> linkedVariables;
337                     linkedVariables.insert(HuginBase::ImageVariableGroup::IVE_RadialVigCorrCoeff);
338                     cmds.push_back(new PanoCommand::ChangePartImagesLinkingCmd(*pano, images, linkedVariables,
339                         true, HuginBase::StandardImageVariableGroups::getLensVariables()));
340                     cmds.push_back(new PanoCommand::ChangeImageRadialVigCorrCoeffCmd(*pano, images, vig));
341                 };
342             };
343         };
344         cmd=new PanoCommand::CombinedPanoCommand(*pano, cmds);
345         return true;
346     };
347     return false;
348 };
349 
350 /** dialog for saving lens parameter into lens database */
351 class SaveLensDBDialog : public wxDialog
352 {
353 public:
354     /** Constructor, read from xrc ressource; restore last uses settings, size and position */
355     explicit SaveLensDBDialog(wxWindow *parent);
356     void SetCameraMaker(std::string maker);
357     std::string GetCameraMaker() const;
358     void SetCameraModel(std::string model);
359     std::string GetCameraModel() const;
360     void SetLensName(std::string lensname);
361     std::string GetLensName() const;
362     std::string GetLensMaker() const;
363     void SetFocalLength(double focal);
364     double GetFocalLength() const;
365     void SetAperture(double aperture);
366     double GetAperture() const;
367     void SetSubjectDistance(double distance);
368     double GetSubjectDistance() const;
369     bool GetSaveDistortion() const;
370     bool GetSaveVignetting() const;
371     void DeactivateSaveVignetting();
372 
373 protected:
374     /** Saves current state of all checkboxes when closing dialog with Ok */
375     void OnOk(wxCommandEvent & e);
376     void OnCheckChanged(wxCommandEvent & e);
377 
378 private:
379     wxCheckBox *m_saveDistortion;
380     wxCheckBox *m_saveVignetting;
381     double m_focal;
382     double m_aperture;
383     double m_distance;
384     DECLARE_EVENT_TABLE()
385 };
386 
BEGIN_EVENT_TABLE(SaveLensDBDialog,wxDialog)387 BEGIN_EVENT_TABLE(SaveLensDBDialog,wxDialog)
388     EVT_BUTTON(wxID_OK, SaveLensDBDialog::OnOk)
389     EVT_CHECKBOX(XRCID("save_lens_distortion"), SaveLensDBDialog::OnCheckChanged)
390     EVT_CHECKBOX(XRCID("save_lens_vignetting"), SaveLensDBDialog::OnCheckChanged)
391 END_EVENT_TABLE()
392 
393 SaveLensDBDialog::SaveLensDBDialog(wxWindow *parent)
394 {
395     // load our children. some children might need special
396     // initialization. this will be done later.
397     wxXmlResource::Get()->LoadDialog(this, parent, wxT("save_lens_dlg"));
398 
399     //set parameters
400     wxConfigBase * config = wxConfigBase::Get();
401     // get display size
402     int dx,dy;
403     wxDisplaySize(&dx,&dy);
404     int w = config->Read(wxT("/SaveLensDialog/width"),-1l);
405     int h = config->Read(wxT("/SaveLensDialog/height"),-1l);
406     if (w>0 && w<=dx && h>0 && h<=dy)
407     {
408         SetClientSize(w,h);
409     }
410     else
411     {
412         Fit();
413     }
414     //position
415     int x = config->Read(wxT("/SaveLensDialog/positionX"),-1l);
416     int y = config->Read(wxT("/SaveLensDialog/positionY"),-1l);
417     if ( y >= 0 && x >= 0)
418     {
419         this->Move(x, y);
420     }
421     else
422     {
423         this->Move(0, 44);
424     };
425     bool b;
426     config->Read(wxT("/SaveLensDialog/saveDistortion"),&b,true);
427     m_saveDistortion=XRCCTRL(*this,"save_lens_distortion",wxCheckBox);
428     m_saveDistortion->SetValue(b);
429     config->Read(wxT("/SaveLensDialog/saveVignetting"),&b,true);
430     m_saveVignetting=XRCCTRL(*this,"save_lens_vignetting",wxCheckBox);
431     m_saveVignetting->SetValue(b);
432 };
433 
SetCameraMaker(std::string maker)434 void SaveLensDBDialog::SetCameraMaker(std::string maker)
435 {
436     if(!maker.empty())
437     {
438         XRCCTRL(*this,"save_lens_camera_maker",wxTextCtrl)->SetValue(wxString(maker.c_str(), wxConvLocal));
439     };
440 };
441 
GetCameraMaker() const442 std::string SaveLensDBDialog::GetCameraMaker() const
443 {
444     return std::string(XRCCTRL(*this,"save_lens_camera_maker",wxTextCtrl)->GetValue().Trim().mb_str(wxConvLocal));
445 };
446 
SetCameraModel(std::string model)447 void SaveLensDBDialog::SetCameraModel(std::string model)
448 {
449     if(!model.empty())
450     {
451         XRCCTRL(*this,"save_lens_camera_model",wxTextCtrl)->SetValue(wxString(model.c_str(), wxConvLocal));
452     };
453 };
454 
GetCameraModel() const455 std::string SaveLensDBDialog::GetCameraModel() const
456 {
457     return std::string(XRCCTRL(*this,"save_lens_camera_model",wxTextCtrl)->GetValue().Trim().mb_str(wxConvLocal));
458 };
459 
SetLensName(std::string lensname)460 void SaveLensDBDialog::SetLensName(std::string lensname)
461 {
462     if(!lensname.empty())
463     {
464         XRCCTRL(*this,"save_lens_name",wxTextCtrl)->SetValue(wxString(lensname.c_str(), wxConvLocal));
465     };
466 };
467 
GetLensName() const468 std::string SaveLensDBDialog::GetLensName() const
469 {
470     return std::string(XRCCTRL(*this,"save_lens_name",wxTextCtrl)->GetValue().Trim().mb_str(wxConvLocal));
471 };
472 
GetLensMaker() const473 std::string SaveLensDBDialog::GetLensMaker() const
474 {
475     return std::string(XRCCTRL(*this,"save_lens_maker",wxTextCtrl)->GetValue().Trim().mb_str(wxConvLocal));
476 };
477 
SetFocalLength(double focal)478 void SaveLensDBDialog::SetFocalLength(double focal)
479 {
480     m_focal=focal;
481     XRCCTRL(*this,"save_lens_focallength",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_focal,1));
482 };
483 
GetFocalLength() const484 double SaveLensDBDialog::GetFocalLength() const
485 {
486     return m_focal;
487 };
488 
SetAperture(double aperture)489 void SaveLensDBDialog::SetAperture(double aperture)
490 {
491     m_aperture=aperture;
492     XRCCTRL(*this,"save_lens_aperture",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_aperture,1));
493 };
494 
GetAperture() const495 double SaveLensDBDialog::GetAperture() const
496 {
497     return m_aperture;
498 };
499 
SetSubjectDistance(double distance)500 void SaveLensDBDialog::SetSubjectDistance(double distance)
501 {
502     m_distance=distance;
503     XRCCTRL(*this,"save_lens_distance",wxTextCtrl)->SetValue(hugin_utils::doubleTowxString(m_distance,0));
504 };
505 
GetSubjectDistance() const506 double SaveLensDBDialog::GetSubjectDistance() const
507 {
508     return m_distance;
509 };
510 
GetSaveDistortion() const511 bool SaveLensDBDialog::GetSaveDistortion() const
512 {
513     return m_saveDistortion->GetValue();
514 };
515 
GetSaveVignetting() const516 bool SaveLensDBDialog::GetSaveVignetting() const
517 {
518     return m_saveVignetting->GetValue();
519 };
520 
DeactivateSaveVignetting()521 void SaveLensDBDialog::DeactivateSaveVignetting()
522 {
523     m_saveVignetting->SetValue(false);
524     m_saveVignetting->Disable();
525 };
526 
OnOk(wxCommandEvent & e)527 void SaveLensDBDialog::OnOk(wxCommandEvent & e)
528 {
529     if(!m_saveDistortion->GetValue() && !m_saveVignetting->GetValue())
530     {
531         return;
532     };
533     if(GetLensName().empty() && (GetCameraMaker().empty() || GetCameraModel().empty()))
534     {
535         wxMessageBox(_("There is too little information for saving data into database. Please check your input!"),_("Warning"),wxOK|wxICON_ERROR,this);
536         return;
537     };
538     if(!str2double(this,XRCCTRL(*this,"save_lens_focallength",wxTextCtrl)->GetValue(),m_focal))
539     {
540         return;
541     };
542     if(m_saveVignetting->GetValue())
543     {
544         wxString val = XRCCTRL(*this, "save_lens_aperture", wxTextCtrl)->GetValue().Trim();
545         if (val.empty())
546         {
547             m_aperture = 0;
548         }
549         else
550         {
551             if (!str2double(this, val, m_aperture))
552             {
553                 return;
554             };
555         };
556         val = XRCCTRL(*this, "save_lens_distance", wxTextCtrl)->GetValue().Trim();
557         if (val.empty())
558         {
559             m_distance = 0;
560         }
561         else
562         {
563             if (!str2double(this, val, m_distance))
564             {
565                 return;
566             };
567         };
568     };
569     //store selected options
570     wxConfigBase * config = wxConfigBase::Get();
571     wxSize sz = this->GetClientSize();
572     config->Write(wxT("/SaveLensDialog/width"), sz.GetWidth());
573     config->Write(wxT("/SaveLensDialog/height"), sz.GetHeight());
574     wxPoint ps = this->GetPosition();
575     config->Write(wxT("/SaveLensDialog/positionX"), ps.x);
576     config->Write(wxT("/SaveLensDialog/positionY"), ps.y);
577     config->Write(wxT("/SaveLensDialog/saveDistortion"),m_saveDistortion->GetValue());
578     if(m_saveVignetting->IsEnabled())
579     {
580         config->Write(wxT("/SaveLensDialog/saveVignetting"),m_saveVignetting->GetValue());
581     };
582     config->Flush();
583     e.Skip();
584 };
585 
OnCheckChanged(wxCommandEvent & e)586 void SaveLensDBDialog::OnCheckChanged(wxCommandEvent & e)
587 {
588     XRCCTRL(*this,"wxID_OK",wxButton)->Enable(m_saveDistortion->GetValue() || m_saveVignetting->GetValue());
589 };
590 
SaveLensParameters(wxWindow * parent,const HuginBase::SrcPanoImage & img,bool includeVignetting)591 bool SaveLensParameters(wxWindow * parent, const HuginBase::SrcPanoImage& img, bool includeVignetting)
592 {
593     HuginBase::LensDB::LensDB& lensDB=HuginBase::LensDB::LensDB::GetSingleton();
594     // show dialog
595     SaveLensDBDialog lensDlg(parent);
596     lensDlg.SetCameraMaker(img.getExifMake());
597     lensDlg.SetCameraModel(img.getExifModel());
598     lensDlg.SetLensName(img.getDBLensName());
599     lensDlg.SetFocalLength(img.getExifFocalLength());
600     lensDlg.SetAperture(img.getExifAperture());
601     lensDlg.SetSubjectDistance(img.getExifDistance());
602     if (!includeVignetting)
603     {
604         lensDlg.DeactivateSaveVignetting();
605     };
606     if (lensDlg.ShowModal() != wxID_OK)
607     {
608         return false;
609     };
610     const std::string camMaker = lensDlg.GetCameraMaker();
611     const std::string camModel = lensDlg.GetCameraModel();
612     std::string lensname = lensDlg.GetLensName();
613     const double focal = lensDlg.GetFocalLength();
614     if (lensname.empty())
615     {
616         //empty lensname, assuming it is a compact camera
617         lensname = camMaker + "|" + camModel;
618     };
619     // unknown crop factor, remember it
620     if (img.getExifCropFactor() < 0.1 && !camMaker.empty() && !camModel.empty())
621     {
622         lensDB.SaveCameraCrop(camMaker, camModel, img.getCropFactor());
623     };
624     if (lensDlg.GetSaveDistortion())
625     {
626         const double newFocallength = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getCropFactor(), img.getSize());
627         const double newHFOV = HuginBase::SrcPanoImage::calcHFOV(img.getProjection(), newFocallength, img.getCropFactor(), vigra::Size2D(3000, 2000));
628         // save information with higher weight
629         if (!lensDB.SaveLensFov(lensname, lensDlg.GetFocalLength(), newHFOV, 75))
630         {
631             wxMessageBox(_("Could not save information into database."), _("Error"), wxOK | wxICON_ERROR, parent);
632             return false;
633         };
634         if (!lensDB.SaveDistortion(lensname, focal, img.getRadialDistortion(), 75))
635         {
636             wxMessageBox(_("Could not save information into database."), _("Error"), wxOK | wxICON_ERROR, parent);
637             return false;
638         };
639     };
640     if(lensDlg.GetSaveVignetting())
641     {
642         if (!lensDB.SaveVignetting(lensname, focal, lensDlg.GetAperture(), lensDlg.GetSubjectDistance(), img.getRadialVigCorrCoeff(), 75))
643         {
644             wxMessageBox(_("Could not save information into database."), _("Error"), wxOK | wxICON_ERROR, parent);
645             return false;
646         };
647     };
648     return true;
649 };
650 
651