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/glcontextmanager.h"
31
#include "tgt/gpucapabilities.h"
32
33
34
#include "tgt/shadermanager.h"
#include "tgt/qt/qtapplication.h"
#include "tgt/qt/qtthreadedcanvas.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/job.h"
40
#include "core/tools/opengljobprocessor.h"
41
#include "core/tools/simplejobprocessor.h"
42
#include "core/tools/stringutils.h"
43
#include "core/tools/quadrenderer.h"
44
#include "core/pipeline/abstractpipeline.h"
45
#include "core/pipeline/visualizationprocessor.h"
46
#include "modules/pipelinefactory.h"
47

schultezub's avatar
schultezub committed
48
namespace campvis {
49

50
    const std::string CampVisApplication::loggerCat_ = "CAMPVis.application.CampVisApplication";
51

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

63
        _mainWindow = new MainWindow(this);
64
        tgt::GlContextManager::init();
65
66

        OpenGLJobProcessor::init();
67
        SimpleJobProcessor::init();
68
69
    }

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

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

85
86
    void CampVisApplication::init() {
        tgtAssert(_initialized == false, "Tried to initialize CampVisApplication twice.");
87
88
89
90
91
92
93

        // Init TGT
        tgt::InitFeature::Features featureset = tgt::InitFeature::ALL;
        tgt::init(featureset);
        LogMgr.getConsoleLog()->addCat("", true);

        // create a local OpenGL context and init GL
94
        _localContext = new QtThreadedCanvas("", tgt::ivec2(16, 16));
95

96
        tgt::GLContextScopedLock lock(_localContext);
97
        tgt::GlContextManager::getRef().registerContextAndInitGlew(_localContext);
98

99
        tgt::initGL(featureset);
100
        ShdrMgr.setDefaultGlslVersion("330");
101
102
        LGL_ERROR;

103
        QuadRenderer::init();
104
        
105
106
        if (_argc > 0) {
            // ugly hack
schultezub's avatar
schultezub committed
107
            std::string basePath(_argv[0]);
108
109
110
111
112
            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
113
114
115
            ShdrMgr.addPath(basePath);
            ShdrMgr.addPath(basePath + "/core/glsl");

116
117
118
119
120
121
#ifdef CAMPVIS_SOURCE_DIR
            {
                std::string sourcePath = CAMPVIS_SOURCE_DIR;
                ShdrMgr.addPath(sourcePath);
                ShdrMgr.addPath(sourcePath + "/core/glsl");
            }
schultezub's avatar
schultezub committed
122
#endif
123
124
        }

125
126
        _mainWindow->init();

127
128
129
130
131
132
133
134
135
136
        // ensure matching OpenGL specs
        LINFO("Using Graphics Hardware " << GpuCaps.getVendorAsString() << " " << GpuCaps.getGlRendererString() << " on " << GpuCaps.getOSVersionString());
        LINFO("Supported OpenGL " << GpuCaps.getGlVersion() << ", GLSL " << GpuCaps.getShaderVersion());
        if (GpuCaps.getGlVersion() < tgt::GpuCapabilities::GlVersion::TGT_GL_VERSION_3_3) {
            LERROR("Your system does not support OpenGL 3.3, which is mandatory. CAMPVis will probably not work as intended.");
        }
        if (GpuCaps.getShaderVersion() < tgt::GpuCapabilities::GlVersion::SHADER_VERSION_330) {
            LERROR("Your system does not support GLSL Shader Version 3.30, which is mandatory. CAMPVis will probably not work as intended.");
        }

137
138
        GLJobProc.start();
        GLJobProc.registerContext(_localContext);
139

140
141
142
143
144
145
146
        // parse argument list and create pipelines
        QStringList pipelinesToAdd = this->arguments();
        for (int i = 1; i < pipelinesToAdd.size(); ++i) {
            DataContainer* dc = createAndAddDataContainer("DataContainer #" + StringUtils::toString(_dataContainers.size() + 1));
            AbstractPipeline* p = PipelineFactory::getRef().createPipeline(pipelinesToAdd[i].toStdString(), dc);
            if (p != 0)
                addPipeline(pipelinesToAdd[i].toStdString(), p);
147
148
149
150
151
        }

        _initialized = true;
    }

152
153
    void CampVisApplication::deinit() {
        tgtAssert(_initialized, "Tried to deinitialize uninitialized CampVisApplication.");
154

155
156
        GLJobProc.stop();

157
158
        {
            // Deinit everything OpenGL related using the local context.
159
            tgt::GLContextScopedLock lock(_localContext);
160

161
162
163
164
165
166
            // Deinit pipeline first
            for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
                (*it)->deinit();
            }

            // Now deinit painters:
167
            for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
168
169
170
                it->second->deinit();
            }

171
            _mainWindow->deinit();
172
173
            QuadRenderer::deinit();

174
175
            // deinit OpenGL and tgt
            tgt::deinitGL();
176
177
        }

178
        SimpleJobProcessor::deinit();
179
        OpenGLJobProcessor::deinit();
180
        PipelineFactory::deinit();
181

182
        tgt::GlContextManager::deinit();
183
184
        tgt::deinit();

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

188
189
190
        _initialized = false;
    }

191
192
    int CampVisApplication::run() {
        tgtAssert(_initialized, "Tried to run uninitialized CampVisApplication.");
193
194

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

197
198
        _mainWindow->show();

199
200
201
202
203
204
        // Start QApplication
        int toReturn = QApplication::exec();

        return toReturn;
    }

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

208
        // create canvas and painter for the pipeline and connect all together
209
        tgt::QtThreadedCanvas* canvas = new tgt::QtThreadedCanvas("CAMPVis", tgt::ivec2(512, 512));
210
        GLJobProc.registerContext(canvas);
211
212
        canvas->init();

213
        CampVisPainter* painter = new CampVisPainter(canvas, pipeline);
214
        canvas->setPainter(painter, false);
215
        pipeline->setCanvas(canvas);
216

217
218
219
        _visualizations.push_back(std::make_pair(pipeline, painter));
        _pipelines.push_back(pipeline);

220
221
        _mainWindow->addVisualizationPipelineWidget(name, canvas);

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
        // initialize context (GLEW) and pipeline in OpenGL thread)
        GLJobProc.enqueueJob(
            canvas, 
            makeJobOnHeap<CampVisApplication, tgt::GLCanvas*, AbstractPipeline*>(this, &CampVisApplication::initGlContextAndPipeline, canvas, pipeline), 
            OpenGLJobProcessor::SerialJob);

        s_PipelinesChanged();
    }

    void CampVisApplication::initGlContextAndPipeline(tgt::GLCanvas* canvas, AbstractPipeline* pipeline) {
        tgt::GlContextManager::getRef().registerContextAndInitGlew(canvas);

        pipeline->init();
        LGL_ERROR;
        canvas->getPainter()->init();
        LGL_ERROR;

239
240
241
242
243
        // 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);
        }
244
245
    }

246
247
248
249
250
251
    void CampVisApplication::registerDockWidget(Qt::DockWidgetArea area, QDockWidget* dock) {
        tgtAssert(dock != 0, "Dock widget must not be 0.");

        _mainWindow->addDockWidget(area, dock);
    }

252
253
254
255
256
    DataContainer* CampVisApplication::createAndAddDataContainer(const std::string& name) {
        DataContainer* dc = new DataContainer(name);
        _dataContainers.push_back(dc);
        s_DataContainersChanged();
        return dc;
257
258
    }

259
260
261
262
263
264
265
266
267
268
269
    void CampVisApplication::rebuildAllShadersFromFiles() {
        // rebuilding all shaders has to be done from OpenGL context, use the local one.
        GLJobProc.enqueueJob(_localContext, makeJobOnHeap(this, &CampVisApplication::triggerShaderRebuild), OpenGLJobProcessor::SerialJob);
    }

    void CampVisApplication::triggerShaderRebuild() {

        if (! ShdrMgr.rebuildAllShadersFromFile()) {
            LERROR("Could not rebuild all shaders from file.");
            return;
        }
270
271
272
        else {
            LINFO("Rebuilding shaders from file successful.");
        }
273
274
275
276
277
278
279
280
281
282

        for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
            for (std::vector<AbstractProcessor*>::const_iterator pit = (*it)->getProcessors().begin(); pit != (*it)->getProcessors().end(); ++pit) {
                if (VisualizationProcessor* tester = dynamic_cast<VisualizationProcessor*>(*pit)) {
                	tester->invalidate(AbstractProcessor::INVALID_RESULT);
                }
            }
        }
    }

283

284
}