AssistantExecutor.cpp

Go to the documentation of this file.
00001 
00008 /*  This is free software; you can redistribute it and/or
00009 *  modify it under the terms of the GNU General Public
00010 *  License as published by the Free Software Foundation; either
00011 *  version 2 of the License, or (at your option) any later version.
00012 *
00013 *  This software is distributed in the hope that it will be useful,
00014 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 *  Lesser General Public License for more details.
00017 *
00018 *  You should have received a copy of the GNU General Public
00019 *  License along with this software. If not, see
00020 *  <http://www.gnu.org/licenses/>.
00021 *
00022 */
00023 
00024 #include "AssistantExecutor.h"
00025 
00026 #include <wx/config.h>
00027 #include <wx/translation.h>
00028 #include <wx/fileconf.h>
00029 #include <wx/wfstream.h>
00030 #include "hugin_utils/utils.h"
00031 #include "algorithms/optimizer/ImageGraph.h"
00032 #include "base_wx/platform.h"
00033 #include "base_wx/wxPlatform.h"
00034 #include "hugin/config_defaults.h"
00035 
00036 
00037 namespace HuginQueue
00038 {
00039     CommandQueue* GetAssistantCommandQueue(const HuginBase::Panorama & pano, const wxString& ExePath, const wxString& project)
00040     {
00041         CommandQueue* commands=new CommandQueue();
00042         wxString quotedProject(wxEscapeFilename(project));
00043 
00044         //read main settings
00045         wxConfigBase* config = wxConfigBase::Get();
00046         const bool runCeleste = config->Read(wxT("/Celeste/Auto"), HUGIN_CELESTE_AUTO) != 0;
00047         double celesteThreshold;
00048         config->Read(wxT("/Celeste/Threshold"), &celesteThreshold, HUGIN_CELESTE_THRESHOLD);
00049         const bool celesteSmallRadius = config->Read(wxT("/Celeste/Filter"), HUGIN_CELESTE_FILTER) == 0;
00050         const bool runLinefind = (pano.getNrOfImages()==1) ? true : (config->Read(wxT("/Assistant/Linefind"), HUGIN_ASS_LINEFIND) != 0);
00051         const bool runCPClean = config->Read(wxT("/Assistant/AutoCPClean"), HUGIN_ASS_AUTO_CPCLEAN) != 0;
00052         double scale;
00053         config->Read(wxT("/Assistant/panoDownsizeFactor"), &scale, HUGIN_ASS_PANO_DOWNSIZE_FACTOR);
00054 
00055         bool runicp = (pano.getNrOfCtrlPoints() == 0);
00056         if (!runicp)
00057         {
00058             //we check, if all images are connected
00059             //if not, we run also icpfind
00060             HuginGraph::ImageGraph graph(pano);
00061             runicp = !graph.IsConnected();
00062         };
00063         //build commandline for icpfind
00064         if (runicp && pano.getNrOfImages() > 1)
00065         {
00066             //create cp find
00067             commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("icpfind")),
00068                 wxT("-o ") + quotedProject + wxT(" ") + quotedProject, _("Searching for control points...")));
00069             //building celeste command
00070             if (runCeleste)
00071             {
00072                 wxString args;
00073                 args << wxT("-t ") << wxStringFromCDouble(celesteThreshold) << wxT(" ");
00074                 if (celesteSmallRadius)
00075                 {
00076                     args.Append(wxT("-r 1 "));
00077                 }
00078                 args.Append(wxT("-o ") + quotedProject + wxT(" ") + quotedProject);
00079                 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("celeste_standalone")),
00080                     args, _("Removing control points in clouds...")));
00081             };
00082             //building cpclean command
00083             if (runCPClean)
00084             {
00085                 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("cpclean")),
00086                     wxT("-o ") + quotedProject + wxT(" ") + quotedProject, _("Statistically cleaning of control points...")));
00087             };
00088         };
00089         //vertical line detector
00090         if (runLinefind)
00091         {
00092             const HuginBase::CPVector allCP = pano.getCtrlPoints();
00093             bool hasVerticalLines = false;
00094             if (allCP.size() > 0)
00095             {
00096                 for (size_t i = 0; i < allCP.size() && !hasVerticalLines; i++)
00097                 {
00098                     hasVerticalLines = (allCP[i].mode == HuginBase::ControlPoint::X);
00099                 };
00100             };
00101             if (!hasVerticalLines)
00102             {
00103                 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("linefind")),
00104                     wxT("--output=") + quotedProject + wxT(" ") + quotedProject, _("Searching for vertical lines...")));
00105             };
00106         };
00107         //now optimise all
00108         commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("checkpto")), quotedProject));
00109         if (pano.getNrOfImages() == 1)
00110         {
00111             commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("autooptimiser")),
00112                 wxT("-a -s -o ") + quotedProject + wxT(" ") + quotedProject, _("Optimizing...")));
00113         }
00114         else
00115         {
00116             commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("autooptimiser")),
00117                 wxT("-a -m -l -s -o ") + quotedProject + wxT(" ") + quotedProject, _("Optimizing...")));
00118         };
00119         wxString panoModifyArgs;
00120         // if necessary scale down final pano
00121         if (scale <= 1.0)
00122         {
00123             panoModifyArgs << wxT("--canvas=") << hugin_utils::roundi(scale * 100) << wxT("% ");
00124         };
00125         panoModifyArgs.Append(wxT("--crop=AUTO --output=") + quotedProject + wxT(" ") + quotedProject);
00126         commands->push_back(new NormalCommand(GetInternalProgram(ExePath, wxT("pano_modify")),
00127             panoModifyArgs, _("Searching for best crop...")));
00128         return commands;
00129     }
00130     
00131     CommandQueue * GetAssistantCommandQueueUserDefined(const HuginBase::Panorama & pano, const wxString & ExePath, const wxString & project, const wxString & assistantSetting)
00132     {
00133         CommandQueue* commands = new CommandQueue;
00134         const wxString quotedProject(wxEscapeFilename(project));
00135 
00136         if (pano.getNrOfImages()==0)
00137         {
00138             std::cerr << "ERROR: Project contains no images. Nothing to do." << std::endl;
00139             return commands;
00140         };
00141         const wxString quotedImage0(wxEscapeFilename(wxString(pano.getImage(0).getFilename().c_str(), HUGIN_CONV_FILENAME)));
00142         wxFileInputStream input(assistantSetting);
00143         if (!input.IsOk())
00144         {
00145             std::cerr << "ERROR: Can not open file \"" << assistantSetting.mb_str(wxConvLocal) << "\"." << std::endl;
00146             return commands;
00147         }
00148         wxFileConfig settings(input);
00149         long stepCount;
00150         settings.Read(wxT("/General/StepCount"), &stepCount, 0);
00151         if (stepCount == 0)
00152         {
00153             std::cerr << "ERROR: User-setting does not define any assistant steps." << std::endl;
00154             return commands;
00155         };
00156         // create some condition variables
00157         const bool hascp = (pano.getNrOfCtrlPoints() > 0);
00158         bool isConnected = false;
00159         bool hasVerticalLines = false;
00160         if (hascp)
00161         {
00162             //we check, if all images are connected
00163             HuginGraph::ImageGraph graph(pano);
00164             isConnected = graph.IsConnected();
00165             // check, if there are line cp
00166             const HuginBase::CPVector allCP = pano.getCtrlPoints();
00167             if (!allCP.empty())
00168             {
00169                 for (size_t i = 0; i < allCP.size() && !hasVerticalLines; i++)
00170                 {
00171                     hasVerticalLines = (allCP[i].mode == HuginBase::ControlPoint::X);
00172                 };
00173             };
00174         };
00175 
00176         for (size_t i = 0; i < stepCount; ++i)
00177         {
00178             wxString stepString(wxT("/Step"));
00179             stepString << i;
00180             if (!settings.HasGroup(stepString))
00181             {
00182                 std::cerr << "ERROR: Assistant specifies " << stepCount << " steps, but step " << i << " is missing in configuration." << std::endl;
00183                 CleanQueue(commands);
00184                 return commands;
00185             }
00186             settings.SetPath(stepString);
00187             // check some conditions
00188             const wxString condition = GetSettingString(&settings, "Condition");
00189             if (condition.CmpNoCase("no cp") == 0 && hascp)
00190             {
00191                 continue;
00192             };
00193             if (condition.CmpNoCase("not connected") == 0 && isConnected)
00194             {
00195                 continue;
00196             };
00197             if (condition.CmpNoCase("no line cp") == 0 && hasVerticalLines)
00198             {
00199                 continue;
00200             };
00201             if (condition.CmpNoCase("single image") == 0 && pano.getNrOfImages() != 1)
00202             {
00203                 continue;
00204             };
00205             // read program name
00206             const wxString progName = GetSettingString(&settings, wxT("Program"));
00207             if (progName.IsEmpty())
00208             {
00209                 std::cerr << "ERROR: Step " << i << " has no program name specified." << std::endl;
00210                 CleanQueue(commands);
00211                 return commands;
00212             };
00213 #ifdef __WXMAC__
00214             // check if program can be found in bundle
00215             const wxString prog = GetExternalProgram(wxConfig::Get(), ExePath, progName);
00216 #elif defined __WXMSW__
00217 
00218             const wxString prog = MSWGetProgname(ExePath, progName);
00219 #else
00220             const wxString prog = progName;
00221 #endif
00222             wxString args = GetSettingString(&settings, wxT("Arguments"));
00223             if (args.IsEmpty())
00224             {
00225                 std::cerr << "ERROR: Step " << i << " has no arguments given." << std::endl;
00226                 CleanQueue(commands);
00227                 return commands;
00228             }
00229             args.Replace("%project%", quotedProject, true);
00230             args.Replace("%image0%", quotedImage0, true);
00231             const wxString description = GetSettingString(&settings, wxT("Description"));
00232             commands->push_back(new NormalCommand(prog, args, description));
00233         }
00234         return commands;
00235     };
00236 
00237 }; // namespace

Generated on 22 Jan 2018 for Hugintrunk by  doxygen 1.4.7