1 /**
2 * Mandelbulber v2, a 3D fractal generator ,=#MKNmMMKmmßMNWy,
3 * ,B" ]L,,p%%%,,,§;, "K
4 * Copyright (C) 2014-21 Mandelbulber Team §R-==%w["'~5]m%=L.=~5N
5 * ,=mm=§M ]=4 yJKA"/-Nsaj "Bw,==,,
6 * This file is part of Mandelbulber. §R.r= jw",M Km .mM FW ",§=ß., ,TN
7 * ,4R =%["w[N=7]J '"5=],""]]M,w,-; T=]M
8 * Mandelbulber is free software: §R.ß~-Q/M=,=5"v"]=Qf,'§"M= =,M.§ Rz]M"Kw
9 * you can redistribute it and/or §w "xDY.J ' -"m=====WeC=\ ""%""y=%"]"" §
10 * modify it under the terms of the "§M=M =D=4"N #"%==A%p M§ M6 R' #"=~.4M
11 * GNU General Public License as §W =, ][T"]C § § '§ e===~ U !§[Z ]N
12 * published by the 4M",,Jm=,"=e~ § § j]]""N BmM"py=ßM
13 * Free Software Foundation, ]§ T,M=& 'YmMMpM9MMM%=w=,,=MT]M m§;'§,
14 * either version 3 of the License, TWw [.j"5=~N[=§%=%W,T ]R,"=="Y[LFT ]N
15 * or (at your option) TW=,-#"%=;[ =Q:["V"" ],,M.m == ]N
16 * any later version. J§"mr"] ,=,," =="""J]= M"M"]==ß"
17 * §= "=C=4 §"eM "=B:m|4"]#F,§~
18 * Mandelbulber is distributed in "9w=,,]w em%wJ '"~" ,=,,ß"
19 * the hope that it will be useful, . "K= ,=RMMMßM"""
20 * but WITHOUT ANY WARRANTY; .'''
21 * without even the implied warranty
22 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 *
24 * See the GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with Mandelbulber. If not, see <http://www.gnu.org/licenses/>.
27 *
28 * ###########################################################################
29 *
30 * Authors: Krzysztof Marczak (buddhi1980@gmail.com)
31 *
32 * main function - 'main' function for application
33 */
34
35 #include "main.hpp"
36
37 #include <qapplication.h>
38
39 #include "animation_flight.hpp"
40 #include "animation_keyframes.hpp"
41 #include "cimage.hpp"
42 #include "command_line_interface.hpp"
43 #include "error_message.hpp"
44 #include "global_data.hpp"
45 #include "headless.h"
46 #include "initparameters.hpp"
47 #include "interface.hpp"
48 #include "netrender.hpp"
49 #include "opencl_engine_render_fractal.h"
50 #include "opencl_global.h"
51 #include "queue.hpp"
52 #include "render_data.hpp"
53 #include "render_window.hpp"
54 #include "rendered_image_widget.hpp"
55 #include "settings.hpp"
56 #include "system.hpp"
57 #include "system_data.hpp"
58 #include "system_directories.hpp"
59 #include "undo.h"
60 #include "write_log.hpp"
61
62 #include "formula/definition/all_fractal_list.hpp"
63
main(int argc,char * argv[])64 int main(int argc, char *argv[])
65 {
66 QCoreApplication *gCoreApplication = new QCoreApplication(argc, argv);
67 gCoreApplication->setOrganizationName("Mandelbulber");
68 gCoreApplication->setApplicationName("Mandelbulber");
69 gCoreApplication->setApplicationVersion(MANDELBULBER_VERSION_STRING);
70
71 // Initialization of system functions
72 InitSystem();
73
74 // configure debug output
75 qInstallMessageHandler(myMessageOutput);
76
77 UpdateLanguage();
78
79 cCommandLineInterface commandLineInterface(gApplication);
80
81 if (commandLineInterface.isNoGUI())
82 {
83 gApplication = qobject_cast<QApplication *>(gCoreApplication);
84 }
85 else
86 {
87 delete gCoreApplication;
88 gApplication = new QApplication(argc, argv);
89 gApplication->setOrganizationName("Mandelbulber");
90 gApplication->setApplicationName("Mandelbulber");
91 gApplication->setApplicationVersion(MANDELBULBER_VERSION_STRING);
92 }
93
94 // registering types for queued connections
95 // notice: /* */ prevent formatters from collapsing nested templates,
96 // since this may cause compiler errors on falsely interpreted operator>>()
97 qRegisterMetaType<cStatistics>("cStatistics");
98 qRegisterMetaType<QList<QByteArray> /* */>("QList<QByteArray>");
99 qRegisterMetaType<QList<int> /* */>("QList<int>");
100 qRegisterMetaType<cParameterContainer>("cParameterContainer");
101 qRegisterMetaType<cFractalContainer>("cFractalContainer");
102 qRegisterMetaType<sTextures>("sTextures");
103 qRegisterMetaType<cProgressText::enumProgressType>("cProgressText::enumProgressType");
104 qRegisterMetaType<QVector<int> /* */>("QVector<int>");
105 qRegisterMetaType<CVector2<double> /* */>("CVector2<double>");
106 qRegisterMetaType<QMessageBox::StandardButtons>("QMessageBox::StandardButtons");
107 qRegisterMetaType<QMessageBox::StandardButtons *>("QMessageBox::StandardButtons*");
108 qRegisterMetaType<cErrorMessage::enumMessageType>("cErrorMessage::enumMessageType");
109 qRegisterMetaType<QList<sRenderedTileData> /* */>("QList<sRenderedTileData>");
110 qRegisterMetaType<std::shared_ptr<const cParameterContainer> /* */>(
111 "std::shared_ptr<const cParameterContainer>");
112 qRegisterMetaType<std::shared_ptr<const cFractalContainer> /* */>(
113 "std::shared_ptr<const cFractalContainer>");
114
115 CalcPreferredFontSize(commandLineInterface.isNoGUI());
116
117 gErrorMessage = new cErrorMessage(gApplication);
118
119 // class for interface windows
120 gMainInterface = new cInterface;
121
122 // create default directories and copy all needed files
123 WriteLog("CreateDefaultFolders()", 2);
124 if (!CreateDefaultFolders())
125 {
126 qCritical() << "Files/directories initialization failed";
127 return 73;
128 }
129
130 // create internal database with parameters
131 gPar.reset(new cParameterContainer);
132 gParFractal.reset(new cFractalContainer);
133
134 // Allocate container for animation frames
135 gAnimFrames.reset(new cAnimationFrames);
136
137 // Allocate container for key frames
138 gKeyframes.reset(new cKeyframes);
139
140 gPar->SetContainerName("main");
141 InitParams(gPar);
142 for (int i = 0; i < NUMBER_OF_FRACTALS; i++)
143 {
144 gParFractal->at(i)->SetContainerName(QString("fractal") + QString::number(i));
145 InitFractalParams(gParFractal->at(i));
146 }
147
148 // Define list of fractal formulas
149 DefineFractalList(&newFractalList);
150
151 // Netrender
152 gNetRender = new cNetRender(gMainInterface);
153
154 // loading AppSettings
155 QString iniFileName = systemData.GetIniFile();
156 if (QFile(iniFileName).exists())
157 {
158 QTextStream out(stdout);
159 out << "Settings file: " << iniFileName << "\n";
160 cSettings parSettings(cSettings::formatAppSettings);
161 parSettings.LoadFromFile(iniFileName);
162 parSettings.Decode(gPar, gParFractal);
163 }
164
165 systemData.loggingVerbosity = gPar->Get<int>("logging_verbosity");
166
167 UpdateDefaultPaths();
168 if (!commandLineInterface.isNoGUI())
169 {
170 UpdateUIStyle();
171 UpdateUISkin();
172 }
173 UpdateLanguage();
174
175 #ifdef USE_OPENCL
176 gOpenCl = new cGlobalOpenCl(gApplication);
177 #endif
178
179 commandLineInterface.ReadCLI();
180
181 #ifdef USE_OPENCL
182 gOpenCl->Reset();
183 gOpenCl->InitPlatfromAndDevices();
184 #endif
185
186 if (!commandLineInterface.isNoGUI())
187 {
188 gMainInterface->ShowUi();
189 gFlightAnimation = new cFlightAnimation(gMainInterface, gAnimFrames, gMainInterface->mainImage,
190 gMainInterface->renderedImage, gPar, gParFractal, gMainInterface->mainWindow);
191 gKeyframeAnimation =
192 new cKeyframeAnimation(gMainInterface, gKeyframes, gMainInterface->mainImage,
193 gMainInterface->renderedImage, gPar, gParFractal, gMainInterface->mainWindow);
194
195 gMainInterface->ConnectProgressAndStatisticsSignals();
196
197 try
198 {
199 gQueue = new cQueue(gMainInterface, systemDirectories.GetQueueFractlistFile(),
200 systemDirectories.GetQueueFolder(), gMainInterface->mainWindow);
201 }
202 catch (QString &ex)
203 {
204 cErrorMessage::showMessage(
205 QObject::tr("Cannot init queue: ") + ex, cErrorMessage::errorMessage);
206 return -1;
207 }
208 }
209
210 // write parameters to ui
211 bool dataFoldersUpdated = false;
212 if (!commandLineInterface.isNoGUI())
213 {
214 gMainInterface->ComboMouseClickUpdate();
215 gMainInterface->SynchronizeInterface(gPar, gParFractal, qInterface::write);
216 gMainInterface->ComboMouseClickUpdate();
217 // dataFoldersUpdated = gMainInterface->DataFolderUpgrade(); //obsolete function
218 gMainInterface->AutoRecovery();
219 gMainInterface->InitPeriodicRefresh();
220 }
221
222 gInterfaceReadyForSynchronization = true;
223
224 gUndo = new cUndo(gMainInterface);
225
226 if (!commandLineInterface.isNoGUI())
227 {
228 gMainInterface->mainWindow->slotPopulateToolbar();
229 }
230
231 commandLineInterface.ProcessCLI();
232
233 // start main Qt loop
234 WriteLog("application->exec()", 2);
235 int result = 0;
236 if (!systemData.globalStopRequest)
237 {
238 if (!commandLineInterface.isNoGUI() && !dataFoldersUpdated) result = gApplication->exec();
239 }
240
241 // clean objects when exit
242
243 delete gMainInterface;
244 delete gApplication;
245
246 return result;
247 }
248