Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

campvisapplication.cpp 11 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2013, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universität München
//      Boltzmannstr. 3, 85748 Garching b. München, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
12
// 
13
14
15
16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18
19
20
21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22
23
24
// 
// ================================================================================================

schultezub's avatar
schultezub committed
25
#include "campvisapplication.h"
26
27
28

#include "tgt/assert.h"
#include "tgt/exception.h"
29
#include "tgt/glcanvas.h"
30
#include "tgt/gpucapabilities.h"
31
32
33
34
#include "tgt/shadermanager.h"
#include "tgt/qt/qtapplication.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "tgt/qt/qtcontextmanager.h"
schultezub's avatar
schultezub committed
35
#include "tbb/compat/thread"
36

schultezub's avatar
schultezub committed
37
#include "application/campvispainter.h"
38
#include "application/gui/mainwindow.h"
39
#include "core/tools/opengljobprocessor.h"
40
#include "core/tools/simplejobprocessor.h"
41
#include "core/tools/stringutils.h"
42
#include "core/tools/quadrenderer.h"
43
#include "core/pipeline/abstractpipeline.h"
44
#include "modules/pipelinefactory.h"
45

schultezub's avatar
schultezub committed
46
namespace campvis {
47

48
    const std::string CampVisApplication::loggerCat_ = "CAMPVis.application.CampVisApplication";
49

50
    CampVisApplication::CampVisApplication(int& argc, char** argv) 
51
52
        : QApplication(argc, argv)
        , _localContext(0)
53
        , _mainWindow(0)
54
55
56
57
        , _initialized(false)
        , _argc(argc)
        , _argv(argv)
    {
58
59
        // Make Xlib and GLX thread safe under X11
        QApplication::setAttribute(Qt::AA_X11InitThreads);
60

61
62
        _mainWindow = new MainWindow(this);
        tgt::QtContextManager::init();
63
64

        OpenGLJobProcessor::init();
65
        SimpleJobProcessor::init();
66
67
    }

68
69
    CampVisApplication::~CampVisApplication() {
        tgtAssert(_initialized == false, "Destructing initialized CampVisApplication, deinitialize first!");
70
71

        // delete everything in the right order:
72
        for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
73
74
75
76
77
            delete it->second;
        }
        for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
            delete *it;
        }
78
79
80
        for (std::vector<DataContainer*>::iterator it = _dataContainers.begin(); it != _dataContainers.end(); ++it) {
            delete *it;
        }
81
82
    }

83
84
    void CampVisApplication::init() {
        tgtAssert(_initialized == false, "Tried to initialize CampVisApplication twice.");
85

86
87
88
        // parse argument list and create pipelines
        QStringList pipelinesToAdd = this->arguments();
        for (int i = 1; i < pipelinesToAdd.size(); ++i) {
89
90
            DataContainer* dc = createAndAddDataContainer("DataContainer #" + StringUtils::toString(_dataContainers.size() + 1));
            AbstractPipeline* p = PipelineFactory::getRef().createPipeline(pipelinesToAdd[i].toStdString(), dc);
91
92
93
94
            if (p != 0)
                addPipeline(pipelinesToAdd[i].toStdString(), p);
        }

95
96
97
98
99
100
        // Init TGT
        tgt::InitFeature::Features featureset = tgt::InitFeature::ALL;
        tgt::init(featureset);
        LogMgr.getConsoleLog()->addCat("", true);

        // create a local OpenGL context and init GL
101
        _localContext = tgt::GlContextManager::getRef().createContext("AppContext", "", tgt::ivec2(16, 16));
102
        tgtAssert(_localContext != 0, "Could not create local OpenGL context");
103

104
        tgt::GLContextScopedLock lock(_localContext);
105

106
        tgt::initGL(featureset);
107
        ShdrMgr.setDefaultGlslVersion("330");
108
109
        LGL_ERROR;

110
        // ensure matching OpenGL specs
111
        if (GpuCaps.getGlVersion() < tgt::GpuCapabilities::GlVersion::TGT_GL_VERSION_3_3) {
112
            LERROR("Your system does not support OpenGL 3.3, which is mandatory. CAMPVis will probably not work as intended.");
113
        }
114
        if (GpuCaps.getShaderVersion() < tgt::GpuCapabilities::GlVersion::SHADER_VERSION_330) {
115
116
117
118
            LERROR("Your system does not support GLSL Shader Version 3.30, which is mandatory. CAMPVis will probably not work as intended.");
        }
        if (!GpuCaps.isNpotSupported() && !GpuCaps.areTextureRectanglesSupported()) {
            LERROR("Neither non-power-of-two textures nor texture rectangles seem to be supported. CAMPVis will probably not work as intended.");
119
120
        }

121
        QuadRenderer::init();
122
        
123
124
        if (_argc > 0) {
            // ugly hack
schultezub's avatar
schultezub committed
125
            std::string basePath(_argv[0]);
126
127
128
129
130
            basePath = tgt::FileSystem::parentDir(basePath);
            ShdrMgr.addPath(basePath);
            ShdrMgr.addPath(basePath + "/core/glsl");

            basePath = tgt::FileSystem::parentDir(tgt::FileSystem::parentDir(basePath));
schultezub's avatar
schultezub committed
131
132
133
            ShdrMgr.addPath(basePath);
            ShdrMgr.addPath(basePath + "/core/glsl");

134
135
136
137
138
139
#ifdef CAMPVIS_SOURCE_DIR
            {
                std::string sourcePath = CAMPVIS_SOURCE_DIR;
                ShdrMgr.addPath(sourcePath);
                ShdrMgr.addPath(sourcePath + "/core/glsl");
            }
schultezub's avatar
schultezub committed
140
#endif
141
142
        }

143
144
        _mainWindow->init();

145
146
147
148
149
150
        // init pipeline first
        for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
            (*it)->init();
        }

        // Now init painters:
151
        for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
152
153
154
            it->second->init();
        }

155
        GLJobProc.start();
156
157
158
        _initialized = true;
    }

159
160
    void CampVisApplication::deinit() {
        tgtAssert(_initialized, "Tried to deinitialize uninitialized CampVisApplication.");
161

162
163
        GLJobProc.stop();

164
165
        {
            // Deinit everything OpenGL related using the local context.
166
            tgt::GLContextScopedLock lock(_localContext);
167

168
169
170
171
172
173
            // Deinit pipeline first
            for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
                (*it)->deinit();
            }

            // Now deinit painters:
174
            for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
175
176
177
                it->second->deinit();
            }

178
            _mainWindow->deinit();
179
180
            QuadRenderer::deinit();

181
182
            // deinit OpenGL and tgt
            tgt::deinitGL();
183
184
        }

185
        SimpleJobProcessor::deinit();
186
        OpenGLJobProcessor::deinit();
187
        PipelineFactory::deinit();
188

189
190
191
        tgt::QtContextManager::deinit();
        tgt::deinit();

192
        // MainWindow dtor needs a valid CampVisApplication, so we need to call it here instead of during destruction.
schultezub's avatar
schultezub committed
193
194
        delete _mainWindow;

195
196
197
        _initialized = false;
    }

198
199
    int CampVisApplication::run() {
        tgtAssert(_initialized, "Tried to run uninitialized CampVisApplication.");
200
201

        // disconnect OpenGL context from this thread so that the other threads can acquire an OpenGL context.
202
        tgt::GlContextManager::getRef().releaseCurrentContext();
203

204
205
        _mainWindow->show();

206
207
208
209
210
211
        // Start QApplication
        int toReturn = QApplication::exec();

        return toReturn;
    }

212
    void CampVisApplication::addPipeline(const std::string& name, AbstractPipeline* pipeline) {
213
214
        tgtAssert(pipeline != 0, "Pipeline must not be 0.");

215
216
217
218
        // if CAMPVis is already fully initialized, we need to temporarily shut down its
        // OpenGL job processor, since we need to create a new context.
        if (_initialized) {
            GLJobProc.pause();
219
            {
220
221
222
                tgt::QtThreadedCanvas* canvas = dynamic_cast<tgt::QtThreadedCanvas*>(tgt::GlContextManager::getRef().createContext(name, "CAMPVis", tgt::ivec2(512, 512)));
                tgtAssert(canvas != 0, "Dynamic cast failed. This should not be the case, since we initialized the GlContextManager singleton with a QtContextManager.");
                tgt::GLContextScopedLock lock(canvas);
223
224
225
                addPipelineImpl(canvas, name, pipeline);
            }
            GLJobProc.resume();
226
        }
227
        else {
228
229
            tgt::QtThreadedCanvas* canvas = dynamic_cast<tgt::QtThreadedCanvas*>(tgt::GlContextManager::getRef().createContext(name, "CAMPVis", tgt::ivec2(512, 512)));
            tgtAssert(canvas != 0, "Dynamic cast failed. This should not be the case, since we initialized the GlContextManager singleton with a QtContextManager.");
230
231
232
233
234
            addPipelineImpl(canvas, name, pipeline);
        }

        s_PipelinesChanged();
    }
235

236
    void CampVisApplication::addPipelineImpl(tgt::QtThreadedCanvas* canvas, const std::string& name, AbstractPipeline* pipeline) {
237
        // create canvas and painter for the pipeline and connect all together
238
        
239
        GLJobProc.registerContext(canvas);
240
241
        canvas->init();

242
        CampVisPainter* painter = new CampVisPainter(canvas, pipeline);
243
        canvas->setPainter(painter, false);
244
        pipeline->setCanvas(canvas);
245

246
247
248
        _visualizations.push_back(std::make_pair(pipeline, painter));
        _pipelines.push_back(pipeline);

249
        if (_initialized) {
250
            LGL_ERROR;
251
            pipeline->init();
252
            LGL_ERROR;
253
            painter->init();
254
            LGL_ERROR;
255
256
        }

257
        tgt::GlContextManager::getRef().releaseCurrentContext();
258
259
260
261
262
263
264
        _mainWindow->addVisualizationPipelineWidget(name, canvas);

        // enable pipeline and invalidate all processors
        pipeline->setEnabled(true);
        for (std::vector<AbstractProcessor*>::const_iterator it = pipeline->getProcessors().begin(); it != pipeline->getProcessors().end(); ++it) {
            (*it)->invalidate(AbstractProcessor::INVALID_RESULT);
        }
265
266
    }

267
268
269
270
271
272
    void CampVisApplication::registerDockWidget(Qt::DockWidgetArea area, QDockWidget* dock) {
        tgtAssert(dock != 0, "Dock widget must not be 0.");

        _mainWindow->addDockWidget(area, dock);
    }

273
274
275
276
277
    DataContainer* CampVisApplication::createAndAddDataContainer(const std::string& name) {
        DataContainer* dc = new DataContainer(name);
        _dataContainers.push_back(dc);
        s_DataContainersChanged();
        return dc;
278
279
280
    }


281
}