Hugin trunk 0.1
Loading...
Searching...
No Matches
AssistantExecutor.cpp
Go to the documentation of this file.
1
8/* This is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License as published by the Free Software Foundation; either
11* version 2 of the License, or (at your option) any later version.
12*
13* This software is distributed in the hope that it will be useful,
14* but WITHOUT ANY WARRANTY; without even the implied warranty of
15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16* Lesser General Public License for more details.
17*
18* You should have received a copy of the GNU General Public
19* License along with this software. If not, see
20* <http://www.gnu.org/licenses/>.
21*
22*/
23
24#include "base_wx/platform.h"
25#include "AssistantExecutor.h"
26
27#include <wx/config.h>
28#include <wx/translation.h>
29#include <wx/fileconf.h>
30#include <wx/wfstream.h>
31#include "hugin_utils/utils.h"
33#include "base_wx/wxPlatform.h"
35
36
37namespace HuginQueue
38{
40 {
41 CommandQueue* commands=new CommandQueue();
43
44 //read main settings
45 wxConfigBase* config = wxConfigBase::Get();
46 const bool runCeleste = config->Read("/Celeste/Auto", HUGIN_CELESTE_AUTO) != 0;
47 double celesteThreshold;
48 config->Read("/Celeste/Threshold", &celesteThreshold, HUGIN_CELESTE_THRESHOLD);
49 const bool celesteSmallRadius = config->Read("/Celeste/Filter", HUGIN_CELESTE_FILTER) == 0;
50 const bool runLinefind = (pano.getNrOfImages()==1) ? true : (config->Read("/Assistant/Linefind", HUGIN_ASS_LINEFIND) != 0);
51 const bool runCPClean = config->Read("/Assistant/AutoCPClean", HUGIN_ASS_AUTO_CPCLEAN) != 0;
52 double scale;
53 config->Read("/Assistant/panoDownsizeFactor", &scale, HUGIN_ASS_PANO_DOWNSIZE_FACTOR);
54 bool hasUserDefinedOutputIni = (config->Read("/Assistant/UserDefinedOutputOption", 0l) == 1l);
56 {
57 // user defined output options, read from ini
60 };
61
62 bool runicp = (pano.getNrOfCtrlPoints() == 0);
63 if (!runicp)
64 {
65 //we check, if all images are connected
66 //if not, we run also icpfind
68 runicp = !graph.IsConnected();
69 };
70 //build commandline for icpfind
71 if (runicp && pano.getNrOfImages() > 1)
72 {
73 //create cp find
74 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "icpfind"),
75 "-o " + quotedProject + " " + quotedProject, _("Searching for control points...")));
76 //building celeste command
77 if (runCeleste)
78 {
79 wxString args;
80 args << "-t " << wxStringFromCDouble(celesteThreshold) << " ";
82 {
83 args.Append("-r 1 ");
84 }
85 args.Append("-o " + quotedProject + " " + quotedProject);
86 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "celeste_standalone"),
87 args, _("Removing control points in clouds...")));
88 };
89 //building cpclean command
90 if (runCPClean)
91 {
92 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "cpclean"),
93 "-o " + quotedProject + " " + quotedProject, _("Statistically cleaning of control points...")));
94 };
95 };
96 //vertical line detector
97 if (runLinefind)
98 {
100 bool hasVerticalLines = false;
101 if (!allCP.empty())
102 {
103 for (size_t i = 0; i < allCP.size() && !hasVerticalLines; i++)
104 {
106 };
107 };
108 if (!hasVerticalLines)
109 {
110 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "linefind"),
111 "--output=" + quotedProject + " " + quotedProject, _("Searching for vertical lines...")));
112 };
113 };
114 //now optimise all
115 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "checkpto"), quotedProject));
116 if (pano.getNrOfImages() == 1)
117 {
118 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "autooptimiser"),
119 (hasUserDefinedOutputIni ? "-a -o " : "-a -s -o ") + quotedProject + " " + quotedProject, _("Optimizing...")));
120 }
121 else
122 {
123 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "autooptimiser"),
124 (hasUserDefinedOutputIni ? "-a -m -l -o " : "-a -m -l -s -o ") + quotedProject + " " + quotedProject, _("Optimizing...")));
125 };
127 wxString label(_("Searching for best crop..."));
129 {
131 panoModifyArgs << "--ini=" << wxEscapeFilename(iniFilename.GetFullPath()) << " ";
132 label = wxString::Format("Setting options from %s", iniFilename.GetFullName().c_str());
133 }
134 else
135 {
136 // if necessary scale down final pano
137 if (scale <= 1.0)
138 {
139 panoModifyArgs << "--canvas=" << hugin_utils::roundi(scale * 100) << "% ";
140 };
141 panoModifyArgs.Append("--crop=AUTO ");
142 };
143 panoModifyArgs.Append("--output=" + quotedProject + " " + quotedProject);
144 commands->push_back(new NormalCommand(GetInternalProgram(ExePath, "pano_modify"), panoModifyArgs, label));
145 return commands;
146 }
147
149 {
150 CommandQueue* commands = new CommandQueue;
152
153 if (pano.getNrOfImages()==0)
154 {
155 errStream << "ERROR: Project contains no images. Nothing to do." << std::endl;
156 return commands;
157 };
158 const wxString quotedImage0(wxEscapeFilename(wxString(pano.getImage(0).getFilename().c_str(), HUGIN_CONV_FILENAME)));
160 if (!input.IsOk())
161 {
162 errStream << "ERROR: Can not open file \"" << assistantSetting.mb_str(wxConvLocal) << "\"." << std::endl;
163 return commands;
164 }
165 wxFileConfig settings(input);
166 long stepCount;
167 settings.Read("/General/StepCount", &stepCount, 0);
168 if (stepCount == 0)
169 {
170 errStream << "ERROR: User-setting does not define any assistant steps." << std::endl;
171 return commands;
172 };
173 // create some condition variables
174 const bool hascp = (pano.getNrOfCtrlPoints() > 0);
175 bool isConnected = false;
176 bool hasVerticalLines = false;
177 if (hascp)
178 {
179 //we check, if all images are connected
181 isConnected = graph.IsConnected();
182 // check, if there are line cp
184 if (!allCP.empty())
185 {
186 for (size_t i = 0; i < allCP.size() && !hasVerticalLines; i++)
187 {
189 };
190 };
191 };
193
194 for (size_t i = 0; i < stepCount; ++i)
195 {
196 wxString stepString("/Step");
197 stepString << i;
198 if (!settings.HasGroup(stepString))
199 {
200 errStream << "ERROR: Assistant specifies " << stepCount << " steps, but step " << i << " is missing in configuration." << std::endl;
201 CleanQueue(commands);
202 return commands;
203 }
204 settings.SetPath(stepString);
205 // check some conditions
206 const wxString condition = GetSettingString(&settings, "Condition");
207 if (condition.CmpNoCase("no cp") == 0 && hascp)
208 {
209 continue;
210 };
211 if (condition.CmpNoCase("not connected") == 0 && isConnected)
212 {
213 continue;
214 };
215 if (condition.CmpNoCase("no line cp") == 0 && hasVerticalLines)
216 {
217 continue;
218 };
219 if (condition.CmpNoCase("single image") == 0 && pano.getNrOfImages() != 1)
220 {
221 continue;
222 };
223 // read program name
224 const wxString progName = GetSettingString(&settings, "Program");
225 if (progName.IsEmpty())
226 {
227 errStream << "ERROR: Step " << i << " has no program name specified." << std::endl;
228 CleanQueue(commands);
229 return commands;
230 };
231#ifdef __WXMAC__
232 // check if program can be found in bundle
233 const wxString prog = GetExternalProgram(wxConfig::Get(), ExePath, progName);
234#elif defined __WXMSW__
235
237#else
238 const wxString prog = progName;
239#endif
240 wxString args = GetSettingString(&settings, "Arguments");
241 if (args.IsEmpty())
242 {
243 errStream << "ERROR: Step " << i << " has no arguments given." << std::endl;
244 CleanQueue(commands);
245 return commands;
246 }
247 args.Replace("%project%", quotedProject, true);
248 args.Replace("%image0%", quotedImage0, true);
249 // build image list file if needed
250 if (imageListFile.IsEmpty() && args.Find("%imagelist%") != wxNOT_FOUND)
251 {
252 wxFileName tempImageList(wxFileName::CreateTempFileName(GetConfigTempDir(wxConfig::Get()) + "hi"));
253 imageListFile = tempImageList.GetFullPath();
257 // write image list file
258 for (auto i = 0; i < pano.getNrOfImages(); ++i)
259 {
260 outputFile << wxString(pano.getImage(i).getFilename().c_str(), HUGIN_CONV_FILENAME) << endl;
261 }
262 outputFile.Flush();
263 };
264 if (!imageListFile.IsEmpty())
265 {
266 args.Replace("%imagelist%", wxEscapeFilename(imageListFile));
267 };
268 const wxString description = GetSettingStringTranslated(&settings, "Description");
269 commands->push_back(new NormalCommand(prog, args, description));
270 }
271 return commands;
272 };
273
274}; // namespace
create a CommandQueue for running the assistant using CLI tools
@ X
evaluate x, points are on a vertical line
Model for a panorama.
Definition Panorama.h:153
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition Panorama.h:211
std::size_t getNrOfCtrlPoints() const
number of control points
Definition Panorama.h:306
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition Panorama.h:319
std::size_t getNrOfImages() const
number of images.
Definition Panorama.h:205
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
Definition ImageGraph.h:45
normal command for queue, processing is stopped if an error occurred in program
Definition Executor.h:38
#define HUGIN_CELESTE_FILTER
#define HUGIN_ASS_LINEFIND
#define HUGIN_ASS_PANO_DOWNSIZE_FACTOR
#define HUGIN_ASS_AUTO_CPCLEAN
#define HUGIN_CELESTE_AUTO
#define HUGIN_CELESTE_THRESHOLD
implementation of huginApp Class
#define HUGIN_CONV_FILENAME
Definition platform.h:40
std::vector< ControlPoint > CPVector
str wxEscapeFilename(const str &arg)
special escaping routine for CommandQueues
Definition Executor.h:79
wxString GetExternalProgram(wxConfigBase *config, const wxString &bindir, const wxString &name)
return path and name of external program, which can be overwritten by the user
Definition Executor.cpp:148
CommandQueue * GetAssistantCommandQueueUserDefined(const HuginBase::Panorama &pano, const wxString &ExePath, const wxString &project, const wxString &assistantSetting, wxArrayString &tempFilesDelete, std::ostream &errStream)
generates the command queue for running the assistant
void CleanQueue(CommandQueue *queue)
clean the queue, delete all entries, but not the queue itself
Definition Executor.cpp:118
wxString wxStringFromCDouble(double val, int precision)
convert double to wxString, it is always using a '.
Definition Executor.cpp:238
std::vector< NormalCommand * > CommandQueue
Definition Executor.h:61
const wxString GetSettingStringTranslated(wxConfigBase *setting, const wxString &name, const wxString defaultValue)
read a translated string from settings and remove all whitespaces
Definition Executor.cpp:288
wxString GetInternalProgram(const wxString &bindir, const wxString &name)
return path and name of external program, which comes bundled with Hugin
Definition Executor.cpp:129
const wxString GetConfigTempDir(const wxConfigBase *config)
return the temp dir from the preferences, ensure that it ends with path separator
Definition Executor.cpp:302
CommandQueue * GetAssistantCommandQueue(const HuginBase::Panorama &pano, const wxString &ExePath, const wxString &project)
generates the command queue for running the assistant
const wxString GetSettingString(wxConfigBase *setting, const wxString &name, const wxString defaultValue)
read a string from setting and remove all whitespaces
Definition Executor.cpp:281
std::string GetUserAppDataDir()
returns the directory for user specific Hugin settings, e.g.
Definition utils.cpp:497
int roundi(T x)
Definition hugin_math.h:73
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41
platform/compiler specific stuff.