00001
00002
00028 #include <config.h>
00029 #include <wx/stdpaths.h>
00030
00031 #include "panoinc_WX.h"
00032 #include "panoinc.h"
00033 #include "base_wx/platform.h"
00034
00035
00036 #include <hugin/config_defaults.h>
00037
00038 #include "PT/Stitcher.h"
00039 #include "base_wx/wxPlatform.h"
00040
00041 extern "C" {
00042 #include <pano13/queryfeature.h>
00043 }
00044
00045 #include "hugin/CommandHistory.h"
00046 #include "hugin/CPImageCtrl.h"
00047 #include "hugin/CPImagesComboBox.h"
00048 #include "hugin/PanoPanel.h"
00049 #include "hugin/MainFrame.h"
00050 #include "hugin/huginApp.h"
00051 #include "hugin/HDRMergeOptionDialog.h"
00052 #include "hugin/TextKillFocusHandler.h"
00053 #include "base_wx/MyProgressDialog.h"
00054 #include "hugin/config_defaults.h"
00055 #include "base_wx/platform.h"
00056 #include "base_wx/huginConfig.h"
00057 #include "algorithms/basic/LayerStacks.h"
00058
00059 #define WX_BROKEN_SIZER_UNKNOWN
00060
00061 using namespace PT;
00062 using namespace std;
00063 using namespace hugin_utils;
00064
00065 BEGIN_EVENT_TABLE(PanoPanel, wxPanel)
00066 EVT_CHOICE ( XRCID("pano_choice_pano_type"),PanoPanel::ProjectionChanged )
00067 EVT_TEXT_ENTER( XRCID("pano_text_hfov"),PanoPanel::HFOVChanged )
00068 EVT_TEXT_ENTER( XRCID("pano_text_vfov"),PanoPanel::VFOVChanged )
00069 EVT_BUTTON ( XRCID("pano_button_calc_fov"), PanoPanel::DoCalcFOV)
00070 EVT_TEXT_ENTER ( XRCID("pano_val_width"),PanoPanel::WidthChanged )
00071 EVT_TEXT_ENTER ( XRCID("pano_val_height"),PanoPanel::HeightChanged )
00072 EVT_TEXT_ENTER ( XRCID("pano_val_roi_top"),PanoPanel::ROIChanged )
00073 EVT_TEXT_ENTER ( XRCID("pano_val_roi_bottom"),PanoPanel::ROIChanged )
00074 EVT_TEXT_ENTER ( XRCID("pano_val_roi_left"),PanoPanel::ROIChanged )
00075 EVT_TEXT_ENTER ( XRCID("pano_val_roi_right"),PanoPanel::ROIChanged )
00076 EVT_BUTTON ( XRCID("pano_button_opt_width"), PanoPanel::DoCalcOptimalWidth)
00077 EVT_BUTTON ( XRCID("pano_button_opt_roi"), PanoPanel::DoCalcOptimalROI)
00078 EVT_BUTTON ( XRCID("pano_button_stitch"),PanoPanel::OnDoStitch )
00079
00080 EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_blended"), PanoPanel::OnOutputFilesChanged)
00081 EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_layers"), PanoPanel::OnOutputFilesChanged)
00082 EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_layers"), PanoPanel::OnOutputFilesChanged)
00083 EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_blended"), PanoPanel::OnOutputFilesChanged)
00084 EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_layers_fused"), PanoPanel::OnOutputFilesChanged)
00085 EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_stacks"), PanoPanel::OnOutputFilesChanged)
00086 EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_remapped"), PanoPanel::OnOutputFilesChanged)
00087 EVT_CHECKBOX ( XRCID("pano_cb_hdr_output_blended"), PanoPanel::OnOutputFilesChanged)
00088 EVT_CHECKBOX ( XRCID("pano_cb_hdr_output_stacks"), PanoPanel::OnOutputFilesChanged)
00089 EVT_CHECKBOX ( XRCID("pano_cb_hdr_output_layers"), PanoPanel::OnOutputFilesChanged)
00090
00091 EVT_CHOICE ( XRCID("pano_choice_remapper"),PanoPanel::RemapperChanged )
00092 EVT_BUTTON ( XRCID("pano_button_remapper_opts"),PanoPanel::OnRemapperOptions )
00093
00094 EVT_CHOICE ( XRCID("pano_choice_fusion"),PanoPanel::FusionChanged )
00095 EVT_BUTTON ( XRCID("pano_button_fusion_opts"),PanoPanel::OnFusionOptions )
00096
00097 EVT_CHOICE ( XRCID("pano_choice_hdrmerge"),PanoPanel::HDRMergeChanged )
00098 EVT_BUTTON ( XRCID("pano_button_hdrmerge_opts"),PanoPanel::OnHDRMergeOptions )
00099
00100 EVT_CHOICE ( XRCID("pano_choice_blender"),PanoPanel::BlenderChanged )
00101 EVT_BUTTON ( XRCID("pano_button_blender_opts"),PanoPanel::OnBlenderOptions )
00102
00103 EVT_CHOICE ( XRCID("pano_choice_file_format"),PanoPanel::FileFormatChanged )
00104 EVT_CHOICE ( XRCID("pano_choice_hdr_file_format"),PanoPanel::HDRFileFormatChanged )
00105
00106 EVT_TEXT_ENTER ( XRCID("pano_output_normal_opts_jpeg_quality"),PanoPanel::OnJPEGQualityText )
00107 EVT_CHOICE ( XRCID("pano_output_normal_opts_tiff_compression"),PanoPanel::OnNormalTIFFCompression)
00108 EVT_CHOICE ( XRCID("pano_output_hdr_opts_tiff_compression"),PanoPanel::OnHDRTIFFCompression)
00109
00110 END_EVENT_TABLE()
00111
00112 PanoPanel::PanoPanel()
00113 : pano(0), updatesDisabled(false), m_guiLevel(GUI_SIMPLE)
00114 {
00115
00116 }
00117
00118 bool PanoPanel::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
00119 long style, const wxString& name)
00120 {
00121 if (! wxPanel::Create(parent, id, pos, size, style, name)) {
00122 return false;
00123 }
00124
00125 wxXmlResource::Get()->LoadPanel(this, wxT("panorama_panel"));
00126 wxPanel * panel = XRCCTRL(*this, "panorama_panel", wxPanel);
00127
00128 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
00129 topsizer->Add(panel, 1, wxEXPAND, 0);
00130 SetSizer(topsizer);
00131
00132
00133
00134 m_ProjectionChoice = XRCCTRL(*this, "pano_choice_pano_type" ,wxChoice);
00135 DEBUG_ASSERT(m_ProjectionChoice);
00136
00137 m_keepViewOnResize = true;
00138 m_hasStacks=false;
00139
00140 #ifdef ThisNeverHappens
00141
00142 wxLogMessage(_("Fisheye"));
00143 wxLogMessage(_("Stereographic"));
00144 wxLogMessage(_("Mercator"));
00145 wxLogMessage(_("Trans Mercator"));
00146 wxLogMessage(_("Sinusoidal"));
00147 wxLogMessage(_("Lambert Cylindrical Equal Area"));
00148 wxLogMessage(_("Lambert Equal Area Azimuthal"));
00149 wxLogMessage(_("Albers Equal Area Conic"));
00150 wxLogMessage(_("Miller Cylindrical"));
00151 wxLogMessage(_("Panini"));
00152 wxLogMessage(_("Architectural"));
00153 wxLogMessage(_("Orthographic"));
00154 wxLogMessage(_("Equisolid"));
00155 wxLogMessage(_("Equirectangular Panini"));
00156 wxLogMessage(_("Biplane"));
00157 wxLogMessage(_("Triplane"));
00158 wxLogMessage(_("Panini General"));
00159 wxLogMessage(_("Thoby Projection"));
00160 wxLogMessage(_("Hammer-Aitoff Equal Area"));
00161 #endif
00162
00163
00164 int nP = panoProjectionFormatCount();
00165 for(int n=0; n < nP; n++) {
00166 pano_projection_features proj;
00167 if (panoProjectionFeaturesQuery(n, &proj)) {
00168 wxString str2(proj.name, wxConvLocal);
00169 m_ProjectionChoice->Append(wxGetTranslation(str2));
00170 }
00171 }
00172 m_HFOVText = XRCCTRL(*this, "pano_text_hfov" ,wxTextCtrl);
00173 DEBUG_ASSERT(m_HFOVText);
00174 m_CalcHFOVButton = XRCCTRL(*this, "pano_button_calc_fov" ,wxButton);
00175 DEBUG_ASSERT(m_CalcHFOVButton);
00176 m_HFOVText->PushEventHandler(new TextKillFocusHandler(this));
00177 m_VFOVText = XRCCTRL(*this, "pano_text_vfov" ,wxTextCtrl);
00178 DEBUG_ASSERT(m_VFOVText);
00179 m_VFOVText->PushEventHandler(new TextKillFocusHandler(this));
00180
00181
00182 m_WidthTxt = XRCCTRL(*this, "pano_val_width", wxTextCtrl);
00183 DEBUG_ASSERT(m_WidthTxt);
00184 m_WidthTxt->PushEventHandler(new TextKillFocusHandler(this));
00185 m_CalcOptWidthButton = XRCCTRL(*this, "pano_button_opt_width" ,wxButton);
00186 DEBUG_ASSERT(m_CalcOptWidthButton);
00187
00188 m_HeightTxt = XRCCTRL(*this, "pano_val_height", wxTextCtrl);
00189 DEBUG_ASSERT(m_HeightTxt);
00190 m_HeightTxt->PushEventHandler(new TextKillFocusHandler(this));
00191
00192 m_ROILeftTxt = XRCCTRL(*this, "pano_val_roi_left", wxTextCtrl);
00193 DEBUG_ASSERT(m_ROILeftTxt);
00194 m_ROILeftTxt->PushEventHandler(new TextKillFocusHandler(this));
00195
00196 m_ROIRightTxt = XRCCTRL(*this, "pano_val_roi_right", wxTextCtrl);
00197 DEBUG_ASSERT(m_ROIRightTxt);
00198 m_ROIRightTxt->PushEventHandler(new TextKillFocusHandler(this));
00199
00200 m_ROITopTxt = XRCCTRL(*this, "pano_val_roi_top", wxTextCtrl);
00201 DEBUG_ASSERT(m_ROITopTxt);
00202 m_ROITopTxt->PushEventHandler(new TextKillFocusHandler(this));
00203
00204 m_ROIBottomTxt = XRCCTRL(*this, "pano_val_roi_bottom", wxTextCtrl);
00205 DEBUG_ASSERT(m_ROIBottomTxt);
00206 m_ROIBottomTxt->PushEventHandler(new TextKillFocusHandler(this));
00207
00208 m_CalcOptROIButton = XRCCTRL(*this, "pano_button_opt_roi" ,wxButton);
00209 DEBUG_ASSERT(m_CalcOptROIButton);
00210
00211 m_RemapperChoice = XRCCTRL(*this, "pano_choice_remapper", wxChoice);
00212 DEBUG_ASSERT(m_RemapperChoice);
00213 m_FusionChoice = XRCCTRL(*this, "pano_choice_fusion", wxChoice);
00214 DEBUG_ASSERT(m_FusionChoice);
00215 m_HDRMergeChoice = XRCCTRL(*this, "pano_choice_hdrmerge", wxChoice);
00216 DEBUG_ASSERT(m_HDRMergeChoice);
00217 m_BlenderChoice = XRCCTRL(*this, "pano_choice_blender", wxChoice);
00218 DEBUG_ASSERT(m_BlenderChoice);
00219
00220 m_StitchButton = XRCCTRL(*this, "pano_button_stitch", wxButton);
00221 DEBUG_ASSERT(m_StitchButton);
00222
00223 m_FileFormatChoice = XRCCTRL(*this, "pano_choice_file_format", wxChoice);
00224 DEBUG_ASSERT(m_FileFormatChoice);
00225 m_FileFormatOptionsLabel = XRCCTRL(*this, "pano_output_ldr_format_options_label", wxStaticText);
00226
00227 m_FileFormatJPEGQualityText = XRCCTRL(*this, "pano_output_normal_opts_jpeg_quality", wxTextCtrl);
00228 DEBUG_ASSERT(m_FileFormatJPEGQualityText);
00229 m_FileFormatJPEGQualityText->PushEventHandler(new TextKillFocusHandler(this));
00230
00231 m_FileFormatTIFFCompChoice = XRCCTRL(*this, "pano_output_normal_opts_tiff_compression", wxChoice);
00232 DEBUG_ASSERT(m_FileFormatTIFFCompChoice);
00233
00234 m_HDRFileFormatChoice = XRCCTRL(*this, "pano_choice_hdr_file_format", wxChoice);
00235 DEBUG_ASSERT(m_HDRFileFormatChoice);
00236 m_HDRFileFormatLabelTIFFCompression = XRCCTRL(*this, "pano_output_hdr_opts_tiff_compression_label", wxStaticText);
00237 DEBUG_ASSERT(m_HDRFileFormatLabelTIFFCompression);
00238 m_FileFormatHDRTIFFCompChoice = XRCCTRL(*this, "pano_output_hdr_opts_tiff_compression", wxChoice);
00239 DEBUG_ASSERT(m_FileFormatHDRTIFFCompChoice);
00240
00241 m_pano_ctrls = XRCCTRL(*this, "pano_controls_panel", wxScrolledWindow);
00242 DEBUG_ASSERT(m_pano_ctrls);
00243 m_pano_ctrls->SetSizeHints(20, 20);
00244 m_pano_ctrls->FitInside();
00245 m_pano_ctrls->SetScrollRate(10, 10);
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 DEBUG_TRACE("")
00257 return true;
00258 }
00259
00260 void PanoPanel::Init(Panorama * panorama)
00261 {
00262 pano = panorama;
00263
00264 pano->addObserver(this);
00265 panoramaChanged(*panorama);
00266 }
00267
00268 PanoPanel::~PanoPanel(void)
00269 {
00270 DEBUG_TRACE("dtor");
00271 wxConfigBase::Get()->Write(wxT("Stitcher/DefaultRemapper"),m_RemapperChoice->GetSelection());
00272
00273 m_HFOVText->PopEventHandler(true);
00274 m_VFOVText->PopEventHandler(true);
00275 m_WidthTxt->PopEventHandler(true);
00276 m_HeightTxt->PopEventHandler(true);
00277 m_ROILeftTxt->PopEventHandler(true);
00278 m_ROIRightTxt->PopEventHandler(true);
00279 m_ROITopTxt->PopEventHandler(true);
00280 m_ROIBottomTxt->PopEventHandler(true);
00281 m_FileFormatJPEGQualityText->PopEventHandler(true);
00282 pano->removeObserver(this);
00283 DEBUG_TRACE("dtor end");
00284 }
00285
00286
00287 void PanoPanel::panoramaChanged (PT::Panorama &pano)
00288 {
00289 DEBUG_TRACE("");
00290
00291 #ifdef STACK_CHECK //Disabled for 0.7.0 release
00292 const bool hasStacks = StackCheck(pano);
00293 #else
00294 const bool hasStacks = false;
00295 #endif
00296
00297 PanoramaOptions opt = pano.getOptions();
00298
00299
00300 UpdateDisplay(opt,hasStacks);
00301
00302 m_oldOpt = opt;
00303 }
00304
00305
00306 bool PanoPanel::StackCheck(PT::Panorama &pano)
00307 {
00308 DEBUG_TRACE("");
00309 PanoramaOptions opt = pano.getOptions();
00310
00311
00312 UIntSet activeImages = pano.getActiveImages();
00313 UIntSet images = getImagesinROI(pano,activeImages);
00314 vector<UIntSet> hdrStacks = HuginBase::getHDRStacks(pano, images, pano.getOptions());
00315 DEBUG_DEBUG(hdrStacks.size() << ": HDR stacks detected");
00316 const bool hasStacks = (hdrStacks.size() != activeImages.size());
00317
00318
00319 bool isChanged = (hasStacks != m_hasStacks);
00320 if (isChanged) {
00321 if (hasStacks) {
00322
00323 opt.outputLDRBlended = false;
00324 opt.outputLDRLayers = false;
00325
00326 if (!(opt.outputLDRExposureBlended ||
00327 opt.outputLDRExposureLayers ||
00328 opt.outputLDRExposureRemapped ||
00329 opt.outputHDRBlended ||
00330 opt.outputHDRStacks ||
00331 opt.outputHDRLayers)) {
00332 opt.outputLDRExposureBlended = true;
00333 }
00334 } else {
00335
00336 opt.outputLDRExposureBlended = false;
00337 opt.outputLDRExposureLayers = false;
00338 opt.outputLDRExposureRemapped = false;
00339 opt.outputHDRBlended = false;
00340 opt.outputHDRStacks = false;
00341 opt.outputHDRLayers = false;
00342
00343 if (!(opt.outputLDRBlended || opt.outputLDRLayers)) {
00344 opt.outputLDRBlended = true;
00345 }
00346 }
00347 pano.setOptions(opt);
00348 }
00349
00350 m_hasStacks = hasStacks;
00351
00352 return hasStacks;
00353 }
00354
00355
00356 void PanoPanel::UpdateDisplay(const PanoramaOptions & opt, const bool hasStacks)
00357 {
00358
00359
00360
00361
00362 m_ProjectionChoice->SetSelection(opt.getProjection());
00363 m_keepViewOnResize = opt.fovCalcSupported(opt.getProjection());
00364
00365 std::string val;
00366 val = doubleToString(opt.getHFOV(),1);
00367 m_HFOVText->SetValue(wxString(val.c_str(), wxConvLocal));
00368 val = doubleToString(opt.getVFOV(),1);
00369 m_VFOVText->SetValue(wxString(val.c_str(), wxConvLocal));
00370
00371
00372 bool hasImages = pano->getActiveImages().size() > 0;
00373 m_VFOVText->Enable(m_keepViewOnResize);
00374 m_CalcOptWidthButton->Enable(m_keepViewOnResize && hasImages);
00375 m_CalcHFOVButton->Enable(m_keepViewOnResize && hasImages);
00376 m_CalcOptROIButton->Enable(hasImages);
00377
00378 m_WidthTxt->SetValue(wxString::Format(wxT("%d"), opt.getWidth()));
00379 m_HeightTxt->SetValue(wxString::Format(wxT("%d"), opt.getHeight()));
00380
00381 m_ROILeftTxt->SetValue(wxString::Format(wxT("%d"), opt.getROI().left() ));
00382 m_ROIRightTxt->SetValue(wxString::Format(wxT("%d"), opt.getROI().right() ));
00383 m_ROITopTxt->SetValue(wxString::Format(wxT("%d"), opt.getROI().top() ));
00384 m_ROIBottomTxt->SetValue(wxString::Format(wxT("%d"), opt.getROI().bottom() ));
00385
00386
00387 XRCCTRL(*this, "pano_cb_ldr_output_blended", wxCheckBox)->SetValue(opt.outputLDRBlended);
00388 XRCCTRL(*this, "pano_cb_ldr_output_exposure_blended", wxCheckBox)->SetValue(opt.outputLDRExposureBlended);
00389 XRCCTRL(*this, "pano_cb_ldr_output_exposure_layers_fused", wxCheckBox)->SetValue(opt.outputLDRExposureLayersFused);
00390 XRCCTRL(*this, "pano_cb_hdr_output_blended", wxCheckBox)->SetValue(opt.outputHDRBlended);
00391 XRCCTRL(*this, "pano_cb_hdr_output_blended", wxCheckBox)->Show(opt.outputHDRBlended || m_guiLevel>GUI_SIMPLE);
00392
00393
00394 XRCCTRL(*this, "pano_text_remapped_images", wxStaticText)->Show(opt.outputLDRLayers || opt.outputLDRExposureRemapped || opt.outputHDRLayers || m_guiLevel>GUI_SIMPLE);
00395 XRCCTRL(*this, "pano_cb_ldr_output_layers", wxCheckBox)->SetValue(opt.outputLDRLayers);
00396 XRCCTRL(*this, "pano_cb_ldr_output_layers", wxCheckBox)->Show(opt.outputLDRLayers || m_guiLevel>GUI_SIMPLE);
00397 XRCCTRL(*this, "pano_cb_ldr_output_exposure_remapped", wxCheckBox)->SetValue(opt.outputLDRExposureRemapped);
00398 XRCCTRL(*this, "pano_cb_ldr_output_exposure_remapped", wxCheckBox)->Show(opt.outputLDRExposureRemapped || m_guiLevel>GUI_SIMPLE);
00399 XRCCTRL(*this, "pano_cb_hdr_output_layers", wxCheckBox)->SetValue(opt.outputHDRLayers);
00400 XRCCTRL(*this, "pano_cb_hdr_output_layers", wxCheckBox)->Show(opt.outputHDRLayers || m_guiLevel>GUI_SIMPLE);
00401
00402
00403 XRCCTRL(*this, "pano_text_stacks", wxStaticText)->Show(opt.outputHDRStacks || opt.outputLDRStacks || m_guiLevel>GUI_SIMPLE);
00404 XRCCTRL(*this, "pano_cb_ldr_output_stacks", wxCheckBox)->SetValue(opt.outputLDRStacks);
00405 XRCCTRL(*this, "pano_cb_ldr_output_stacks", wxCheckBox)->Show(opt.outputLDRStacks || m_guiLevel>GUI_SIMPLE);
00406 XRCCTRL(*this, "pano_cb_hdr_output_stacks", wxCheckBox)->SetValue(opt.outputHDRStacks);
00407 XRCCTRL(*this, "pano_cb_hdr_output_stacks", wxCheckBox)->Show(opt.outputHDRStacks || m_guiLevel>GUI_SIMPLE);
00408
00409
00410 XRCCTRL(*this, "pano_text_layers", wxStaticText)->Show(opt.outputLDRExposureLayers || m_guiLevel>GUI_SIMPLE);
00411 XRCCTRL(*this, "pano_cb_ldr_output_exposure_layers", wxCheckBox)->SetValue(opt.outputLDRExposureLayers);
00412 XRCCTRL(*this, "pano_cb_ldr_output_exposure_layers", wxCheckBox)->Show(opt.outputLDRExposureLayers || m_guiLevel>GUI_SIMPLE);
00413
00414 bool anyOutputSelected = (opt.outputLDRBlended ||
00415 opt.outputLDRLayers ||
00416 opt.outputLDRExposureLayers ||
00417 opt.outputLDRExposureBlended ||
00418 opt.outputLDRExposureLayersFused ||
00419 opt.outputLDRExposureRemapped ||
00420 opt.outputLDRStacks ||
00421 opt.outputHDRBlended ||
00422 opt.outputHDRStacks ||
00423 opt.outputHDRLayers);
00424
00425
00426 bool any_output_possible = hasImages && anyOutputSelected;
00427 m_StitchButton->Enable(any_output_possible);
00428
00429 #ifdef STACK_CHECK //Disabled for 0.7.0 release
00430 if (hasStacks) {
00431 XRCCTRL(*this,"pano_cb_ldr_output_blended",wxCheckBox)->Disable();
00432 XRCCTRL(*this,"pano_cb_ldr_output_layers",wxCheckBox)->Disable();
00433
00434 XRCCTRL(*this,"pano_cb_ldr_output_exposure_layers",wxCheckBox)->Enable();
00435 XRCCTRL(*this,"pano_cb_ldr_output_exposure_blended",wxCheckBox)->Enable();
00436 XRCCTRL(*this,"pano_cb_ldr_output_exposure_remapped",wxCheckBox)->Enable();
00437 XRCCTRL(*this,"pano_cb_hdr_output_blended",wxCheckBox)->Enable();
00438 XRCCTRL(*this,"pano_cb_hdr_output_stacks",wxCheckBox)->Enable();
00439 XRCCTRL(*this,"pano_cb_hdr_output_layers",wxCheckBox)->Enable();
00440
00441 } else {
00442 XRCCTRL(*this,"pano_cb_ldr_output_blended",wxCheckBox)->Enable();
00443 XRCCTRL(*this,"pano_cb_ldr_output_layers",wxCheckBox)->Enable();
00444
00445 XRCCTRL(*this,"pano_cb_ldr_output_exposure_layers",wxCheckBox)->Disable();
00446 XRCCTRL(*this,"pano_cb_ldr_output_exposure_blended",wxCheckBox)->Disable();
00447 XRCCTRL(*this,"pano_cb_ldr_output_exposure_remapped",wxCheckBox)->Disable();
00448
00449 XRCCTRL(*this,"pano_cb_hdr_output_blended",wxCheckBox)->Disable();
00450 XRCCTRL(*this,"pano_cb_hdr_output_stacks",wxCheckBox)->Disable();
00451 XRCCTRL(*this,"pano_cb_hdr_output_layers",wxCheckBox)->Disable();
00452 }
00453 #endif
00454
00455 m_RemapperChoice->Show(m_guiLevel>GUI_SIMPLE);
00456 m_RemapperChoice->Enable(m_guiLevel>GUI_SIMPLE);
00457 XRCCTRL(*this, "pano_button_remapper_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00458 XRCCTRL(*this, "pano_button_remapper_opts", wxButton)->Enable(m_guiLevel>GUI_SIMPLE);
00459 XRCCTRL(*this, "pano_text_remapper", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00460 XRCCTRL(*this, "pano_text_processing", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00461
00462 bool blenderEnabled = (opt.outputLDRBlended ||
00463 opt.outputLDRExposureBlended ||
00464 opt.outputLDRExposureLayersFused ||
00465 opt.outputLDRExposureLayers ||
00466 opt.outputHDRBlended ) && m_guiLevel>GUI_SIMPLE;
00467
00468 m_BlenderChoice->Enable(blenderEnabled);
00469 m_BlenderChoice->Show(m_guiLevel>GUI_SIMPLE);
00470 XRCCTRL(*this, "pano_button_blender_opts", wxButton)->Enable(blenderEnabled);
00471 XRCCTRL(*this, "pano_button_blender_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00472 XRCCTRL(*this, "pano_text_blender", wxStaticText)->Enable(blenderEnabled);
00473 XRCCTRL(*this, "pano_text_blender", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00474
00475 bool fusionEnabled = (opt.outputLDRExposureBlended || opt.outputLDRExposureLayersFused || opt.outputLDRStacks) && m_guiLevel>GUI_SIMPLE;
00476 m_FusionChoice->Enable(fusionEnabled);
00477 m_FusionChoice->Show(m_guiLevel>GUI_SIMPLE);
00478 XRCCTRL(*this, "pano_button_fusion_opts", wxButton)->Enable(fusionEnabled);
00479 XRCCTRL(*this, "pano_button_fusion_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00480 XRCCTRL(*this, "pano_text_fusion", wxStaticText)->Enable(fusionEnabled);
00481 XRCCTRL(*this, "pano_text_fusion", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00482
00483 bool hdrMergeEnabled = (opt.outputHDRBlended || opt.outputHDRStacks) && m_guiLevel>GUI_SIMPLE;
00484 m_HDRMergeChoice->Enable(hdrMergeEnabled);
00485 m_HDRMergeChoice->Show(m_guiLevel>GUI_SIMPLE);
00486 XRCCTRL(*this, "pano_button_hdrmerge_opts", wxButton)->Enable(hdrMergeEnabled);
00487 XRCCTRL(*this, "pano_button_hdrmerge_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00488 XRCCTRL(*this, "pano_text_hdrmerge", wxStaticText)->Enable(hdrMergeEnabled);
00489 XRCCTRL(*this, "pano_text_hdrmerge", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00490
00491
00492 bool ldr_pano_enabled = opt.outputLDRBlended ||
00493 opt.outputLDRExposureBlended ||
00494 opt.outputLDRExposureLayersFused;
00495
00496 XRCCTRL(*this, "pano_output_ldr_format_label", wxStaticText)->Enable(ldr_pano_enabled);
00497 m_FileFormatOptionsLabel->Enable(ldr_pano_enabled);
00498 m_FileFormatChoice->Enable(ldr_pano_enabled);
00499 m_FileFormatJPEGQualityText->Enable(ldr_pano_enabled);
00500 m_FileFormatTIFFCompChoice->Enable(ldr_pano_enabled);
00501
00502 long i=0;
00503 if (opt.outputImageType == "tif") {
00504 i = 0;
00505 m_FileFormatOptionsLabel->Show();
00506 m_FileFormatOptionsLabel->SetLabel(_("Compression:"));
00507 m_FileFormatJPEGQualityText->Hide();
00508 m_FileFormatTIFFCompChoice->Show();
00509 if (opt.outputImageTypeCompression == "PACKBITS") {
00510 m_FileFormatTIFFCompChoice->SetSelection(1);
00511 } else if (opt.outputImageTypeCompression == "LZW") {
00512 m_FileFormatTIFFCompChoice->SetSelection(2);
00513 } else if (opt.outputImageTypeCompression == "DEFLATE") {
00514 m_FileFormatTIFFCompChoice->SetSelection(3);
00515 } else {
00516 m_FileFormatTIFFCompChoice->SetSelection(0);
00517 }
00518 } else if (opt.outputImageType == "jpg") {
00519 i = 1;
00520 m_FileFormatOptionsLabel->Show();
00521 m_FileFormatOptionsLabel->SetLabel(_("Quality:"));
00522 m_FileFormatJPEGQualityText->Show();
00523 m_FileFormatTIFFCompChoice->Hide();
00524 m_FileFormatJPEGQualityText->SetValue(wxString::Format(wxT("%d"), opt.quality));
00525 } else if (opt.outputImageType == "png") {
00526 m_FileFormatOptionsLabel->Hide();
00527 m_FileFormatJPEGQualityText->Hide();
00528 m_FileFormatTIFFCompChoice->Hide();
00529 i = 2;
00530 } else if (opt.outputImageType == "exr") {
00532 m_FileFormatOptionsLabel->Hide();
00533 m_FileFormatJPEGQualityText->Hide();
00534 m_FileFormatTIFFCompChoice->Hide();
00535 i = 3;
00536 } else
00537 wxLogError(wxT("INTERNAL error: unknown output image type"));
00538
00539 m_FileFormatChoice->SetSelection(i);
00540
00541 bool hdr_pano_enabled = opt.outputHDRBlended;
00542
00543 XRCCTRL(*this, "pano_output_hdr_format_label", wxStaticText)->Enable(hdr_pano_enabled);
00544 XRCCTRL(*this, "pano_output_hdr_format_label", wxStaticText)->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00545 m_HDRFileFormatChoice->Enable(hdr_pano_enabled);
00546 m_HDRFileFormatChoice->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00547 m_HDRFileFormatLabelTIFFCompression->Enable(hdr_pano_enabled);
00548 m_HDRFileFormatLabelTIFFCompression->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00549 m_FileFormatHDRTIFFCompChoice->Enable(hdr_pano_enabled);
00550 m_FileFormatHDRTIFFCompChoice->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00551
00552 i=0;
00553 if (opt.outputImageTypeHDR == "exr") {
00554 i = 0;
00555 m_HDRFileFormatLabelTIFFCompression->Hide();
00556 m_FileFormatHDRTIFFCompChoice->Hide();
00557 } else if (opt.outputImageTypeHDR == "tif") {
00558 i = 1;
00559 m_HDRFileFormatLabelTIFFCompression->Show();
00560 m_FileFormatHDRTIFFCompChoice->Show();
00561 if (opt.outputImageTypeHDRCompression == "PACKBITS") {
00562 m_FileFormatHDRTIFFCompChoice->SetSelection(1);
00563 } else if (opt.outputImageTypeHDRCompression == "LZW") {
00564 m_FileFormatHDRTIFFCompChoice->SetSelection(2);
00565 } else if (opt.outputImageTypeHDRCompression == "DEFLATE") {
00566 m_FileFormatHDRTIFFCompChoice->SetSelection(3);
00567 } else {
00568 m_FileFormatHDRTIFFCompChoice->SetSelection(0);
00569 }
00570 } else
00571 wxLogError(wxT("INTERNAL error: unknown hdr output image type"));
00572
00573 m_HDRFileFormatChoice->SetSelection(i);
00574
00575 m_pano_ctrls->FitInside();
00576 Layout();
00577
00578 #ifdef __WXMSW__
00579 this->Refresh(false);
00580 #endif
00581
00582 }
00583
00584 void PanoPanel::ProjectionChanged ( wxCommandEvent & e )
00585 {
00586 if (updatesDisabled) return;
00587 PanoramaOptions opt = pano->getOptions();
00588
00589
00590 PanoramaOptions::ProjectionFormat newP = (PanoramaOptions::ProjectionFormat) m_ProjectionChoice->GetSelection();
00591
00592
00593 opt.setProjection(newP);
00594
00595 GlobalCmdHist::getInstance().addCommand(
00596 new PT::SetPanoOptionsCmd( *pano, opt )
00597 );
00598 DEBUG_DEBUG ("Projection changed: " << newP)
00599 }
00600
00601 void PanoPanel::HFOVChanged ( wxCommandEvent & e )
00602 {
00603 if (updatesDisabled) return;
00604 PanoramaOptions opt = pano->getOptions();
00605
00606
00607 wxString text = m_HFOVText->GetValue();
00608 DEBUG_INFO ("HFOV = " << text.mb_str(wxConvLocal) );
00609 if (text == wxT("")) {
00610 return;
00611 }
00612
00613 double hfov;
00614 if (!str2double(text, hfov)) {
00615 wxLogError(_("Value must be numeric."));
00616 return;
00617 }
00618
00619 if ( hfov <=0 || hfov > opt.getMaxHFOV()) {
00620 wxLogError(wxString::Format(
00621 _("Invalid HFOV value. Maximum HFOV for this projection is %lf."),
00622 opt.getMaxHFOV()));
00623 }
00624 opt.setHFOV(hfov);
00625
00626 GlobalCmdHist::getInstance().addCommand(
00627 new PT::SetPanoOptionsCmd( *pano, opt )
00628 );
00629
00630 DEBUG_INFO ( "new hfov: " << hfov )
00631 }
00632
00633 void PanoPanel::VFOVChanged ( wxCommandEvent & e )
00634 {
00635 if (updatesDisabled) return;
00636 PanoramaOptions opt = pano->getOptions();
00637
00638 wxString text = m_VFOVText->GetValue();
00639 DEBUG_INFO ("VFOV = " << text.mb_str(wxConvLocal) );
00640 if (text == wxT("")) {
00641 return;
00642 }
00643
00644 double vfov;
00645 if (!str2double(text, vfov)) {
00646 wxLogError(_("Value must be numeric."));
00647 return;
00648 }
00649
00650 if ( vfov <=0 || vfov > opt.getMaxVFOV()) {
00651 wxLogError(wxString::Format(
00652 _("Invalid VFOV value. Maximum VFOV for this projection is %lf."),
00653 opt.getMaxVFOV()));
00654 vfov = opt.getMaxVFOV();
00655 }
00656 opt.setVFOV(vfov);
00657
00658 GlobalCmdHist::getInstance().addCommand(
00659 new PT::SetPanoOptionsCmd( *pano, opt )
00660 );
00661
00662 DEBUG_INFO ( "new vfov: " << vfov )
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 void PanoPanel::WidthChanged ( wxCommandEvent & e )
00686 {
00687 if (updatesDisabled) return;
00688 PanoramaOptions opt = pano->getOptions();
00689 long nWidth;
00690 if (m_WidthTxt->GetValue().ToLong(&nWidth)) {
00691 if (nWidth <= 0) return;
00692 opt.setWidth((unsigned int) nWidth, m_keepViewOnResize);
00693 GlobalCmdHist::getInstance().addCommand(
00694 new PT::SetPanoOptionsCmd( *pano, opt )
00695 );
00696 DEBUG_INFO(nWidth );
00697 } else {
00698 wxLogError(_("width needs to be an integer bigger than 0"));
00699 }
00700 }
00701
00702 void PanoPanel::HeightChanged ( wxCommandEvent & e )
00703 {
00704 if (updatesDisabled) return;
00705 PanoramaOptions opt = pano->getOptions();
00706 long nHeight;
00707 if (m_HeightTxt->GetValue().ToLong(&nHeight)) {
00708 if(nHeight <= 0) return;
00709 opt.setHeight((unsigned int) nHeight);
00710 GlobalCmdHist::getInstance().addCommand(
00711 new PT::SetPanoOptionsCmd( *pano, opt )
00712 );
00713 DEBUG_INFO(nHeight);
00714 } else {
00715 wxLogError(_("height needs to be an integer bigger than 0"));
00716 }
00717 }
00718
00719 void PanoPanel::ROIChanged ( wxCommandEvent & e )
00720 {
00721 if (updatesDisabled) return;
00722 PanoramaOptions opt = pano->getOptions();
00723 long left, right, top, bottom;
00724 if (!m_ROITopTxt->GetValue().ToLong(&top)) {
00725 wxLogError(_("Top needs to be an integer bigger than 0"));
00726 return;
00727 }
00728 if (!m_ROILeftTxt->GetValue().ToLong(&left)) {
00729 wxLogError(_("left needs to be an integer bigger than 0"));
00730 return;
00731 }
00732 if (!m_ROIRightTxt->GetValue().ToLong(&right)) {
00733 wxLogError(_("right needs to be an integer bigger than 0"));
00734 return;
00735 }
00736 if (!m_ROIBottomTxt->GetValue().ToLong(&bottom)) {
00737 wxLogError(_("bottom needs to be an integer bigger than 0"));
00738 return;
00739 }
00740 opt.setROI(vigra::Rect2D(left, top, right, bottom));
00741
00742
00743 if(opt.getROI().width()<1) {
00744 wxLogError(_("Left boundary must be smaller than right."));
00745 UpdateDisplay(pano->getOptions(), false);
00746 return;
00747 }
00748
00749 if(opt.getROI().height()<1) {
00750 wxLogError(_("Top boundary must be smaller than bottom."));
00751 UpdateDisplay(pano->getOptions(), false);
00752 return;
00753 }
00754
00755 GlobalCmdHist::getInstance().addCommand(
00756 new PT::SetPanoOptionsCmd( *pano, opt )
00757 );
00758 }
00759
00760
00761 void PanoPanel::EnableControls(bool enable)
00762 {
00763
00764
00765 m_WidthTxt->Enable(enable);
00766 m_RemapperChoice->Enable(enable);
00767 m_BlenderChoice->Enable(enable);
00768
00769
00770
00771 }
00772
00773 void PanoPanel::RemapperChanged(wxCommandEvent & e)
00774 {
00775 int remapper = m_RemapperChoice->GetSelection();
00776 DEBUG_DEBUG("changing remapper to " << remapper);
00777
00778 PanoramaOptions opt = pano->getOptions();
00779 if (remapper == 1) {
00780 opt.remapper = PanoramaOptions::PTMENDER;
00781 } else {
00782 opt.remapper = PanoramaOptions::NONA;
00783 }
00784
00785 GlobalCmdHist::getInstance().addCommand(
00786 new PT::SetPanoOptionsCmd( *pano, opt )
00787 );
00788 }
00789
00790 void PanoPanel::OnRemapperOptions(wxCommandEvent & e)
00791 {
00792 PanoramaOptions opt = pano->getOptions();
00793 if (opt.remapper == PanoramaOptions::NONA) {
00794 wxDialog dlg;
00795 wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("nona_options_dialog"));
00796 wxChoice * interpol_choice = XRCCTRL(dlg, "nona_choice_interpolator", wxChoice);
00797 wxCheckBox * cropped_cb = XRCCTRL(dlg, "nona_save_cropped", wxCheckBox);
00798 interpol_choice->SetSelection(opt.interpolator);
00799 cropped_cb->SetValue(opt.tiff_saveROI);
00800 dlg.CentreOnParent();
00801
00802 if (dlg.ShowModal() == wxID_OK) {
00803 int interpol = interpol_choice->GetSelection();
00804 if (interpol >= 0) {
00805 opt.interpolator = (vigra_ext::Interpolator) interpol;
00806 }
00807 opt.tiff_saveROI = cropped_cb->GetValue();
00808 GlobalCmdHist::getInstance().addCommand(
00809 new PT::SetPanoOptionsCmd( *pano, opt )
00810 );
00811 }
00812 } else {
00813 wxLogError(_(" PTmender options not yet implemented"));
00814 }
00815 }
00816
00817 void PanoPanel::BlenderChanged(wxCommandEvent & e)
00818 {
00819 int blender = m_BlenderChoice->GetSelection();
00820 DEBUG_DEBUG("changing stitcher to " << blender);
00821
00822 PanoramaOptions opt = pano->getOptions();
00823 switch (blender) {
00824 case 1:
00825 opt.blendMode = PanoramaOptions::NO_BLEND;
00826 break;
00827 case 2:
00828 opt.blendMode = PanoramaOptions::PTMASKER_BLEND;
00829 break;
00830 case 3:
00831 opt.blendMode = PanoramaOptions::PTBLENDER_BLEND;
00832 break;
00833 default:
00834 case 0:
00835 opt.blendMode = PanoramaOptions::ENBLEND_BLEND;
00836 break;
00837 }
00838
00839 GlobalCmdHist::getInstance().addCommand(
00840 new PT::SetPanoOptionsCmd( *pano, opt )
00841 );
00842 }
00843
00844 void PanoPanel::OnBlenderOptions(wxCommandEvent & e)
00845 {
00846 PanoramaOptions opt = pano->getOptions();
00847 if (opt.blendMode == PanoramaOptions::ENBLEND_BLEND) {
00848 wxDialog dlg;
00849 wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("enblend_options_dialog"));
00850 wxTextCtrl * enblend_opts_text = XRCCTRL(dlg, "blender_arguments_text", wxTextCtrl);
00851 enblend_opts_text->SetValue(wxString(opt.enblendOptions.c_str(), wxConvLocal));
00852 dlg.CentreOnParent();
00853
00854 if (dlg.ShowModal() == wxID_OK) {
00855 if (enblend_opts_text->GetValue().length() > 0) {
00856 opt.enblendOptions = enblend_opts_text->GetValue().mb_str(wxConvLocal);
00857 }
00858 else
00859 {
00860 opt.enblendOptions = wxConfigBase::Get()->Read(wxT("Enblend/Args"),wxT(HUGIN_ENBLEND_ARGS)).mb_str(wxConvLocal);
00861 };
00862 GlobalCmdHist::getInstance().addCommand(
00863 new PT::SetPanoOptionsCmd( *pano, opt )
00864 );
00865 }
00866 } else {
00867 wxLogError(_(" PTblender options not yet implemented"));
00868 }
00869 }
00870
00871 void PanoPanel::FusionChanged(wxCommandEvent & e)
00872 {
00873 int fusion = m_FusionChoice->GetSelection();
00874 DEBUG_DEBUG("changing stacking program to " << fusion);
00875 }
00876
00877 void PanoPanel::OnFusionOptions(wxCommandEvent & e)
00878 {
00879 PanoramaOptions opt = pano->getOptions();
00880 wxDialog dlg;
00881 wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("enfuse_options_dialog"));
00882 wxTextCtrl * enfuse_opts_text = XRCCTRL(dlg, "enfuse_arguments_text", wxTextCtrl);
00883 enfuse_opts_text->SetValue(wxString(opt.enfuseOptions.c_str(), wxConvLocal));
00884 dlg.CentreOnParent();
00885
00886 if (dlg.ShowModal() == wxID_OK) {
00887 if (enfuse_opts_text->GetValue().length() > 0) {
00888 opt.enfuseOptions = enfuse_opts_text->GetValue().mb_str(wxConvLocal);
00889 }
00890 else
00891 {
00892 opt.enfuseOptions = wxConfigBase::Get()->Read(wxT("Enfuse/Args"),wxT(HUGIN_ENFUSE_ARGS)).mb_str(wxConvLocal);
00893 };
00894 GlobalCmdHist::getInstance().addCommand(
00895 new PT::SetPanoOptionsCmd( *pano, opt )
00896 );
00897 }
00898 }
00899
00900
00901 void PanoPanel::HDRMergeChanged(wxCommandEvent & e)
00902 {
00903 int blender = m_HDRMergeChoice->GetSelection();
00904 DEBUG_DEBUG("changing HDR merger to " << blender);
00905 }
00906
00907 void PanoPanel::OnHDRMergeOptions(wxCommandEvent & e)
00908 {
00909 PanoramaOptions opt = pano->getOptions();
00910 if (opt.hdrMergeMode == PanoramaOptions::HDRMERGE_AVERAGE) {
00911 HDRMergeOptionsDialog dlg(this);
00912 dlg.SetCommandLineArgument(wxString(opt.hdrmergeOptions.c_str(), wxConvLocal));
00913 if (dlg.ShowModal() == wxOK)
00914 {
00915 opt.hdrmergeOptions=dlg.GetCommandLineArgument().mb_str(wxConvLocal);
00916 GlobalCmdHist::getInstance().addCommand(
00917 new PT::SetPanoOptionsCmd( *pano, opt )
00918 );
00919 }
00920 } else {
00921 wxLogError(_(" Options for this HDRMerge program not yet implemented"));
00922 }
00923 }
00924
00925
00926
00927 void PanoPanel::DoCalcFOV(wxCommandEvent & e)
00928 {
00929 DEBUG_TRACE("");
00930 if (pano->getActiveImages().size() == 0) return;
00931
00932 double hfov, height;
00933 pano->fitPano(hfov, height);
00934 PanoramaOptions opt = pano->getOptions();
00935 opt.setHFOV(hfov);
00936 opt.setHeight(roundi(height));
00937
00938 DEBUG_INFO ( "hfov: " << opt.getHFOV() << " w: " << opt.getWidth() << " h: " << opt.getHeight() << " => vfov: " << opt.getVFOV() << " before update");
00939
00940 GlobalCmdHist::getInstance().addCommand(
00941 new PT::SetPanoOptionsCmd( *pano, opt )
00942 );
00943
00944 PanoramaOptions opt2 = pano->getOptions();
00945 DEBUG_INFO ( "hfov: " << opt2.getHFOV() << " w: " << opt2.getWidth() << " h: " << opt2.getHeight() << " => vfov: " << opt2.getVFOV() << " after update");
00946
00947 }
00948
00949 void PanoPanel::DoCalcOptimalWidth(wxCommandEvent & e)
00950 {
00951 if (pano->getActiveImages().size() == 0) return;
00952
00953 PanoramaOptions opt = pano->getOptions();
00954 unsigned width = pano->calcOptimalWidth();
00955 if (width > 0) {
00956 opt.setWidth( width );
00957 GlobalCmdHist::getInstance().addCommand(
00958 new PT::SetPanoOptionsCmd( *pano, opt )
00959 );
00960 }
00961 DEBUG_INFO ( "new optimal width: " << opt.getWidth() );
00962 }
00963
00964
00965 void PanoPanel::DoCalcOptimalROI(wxCommandEvent & e)
00966 {
00967 DEBUG_INFO("Dirty ROI Calc\n");
00968 if (pano->getActiveImages().size() == 0)
00969 {
00970 return;
00971 };
00972
00973 vigra::Rect2D newROI;
00974 vigra::Size2D newSize;
00975 {
00976 ProgressReporterDialog progress(2, _("Autocrop"), _("Calculating optimal crop"), this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME);
00977 progress.increaseProgress(1);
00978 progress.Pulse();
00979 pano->calcOptimalROI(newROI,newSize);
00980 };
00981 #ifdef __WXMSW__
00982
00983 MainFrame::Get()->Raise();
00984 #endif
00985
00986 PanoramaOptions opt = pano->getOptions();
00987
00988 if(newROI.right() != 0 && newROI.bottom() != 0)
00989 {
00990 opt.setROI(newROI);
00991 GlobalCmdHist::getInstance().addCommand(
00992 new PT::SetPanoOptionsCmd( *pano, opt )
00993 );
00994 };
00995 };
00996
00997 void PanoPanel::DoStitch()
00998 {
00999 if (pano->getNrOfImages() == 0) {
01000 return;
01001 }
01002
01003 if (!CheckGoodSize()) {
01004
01005 return;
01006 }
01007
01008
01009
01010 wxString tempDir= wxConfigBase::Get()->Read(wxT("tempDir"),wxT(""));
01011 if(!tempDir.IsEmpty())
01012 if(tempDir.Last()!=wxFileName::GetPathSeparator())
01013 tempDir.Append(wxFileName::GetPathSeparator());
01014 wxString currentPTOfn = wxFileName::CreateTempFileName(tempDir+wxT("huginpto_"));
01015 if(currentPTOfn.size() == 0) {
01016 wxMessageBox(_("Could not create temporary project file"),_("Error"),
01017 wxCANCEL | wxICON_ERROR,this);
01018 return;
01019 }
01020 DEBUG_DEBUG("tmp PTO file: " << (const char *)currentPTOfn.mb_str(wxConvLocal));
01021
01022 ofstream script(currentPTOfn.mb_str(HUGIN_CONV_FILENAME));
01023 PT::UIntSet all;
01024 if (pano->getNrOfImages() > 0) {
01025 fill_set(all, 0, pano->getNrOfImages()-1);
01026 }
01027 pano->printPanoramaScript(script, pano->getOptimizeVector(), pano->getOptions(), all, false, "");
01028 script.close();
01029
01030
01031
01032
01033 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01034
01035 wxString hugin_stitch_project = MacGetPathToBundledAppMainExecutableFile(CFSTR("HuginStitchProject.app"));
01036 if(hugin_stitch_project == wxT(""))
01037 {
01038 DEBUG_ERROR("hugin_stitch_project could not be found in the bundle.");
01039 return;
01040 }
01041 hugin_stitch_project = wxQuoteFilename(hugin_stitch_project);
01042 #elif defined __WXMAC__
01043
01044 wxFileName hugin_stitch_project_app(wxT(INSTALL_OSX_BUNDLE_DIR), wxEmptyString);
01045 hugin_stitch_project_app.AppendDir(wxT("HuginStitchProject.app"));
01046 CFStringRef stitchProjectAppPath = MacCreateCFStringWithWxString(hugin_stitch_project_app.GetFullPath());
01047 wxString hugin_stitch_project = MacGetPathToMainExecutableFileOfBundle(stitchProjectAppPath);
01048 CFRelease(stitchProjectAppPath);
01049 #else
01050 wxString hugin_stitch_project = wxT("hugin_stitch_project");
01051 #endif
01052
01053
01054 wxFileName outputPrefix(getDefaultOutputName(MainFrame::Get()->getProjectName(), *pano));
01055 outputPrefix.Normalize();
01056
01057
01058
01059
01060
01061 wxFileDialog dlg(this,_("Specify output prefix"),
01062 outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01063 wxFD_SAVE, wxDefaultPosition);
01064 if (dlg.ShowModal() != wxID_OK)
01065 {
01066 return;
01067 };
01068 while(containsInvalidCharacters(dlg.GetPath()))
01069 {
01070 wxArrayString list;
01071 list.Add(dlg.GetPath());
01072 ShowFilenameWarning(this, list);
01073 if(dlg.ShowModal()!=wxID_OK)
01074 return;
01075 };
01076
01077 wxString switches(wxT(" --delete -o "));
01078 if(wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) == 1)
01079 switches=wxT(" --overwrite")+switches;
01080 wxString command = hugin_stitch_project + switches + wxQuoteFilename(dlg.GetPath()) + wxT(" ") + wxQuoteFilename(currentPTOfn);
01081
01082 wxConfigBase::Get()->Flush();
01083 #ifdef __WXGTK__
01084
01085
01086 wxProcess *my_process = new wxProcess(this);
01087 my_process->Redirect();
01088
01089
01090 my_process->Detach();
01091 wxExecute(command,wxEXEC_ASYNC, my_process);
01092 #else
01093 wxExecute(command);
01094 #endif
01095
01096 }
01097
01098 void PanoPanel::DoSendToBatch()
01099 {
01100 if (pano->getNrOfImages() == 0)
01101 {
01102 return;
01103 }
01104
01105 if (!CheckGoodSize())
01106 {
01107
01108 return;
01109 }
01110 wxString switches(wxT(" "));
01111 if (wxConfigBase::Get()->Read(wxT("/Processor/start"), HUGIN_PROCESSOR_START) != 0)
01112 {
01113 switches += wxT("-b ");
01114 }
01115 if (wxConfigBase::Get()->Read(wxT("/Processor/parallel"), HUGIN_PROCESSOR_PARALLEL) != 0)
01116 {
01117 switches += wxT("-p ");
01118 }
01119 if (wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) != 0)
01120 {
01121 switches += wxT("-o ");
01122 }
01123 if (wxConfigBase::Get()->Read(wxT("/Processor/verbose"), HUGIN_PROCESSOR_VERBOSE) != 0)
01124 {
01125 switches += wxT("-v ");
01126 }
01127 if(pano->isDirty())
01128 {
01129 bool showDlg=wxConfigBase::Get()->Read(wxT("ShowSaveMessage"), 1l)==1;
01130 if(showDlg)
01131 {
01132 wxDialog dlg;
01133 wxXmlResource::Get()->LoadDialog(&dlg, NULL, wxT("stitch_message_dlg"));
01134 if(dlg.ShowModal())
01135 {
01136 if(XRCCTRL(dlg, "stitch_dont_show_checkbox", wxCheckBox)->IsChecked())
01137 {
01138 wxConfigBase::Get()->Write(wxT("ShowSaveMessage"), 0l);
01139 };
01140 };
01141 };
01142 wxCommandEvent dummy;
01143 MainFrame::Get()->OnSaveProject(dummy);
01144
01145 if(pano->isDirty())
01146 {
01147 return;
01148 };
01149 };
01150 wxString projectFile = MainFrame::Get()->getProjectName();
01151 if(wxFileName::FileExists(projectFile))
01152 {
01153 wxFileName outputPrefix(getDefaultOutputName(projectFile, *pano));
01154 outputPrefix.Normalize();
01155
01156
01157
01158 wxFileDialog dlg(this,_("Specify output prefix"),
01159 outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01160 wxFD_SAVE, wxDefaultPosition);
01161 if (dlg.ShowModal() != wxID_OK)
01162 {
01163 return;
01164 };
01165 while(containsInvalidCharacters(dlg.GetPath()))
01166 {
01167 wxArrayString list;
01168 list.Add(dlg.GetPath());
01169 ShowFilenameWarning(this, list);
01170 if(dlg.ShowModal()!=wxID_OK)
01171 return;
01172 };
01173
01174 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01175 wxString cmd = MacGetPathToMainExecutableFileOfRegisteredBundle(CFSTR("net.sourceforge.hugin.PTBatcherGUI"));
01176 if(cmd != wxT(""))
01177 {
01178
01179
01180
01181 cmd = wxQuoteString(cmd);
01182 cmd += wxT(" ")+switches+wxQuoteFilename(projectFile)+wxT(" ")+wxQuoteFilename(dlg.GetPath());
01183 wxExecute(cmd);
01184 }
01185 else
01186 {
01187 wxMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), wxT("open")), _("Error"));
01188 cmd = wxT("open -b net.sourceforge.hugin.PTBatcherGUI ")+wxQuoteFilename(projectFile);
01189 wxExecute(cmd);
01190 }
01191
01192 #else
01193 #ifdef __WINDOWS__
01194 wxString huginPath = getExePath(wxGetApp().argv[0])+wxFileName::GetPathSeparator();
01195 #else
01196 wxString huginPath = wxT("");
01197 #endif
01198 wxExecute(huginPath+wxT("PTBatcherGUI")+switches+wxQuoteFilename(projectFile)+wxT(" ")+wxQuoteFilename(dlg.GetPath()));
01199 #endif
01200 }
01201 };
01202
01203 void PanoPanel::OnDoStitch ( wxCommandEvent & e )
01204 {
01205 long t;
01206 #if wxCHECK_VERSION(2,9,4)
01207 if(wxGetKeyState(WXK_COMMAND))
01208 #else
01209 if(wxGetKeyState(WXK_CONTROL))
01210 #endif
01211 {
01212 t=1;
01213 }
01214 else
01215 {
01216 wxConfigBase::Get()->Read(wxT("/Processor/gui"),&t,HUGIN_PROCESSOR_GUI);
01217 };
01218 switch (t)
01219 {
01220
01221 case 0:
01222 DoSendToBatch();
01223 break;
01224
01225 case 1:
01226 DoStitch();
01227 break;
01228
01229 default :
01230
01231 break;
01232 }
01233 }
01234
01235 void PanoPanel::FileFormatChanged(wxCommandEvent & e)
01236 {
01237
01238 int fmt = m_FileFormatChoice->GetSelection();
01239 DEBUG_DEBUG("changing file format to " << fmt);
01240
01241 PanoramaOptions opt = pano->getOptions();
01242 switch (fmt) {
01243 case 1:
01244 opt.outputImageType ="jpg";
01245 break;
01246 case 2:
01247 opt.outputImageType ="png";
01248 break;
01249 case 3:
01250 opt.outputImageType ="exr";
01251 break;
01252 default:
01253 case 0:
01254 opt.outputImageType ="tif";
01255 break;
01256 }
01257
01258 GlobalCmdHist::getInstance().addCommand(
01259 new PT::SetPanoOptionsCmd( *pano, opt )
01260 );
01261 }
01262
01263 void PanoPanel::HDRFileFormatChanged(wxCommandEvent & e)
01264 {
01265
01266 int fmt = m_HDRFileFormatChoice->GetSelection();
01267 DEBUG_DEBUG("changing file format to " << fmt);
01268
01269 PanoramaOptions opt = pano->getOptions();
01270 switch (fmt) {
01271 case 1:
01272 opt.outputImageTypeHDR ="tif";
01273 break;
01274 default:
01275 case 0:
01276 opt.outputImageTypeHDR ="exr";
01277 break;
01278 }
01279
01280 GlobalCmdHist::getInstance().addCommand(
01281 new PT::SetPanoOptionsCmd( *pano, opt )
01282 );
01283 }
01284
01285 void PanoPanel::OnJPEGQualityText(wxCommandEvent & e)
01286 {
01287 PanoramaOptions opt = pano->getOptions();
01288 long l = 100;
01289 m_FileFormatJPEGQualityText->GetValue().ToLong(&l);
01290 if (l < 0) l=1;
01291 if (l > 100) l=100;
01292 DEBUG_DEBUG("Setting jpeg quality to " << l);
01293 opt.quality = l;
01294 GlobalCmdHist::getInstance().addCommand(
01295 new PT::SetPanoOptionsCmd( *pano, opt )
01296 );
01297 }
01298
01299 void PanoPanel::OnNormalTIFFCompression(wxCommandEvent & e)
01300 {
01301 PanoramaOptions opt = pano->getOptions();
01302 switch(e.GetSelection()) {
01303 case 0:
01304 default:
01305 opt.outputImageTypeCompression = "NONE";
01306 opt.tiffCompression = "NONE";
01307 break;
01308 case 1:
01309 opt.outputImageTypeCompression = "PACKBITS";
01310 opt.tiffCompression = "PACKBITS";
01311 break;
01312 case 2:
01313 opt.outputImageTypeCompression = "LZW";
01314 opt.tiffCompression = "LZW";
01315 break;
01316 case 3:
01317 opt.outputImageTypeCompression = "DEFLATE";
01318 opt.tiffCompression = "DEFLATE";
01319 break;
01320 }
01321 GlobalCmdHist::getInstance().addCommand(
01322 new PT::SetPanoOptionsCmd( *pano, opt )
01323 );
01324 }
01325
01326 void PanoPanel::OnHDRTIFFCompression(wxCommandEvent & e)
01327 {
01328 PanoramaOptions opt = pano->getOptions();
01329 switch(e.GetSelection()) {
01330 case 0:
01331 default:
01332 opt.outputImageTypeHDRCompression = "NONE";
01333 break;
01334 case 1:
01335 opt.outputImageTypeHDRCompression = "PACKBITS";
01336 break;
01337 case 2:
01338 opt.outputImageTypeHDRCompression = "LZW";
01339 break;
01340 case 3:
01341 opt.outputImageTypeHDRCompression = "DEFLATE";
01342 break;
01343 }
01344 GlobalCmdHist::getInstance().addCommand(
01345 new PT::SetPanoOptionsCmd( *pano, opt )
01346 );
01347 }
01348
01349 void PanoPanel::OnOutputFilesChanged(wxCommandEvent & e)
01350 {
01351 int id = e.GetId();
01352 PanoramaOptions opts = pano->getOptions();
01353
01354 if (id == XRCID("pano_cb_ldr_output_blended") ) {
01355 opts.outputLDRBlended = e.IsChecked();
01356 } else if (id == XRCID("pano_cb_ldr_output_layers") ) {
01357 opts.outputLDRLayers = e.IsChecked();
01358 } else if (id == XRCID("pano_cb_ldr_output_exposure_layers") ) {
01359 opts.outputLDRExposureLayers = e.IsChecked();
01360 } else if (id == XRCID("pano_cb_ldr_output_exposure_blended") ) {
01361 opts.outputLDRExposureBlended = e.IsChecked();
01362 } else if (id == XRCID("pano_cb_ldr_output_exposure_layers_fused") ) {
01363 opts.outputLDRExposureLayersFused = e.IsChecked();
01364 } else if (id == XRCID("pano_cb_ldr_output_exposure_remapped") ) {
01365 opts.outputLDRExposureRemapped = e.IsChecked();
01366 } else if (id == XRCID("pano_cb_ldr_output_stacks") ) {
01367 opts.outputLDRStacks = e.IsChecked();
01368 } else if (id == XRCID("pano_cb_hdr_output_blended") ) {
01369 opts.outputHDRBlended = e.IsChecked();
01370 } else if (id == XRCID("pano_cb_hdr_output_stacks") ) {
01371 opts.outputHDRStacks = e.IsChecked();
01372 } else if (id == XRCID("pano_cb_hdr_output_layers") ) {
01373 opts.outputHDRLayers = e.IsChecked();
01374 }
01375
01376 GlobalCmdHist::getInstance().addCommand(
01377 new PT::SetPanoOptionsCmd( *pano, opts )
01378 );
01379 }
01380
01381 bool PanoPanel::CheckGoodSize()
01382 {
01383 vigra::Rect2D cropped_region = pano->getOptions().getROI();
01384 unsigned long long int area = ((unsigned long int) cropped_region.width()) * ((unsigned long int) cropped_region.height());
01385
01386 if (area > 500000000)
01387 {
01388
01389
01390 #if wxCHECK_VERSION(2,9,0)
01391 wxMessageDialog dialog(this,
01392 _("Are you sure you want to stitch such a large panorama?"),
01393 #ifdef _WINDOWS
01394 _("Hugin"),
01395 #else
01396 wxT(""),
01397 #endif
01398 wxICON_EXCLAMATION | wxYES_NO);
01399 dialog.SetExtendedMessage(
01400 wxString::Format(_("The panorama you are trying to stitch is %.1f gigapixels.\nIf this is too big, reduce the panorama Canvas Size and the cropped region and stitch from the Stitcher tab. Stitching a panorama this size could take a long time and a large amount of memory."),
01401 area / 1000000000.0));
01402 dialog.SetYesNoLabels(_("Stitch anyway"), _("Let me fix that"));
01403 #else // replacement for old wxWidgets versions.
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01418 wxMessageDialog dialog(this,
01419 wxString::Format(_("Are you sure you want to stitch such a large panorama?\n\nThe panorama you are trying to stitch is %.1f gigapixels.\nIf this is too big, reduce the panorama Canvas Size and the cropped region and stitch from the Stitcher tab. Stitching a panorama this size could take a long time and a large amount of memory."),
01420 area / 1000000000.0),
01421 #ifdef _WINDOWS
01422 _("Hugin"),
01423 #else
01424 wxT(""),
01425 #endif
01426 wxICON_EXCLAMATION | wxYES_NO);
01427 #endif
01428 switch (dialog.ShowModal())
01429 {
01430 case wxID_OK:
01431 case wxID_YES:
01432
01433 return true;
01434 break;
01435 default:
01436
01437 MainFrame::Get()->ShowStitcherTab();
01438 return false;
01439 }
01440 }
01441
01442 return true;
01443 }
01444
01445 void PanoPanel::SetGuiLevel(GuiLevel newGuiLevel)
01446 {
01447 m_guiLevel=newGuiLevel;
01448 UpdateDisplay(m_oldOpt, false);
01449 };
01450
01451 IMPLEMENT_DYNAMIC_CLASS(PanoPanel, wxPanel)
01452
01453 PanoPanelXmlHandler::PanoPanelXmlHandler()
01454 : wxXmlResourceHandler()
01455 {
01456 AddWindowStyles();
01457 }
01458
01459 wxObject *PanoPanelXmlHandler::DoCreateResource()
01460 {
01461 XRC_MAKE_INSTANCE(cp, PanoPanel)
01462
01463 cp->Create(m_parentAsWindow,
01464 GetID(),
01465 GetPosition(), GetSize(),
01466 GetStyle(wxT("style")),
01467 GetName());
01468
01469 SetupWindow( cp);
01470
01471 return cp;
01472 }
01473
01474 bool PanoPanelXmlHandler::CanHandle(wxXmlNode *node)
01475 {
01476 return IsOfClass(node, wxT("PanoPanel"));
01477 }
01478
01479 IMPLEMENT_DYNAMIC_CLASS(PanoPanelXmlHandler, wxXmlResourceHandler)
01480