Commit f0543917 authored by Alexander Stukowski's avatar Alexander Stukowski

Merge branch master in order to update the GitLab CI script

parents d9caa74a 1a19de38
......@@ -47,10 +47,16 @@ build_linux_package:
stage: build
tags:
- linux_vm
only:
refs:
- master
- schedules
artifacts:
paths:
- build/ovito-*.tar.gz
script:
- scl enable devtoolset-7 bash
- source /opt/rh/devtoolset-7/enable
- mkdir build
- cd build
- export LD_LIBRARY_PATH=$HOME/progs/libav/lib:$LD_LIBRARY_PATH
......@@ -62,7 +68,7 @@ build_linux_package:
-DOVITO_DOUBLE_PRECISION_FP=ON
-DOVITO_BUILD_PLUGIN_OSPRAY=ON
-DHDF5_DIR=$HOME/progs/hdf5/share/cmake/hdf5
-DnetCDF_DIR=$HOME/progs/netcdf/lib/cmake/netCDF
-DnetCDF_DIR=`echo $HOME/progs/netcdf/lib*/cmake/netCDF`
-DPYTHON_EXECUTABLE=$HOME/progs/python/bin/python3
-DPYTHON_LIBRARY=`echo $HOME/progs/python/lib/libpython*.so.*`
-DPYTHON_INCLUDE_DIR=`echo $HOME/progs/python/include/python*`
......@@ -71,8 +77,8 @@ build_linux_package:
-DQSCINTILLA_LIBRARY=`echo $HOME/progs/QScintilla_gpl-*/Qt4Qt5/libqscintilla2_qt5.so.*`
-DLIBAV_INCLUDE_DIR=$HOME/progs/libav/include
-DLIBAV_LIBRARY_DIR=$HOME/progs/libav/lib
-Dospray_DIR=`echo $HOME/progs/ospray_install/lib/cmake/ospray-*`
-Dembree_DIR=`echo $HOME/progs/embree_install/lib/cmake/embree-*`
-Dospray_DIR=`echo $HOME/progs/ospray_install/lib*/cmake/ospray-*`
-Dembree_DIR=`echo $HOME/progs/embree_install/lib*/cmake/embree-*`
-DISPC_EXECUTABLE=`echo $HOME/progs/ispc-*-linux/ispc`
-DTBB_INCLUDE_DIR=`echo $HOME/progs/tbb*oss`/include/
-DTBB_LIBRARY=`echo $HOME/progs/tbb*oss`/lib/intel64/gcc4.7/libtbb.so
......@@ -81,15 +87,21 @@ build_linux_package:
-DTBB_ROOT=`echo $HOME/progs/tbb*oss`
-DLIBSSH_INCLUDE_DIR=$HOME/progs/libssh/include
-DLIBSSH_LIBRARY=$HOME/progs/libssh/lib/libssh.so
-DBOOST_INCLUDEDIR=$HOME/progs/boost_1_70_0
..
- make
- cpack
- sshpass -e sftp ovito.org:testing/ <<< $'put ovito-*.tar.gz'
# This pipeline job generates the redistributable program package for MacOS.
build_macos_package:
stage: build
tags:
- macos_vm
only:
refs:
- master
- schedules
artifacts:
paths:
- build/ovito-*.dmg
......@@ -124,12 +136,17 @@ build_macos_package:
- make
- ctest --output-on-failure
- cpack
- sshpass -e sftp ovito.org:testing/ <<< $'put ovito-*.dmg'
# This pipeline job generates the redistributable program package for Windows.
build_windows_package:
stage: build
tags:
- windows_vm
only:
refs:
- master
- schedules
artifacts:
paths:
- build/ovito-*.zip
......@@ -205,4 +222,6 @@ build_windows_package:
- nmake
#- ctest --output-on-failure # Disabled for now, because Windows 10 VM guests don't support OpenGL 2.1+, which is needed for the tests.
- cpack
- cpack -G ZIP
\ No newline at end of file
- cpack -G ZIP
- sshpass -e sftp ovito.org:testing/ <<< $'put ovito-*.zip'
- sshpass -e sftp ovito.org:testing/ <<< $'put ovito-*.exe'
\ No newline at end of file
......@@ -2,44 +2,26 @@
Steps to build the redistributable program packages for Linux.
**************************************************************************
**************************************************************************
Install essential tools and dependencies on Ubuntu 16.04:
**************************************************************************
sudo apt-get install \
libfontconfig1-dev \
libfreetype6-dev \
libx11-dev \
libxext-dev \
libxfixes-dev \
libxi-dev \
libxrender-dev \
libxcb1-dev \
libx11-xcb-dev \
libxcb-glx0-dev \
libxkbcommon-dev \
libxkbcommon-x11-dev \
libglu1-mesa-dev \
xsltproc \
docbook-xml \
libfftw3-dev \
libssl-dev \
libboost-system-dev \
libboost-thread-dev \
yasm \
git \
libsqlite3-dev \
libncurses5-dev \
libncursesw5-dev \
libreadline-dev \
libbz2-dev \
libexpat1-dev \
liblzma-dev \
libffi-dev \
uuid-dev \
liblapack3
- Install CMake >=3.11 from www.cmake.org
- Install
yum install lapack
yum install fftw3-devel
# Install newer GCC compiler toolset (run as "root"):
yum install centos-release-scl
yum upgrade
yum install -y devtoolset-7
# Activate newer GCC compiler toolset:
scl enable devtoolset-7 bash
**************************************************************************
Boost 1.70
**************************************************************************
No installation needed
Extract archive to $HOME/progs/boost_1_70_0/
**************************************************************************
Build Qt libraries (version 5.12.4)
Note: Update LGPL instructions in the user manual when changing this.
......@@ -88,11 +70,21 @@ Note: Update LGPL instructions in the user manual when changing this.
-skip qtwebview \
-skip qtwebglplugin \
-skip qtxmlpatterns \
-no-use-gold-linker \
-prefix $HOME/progs/qt5
make
make install
**************************************************************************
OpenSSL (openssl-1.1.1c)
*************************************************************************
./Configure linux-x86_64 --prefix=/usr --openssldir=/usr shared
make
make test
su
make install
**************************************************************************
Build Python (version 3.7.x):
**************************************************************************
......@@ -106,6 +98,9 @@ _ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto
su
yum install libffi-devel
exit
./configure --enable-shared --enable-optimizations --prefix=$HOME/progs/python
make && make install
......@@ -118,6 +113,7 @@ Edit "$HOME/progs/python/lib/python3.7/site.py" and set: ENABLE_USER_SITE = Fals
Install Python packages:
**************************************************************************
cd $HOME/progs/python/bin
LD_LIBRARY_PATH=$HOME/progs/python/lib ./pip3 install --upgrade pip
LD_LIBRARY_PATH=$HOME/progs/python/lib ./pip3 install numpy
LD_LIBRARY_PATH=$HOME/progs/python/lib ./pip3 install sphinx
LD_LIBRARY_PATH=$HOME/progs/python/lib ./pip3 install ipython
......@@ -159,6 +155,17 @@ cd QScintilla_gpl-2.*.*/Qt4Qt5/
$HOME/progs/qt5/bin/qmake qscintilla.pro
make
**************************************************************************
Build yasm:
**************************************************************************
git clone git://github.com/yasm/yasm.git
cd yasm
./autogen.sh
./configure
make
su
make install
**************************************************************************
Build libav (release 12):
Note: Update LGPL instructions in the user manual when changing this.
......@@ -213,6 +220,7 @@ cmake \
-DENABLE_HDF4=OFF \
-DUSE_HDF5=ON \
-DHDF5_DIR=$PWD/../../hdf5/share/cmake/hdf5 \
-DCMAKE_C_FLAGS="-DHAVE_STRDUP" \
..
make install
......@@ -259,7 +267,7 @@ cd build
cmake \
-DCMAKE_INSTALL_PREFIX=$HOME/progs/ospray_install \
-DISPC_EXECUTABLE=`echo $HOME/progs/ispc-v*-linux/ispc` \
-Dembree_DIR=`echo $HOME/progs/embree_install/lib/cmake/embree-*` \
-Dembree_DIR=`echo $HOME/progs/embree_install/lib*/cmake/embree-*` \
-DOSPRAY_APPS_BENCHMARK=OFF \
-DOSPRAY_APPS_EXAMPLEVIEWER=OFF \
-DOSPRAY_APPS_UTILITIES=OFF \
......@@ -268,9 +276,9 @@ cmake \
-DBUILD_SHARED_LIBS=ON \
..
make install
cp -d $HOME/progs/embree_install/lib/libembree*.so* $HOME/progs/ospray_install/lib/
cp -d $HOME/progs/tbb*oss/lib/intel64/gcc4.7/libtbb.so.* $HOME/progs/ospray_install/lib/
cp -d $HOME/progs/tbb*oss/lib/intel64/gcc4.7/libtbbmalloc.so.* $HOME/progs/ospray_install/lib/
cp -d $HOME/progs/embree_install/lib*/libembree*.so* $HOME/progs/ospray_install/lib*/
cp -d $HOME/progs/tbb*oss/lib/intel64/gcc4.7/libtbb.so.* $HOME/progs/ospray_install/lib*/
cp -d $HOME/progs/tbb*oss/lib/intel64/gcc4.7/libtbbmalloc.so.* $HOME/progs/ospray_install/lib*/
**************************************************************************
Download and build libssh
......@@ -327,7 +335,7 @@ cmake \
-DOVITO_REDISTRIBUTABLE_PACKAGE=ON \
-DOVITO_DOUBLE_PRECISION_FP=ON \
-DHDF5_DIR=$HOME/progs/hdf5/share/cmake/hdf5 \
-DnetCDF_DIR=$HOME/progs/netcdf/lib/cmake/netCDF \
-DnetCDF_DIR=`echo $HOME/progs/netcdf/lib*/cmake/netCDF` \
-DPYTHON_EXECUTABLE=$HOME/progs/python/bin/python3 \
-DPYTHON_LIBRARY=`echo $HOME/progs/python/lib/libpython*.so.*` \
-DPYTHON_INCLUDE_DIR=`echo $HOME/progs/python/include/python*` \
......@@ -337,8 +345,8 @@ cmake \
-DLIBAV_INCLUDE_DIR=$HOME/progs/libav/include \
-DLIBAV_LIBRARY_DIR=$HOME/progs/libav/lib \
-DOVITO_BUILD_PLUGIN_OSPRAY=ON \
-Dospray_DIR=`echo $HOME/progs/ospray_install/lib/cmake/ospray-*` \
-Dembree_DIR=`echo $HOME/progs/embree_install/lib/cmake/embree-*` \
-Dospray_DIR=`echo $HOME/progs/ospray_install/lib*/cmake/ospray-*` \
-Dembree_DIR=`echo $HOME/progs/embree_install/lib*/cmake/embree-*` \
-DISPC_EXECUTABLE=`echo $HOME/progs/ispc-*-linux/ispc` \
-DTBB_INCLUDE_DIR=`echo $HOME/progs/tbb*oss`/include/ \
-DTBB_LIBRARY=`echo $HOME/progs/tbb*oss`/lib/intel64/gcc4.7/libtbb.so \
......@@ -347,6 +355,7 @@ cmake \
-DTBB_ROOT=`echo $HOME/progs/tbb*oss` \
-DLIBSSH_INCLUDE_DIR=$HOME/progs/libssh/include \
-DLIBSSH_LIBRARY=$HOME/progs/libssh/lib/libssh.so \
-DBOOST_INCLUDEDIR=$HOME/progs/boost_1_70_0 \
../source/
#!/bin/bash
......
......@@ -23,7 +23,60 @@
<simplesect>
<title>Linux</title>
<para>
OVITO for Linux includes the original and unmodified shared libraries of Qt 5.12.4 distributed by the Qt Company.
<para>
OVITO for Linux includes Qt libraries that have been built from the unmodified sources of Qt 5.12.4 distributed by the Qt Company.
The following commands have been used to generate them:
<programlisting>
# Build platform: CentOS 6.9
# Compiler: g++ 7.1 (CentOS devtoolset-7)
./configure \
-opensource \
-confirm-license \
-shared \
-nomake examples \
-qt-libpng \
-qt-libjpeg \
-qt-pcre \
-qt-xcb \
-xkbcommon \
-no-cups \
-pch \
-no-eglfs \
-no-linuxfb \
-skip qtactiveqt \
-skip qtconnectivity \
-skip qt3d \
-skip qtcanvas3d \
-skip qtdatavis3d \
-skip qtcharts \
-skip qtlocation \
-skip qtsensors \
-skip qtdeclarative \
-skip qtdoc \
-skip qtgraphicaleffects \
-skip qtmultimedia \
-skip qtquickcontrols \
-skip qtquickcontrols2 \
-skip qtpurchasing \
-skip qtremoteobjects \
-skip qtsensors \
-skip qtserialport \
-skip qttranslations \
-skip qtwebchannel \
-skip qtgamepad \
-skip qtscript \
-skip qtserialbus \
-skip qtvirtualkeyboard \
-skip qtwayland \
-skip qtwebengine \
-skip qtwebsockets \
-skip qtwebview \
-skip qtwebglplugin \
-skip qtxmlpatterns \
-no-use-gold-linker \
-prefix $HOME/progs/qt5
make && make install
</programlisting>
</para>
</simplesect>
......
......@@ -47,7 +47,8 @@ make install
OVITO for Linux includes shared libraries that have been built from the unmodified sources of Libav.
The following commands have been used to generate them:
<programlisting>
# GCC 5.1 compiler on Ubuntu Linux 10.04:
# Build platform: CentOS 6.9
# Compiler: GCC 7.1 (CentOS devtoolset-7)
./configure \
--enable-pic \
--enable-shared \
......@@ -71,7 +72,6 @@ make install
OVITO for macOS includes shared libraries that have been built from the unmodified sources of Libav 11.12.
The following commands have been used to generate them:
<programlisting>
# GCC 5.1 compiler on Ubuntu Linux 10.04:
export MACOSX_DEPLOYMENT_TARGET=10.12
./configure \
--disable-network \
......
......@@ -43,7 +43,8 @@ nmake install
OVITO for Linux includes shared libraries that have been built from the unmodified sources of libssh 0.9.0.
The following commands have been used to build them:
<programlisting>
# GCC 5.1 compiler on Ubuntu Linux 10.04:
# Build platform: CentOS 6.9
# Compiler: GCC 7.1 (CentOS devtoolset-7)
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_SERVER=OFF .
make install
</programlisting>
......
......@@ -9,7 +9,7 @@
<xsl:param name="callout.graphics" select="'0'"/>
<xsl:param name="callout.unicode" select="'1'"/>
<xsl:param name="wordpress.dir">..</xsl:param>
<xsl:param name="wordpress.dir">../..</xsl:param>
<xsl:param name="use.extensions" select="0"/>
<xsl:param name="chunk.section.depth" select="3"/>
......
......@@ -96,7 +96,7 @@
{%- endif %}
{%- endfor %}
{%- endmacro %}
require_once('{{ pathto('../../wp-blog-header.php', 1) }}');
require_once('{{ pathto('../../../wp-blog-header.php', 1) }}');
header("HTTP/1.1 200 OK");
header("Status: 200 All rosy");
$wp_query->is_404 = false;
......
......@@ -21,6 +21,7 @@
#include <core/Core.h>
#include <core/app/PluginManager.h>
#include <core/app/Application.h>
#include <core/utilities/io/FileManager.h>
#include <core/utilities/concurrent/Promise.h>
#include <core/dataset/DataSet.h>
......@@ -42,6 +43,7 @@ DEFINE_PROPERTY_FIELD(FileExporter, everyNthFrame);
DEFINE_PROPERTY_FIELD(FileExporter, floatOutputPrecision);
DEFINE_REFERENCE_FIELD(FileExporter, nodeToExport);
DEFINE_PROPERTY_FIELD(FileExporter, dataObjectToExport);
DEFINE_PROPERTY_FIELD(FileExporter, ignorePipelineErrors);
SET_PROPERTY_FIELD_LABEL(FileExporter, outputFilename, "Output filename");
SET_PROPERTY_FIELD_LABEL(FileExporter, exportAnimation, "Export animation");
SET_PROPERTY_FIELD_LABEL(FileExporter, useWildcardFilename, "Use wildcard filename");
......@@ -50,6 +52,7 @@ SET_PROPERTY_FIELD_LABEL(FileExporter, startFrame, "Start frame");
SET_PROPERTY_FIELD_LABEL(FileExporter, endFrame, "End frame");
SET_PROPERTY_FIELD_LABEL(FileExporter, everyNthFrame, "Every Nth frame");
SET_PROPERTY_FIELD_LABEL(FileExporter, floatOutputPrecision, "Output precision");
SET_PROPERTY_FIELD_LABEL(FileExporter, ignorePipelineErrors, "Ignore pipeline errors");
SET_PROPERTY_FIELD_UNITS_AND_RANGE(FileExporter, floatOutputPrecision, IntegerParameterUnit, 1, std::numeric_limits<FloatType>::max_digits10);
/******************************************************************************
......@@ -61,7 +64,8 @@ FileExporter::FileExporter(DataSet* dataset) : RefTarget(dataset),
_startFrame(0),
_endFrame(-1),
_everyNthFrame(1),
_floatOutputPrecision(10)
_floatOutputPrecision(10),
_ignorePipelineErrors(Application::instance()->executionContext() == Application::ExecutionContext::Interactive)
{
// Use the entire animation interval as default export interval.
int lastFrame = dataset->animationSettings()->timeToFrame(dataset->animationSettings()->animationInterval().end());
......@@ -164,10 +168,18 @@ PipelineFlowState FileExporter::getPipelineDataToBeExported(TimePoint time, Asyn
throwException(tr("The scene object to be exported is not a data pipeline."));
// Evaluate pipeline.
auto evalFuture = requestRenderState ? pipeline->evaluateRenderingPipeline(time) : pipeline->evaluatePipeline(time);
auto evalFuture = requestRenderState ?
pipeline->evaluateRenderingPipeline(time, !ignorePipelineErrors()) :
pipeline->evaluatePipeline(time, !ignorePipelineErrors());
if(!operation.waitForFuture(evalFuture))
return {};
PipelineFlowState state = evalFuture.result();
if(!ignorePipelineErrors() && state.status().type() == PipelineStatus::Error)
throwException(tr("Export of frame %1 failed, because data pipeline evaluation did not succeed. Status message: %2")
.arg(dataset()->animationSettings()->timeToFrame(time))
.arg(state.status().text()));
if(state.isEmpty())
throwException(tr("The data collection to be exported is empty."));
......
///////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (2018) Alexander Stukowski
//
// This file is part of OVITO (Open Visualization Tool).
......@@ -33,7 +33,7 @@ namespace Ovito { OVITO_BEGIN_INLINE_NAMESPACE(DataIO)
/**
* \brief A meta-class for file exporters (i.e. classes derived from FileExporter).
*/
class OVITO_CORE_EXPORT FileExporterClass : public RefTarget::OOMetaClass
class OVITO_CORE_EXPORT FileExporterClass : public RefTarget::OOMetaClass
{
public:
......@@ -42,18 +42,18 @@ public:
/// \brief Returns the filename filter that specifies the file extension that can be exported by this service.
/// \return A wild-card pattern for the file types that can be produced by the FileExporter class (e.g. \c "*.xyz" or \c "*").
virtual QString fileFilter() const {
virtual QString fileFilter() const {
OVITO_ASSERT_MSG(false, "FileExporterClass::fileFilter()", "This method should be overridden by a meta-subclass of FileExporterClass.");
return {};
return {};
}
/// \brief Returns the file type description that is displayed in the drop-down box of the export file dialog.
/// \return A human-readable string describing the file format written by the FileExporter class.
virtual QString fileFilterDescription() const {
OVITO_ASSERT_MSG(false, "FileExporterClass::fileFilterDescription()", "This method should be overridden by a meta-subclass of FileExporterClass.");
return {};
}
};
};
/**
* \brief Abstract base class for file writers that export data from OVITO to an external file in a specific format.
......@@ -70,13 +70,13 @@ public:
/// \brief Determines whether the given scene node is suitable for exporting with this exporter service.
/// By default, all pipeline scene nodes are considered suitable that produce suitable data objects
/// of the type(s) specified by the FileExporter::exportableDataObjectClass() method.
/// of the type(s) specified by the FileExporter::exportableDataObjectClass() method.
/// Subclasses can refine this behavior as needed.
virtual bool isSuitableNode(SceneNode* node) const;
/// \brief Determines whether the given pipeline output is suitable for exporting with this exporter service.
/// By default, all data collections are considered suitable that contain suitable data objects
/// of the type(s) specified by the FileExporter::exportableDataObjectClass() method.
/// of the type(s) specified by the FileExporter::exportableDataObjectClass() method.
/// Subclasses can refine this behavior as needed.
virtual bool isSuitablePipelineOutput(const PipelineFlowState& state) const;
......@@ -87,7 +87,7 @@ public:
/// \brief Sets the name of the output file that should be written by this exporter.
virtual void setOutputFilename(const QString& filename);
/// \brief Exports the scene data to the output file(s).
/// \return \c true if the output file has been successfully written;
/// \c false if the export operation has been canceled by the user.
......@@ -152,6 +152,9 @@ private:
/// The specific data object from the pipeline output to be exported.
DECLARE_MODIFIABLE_PROPERTY_FIELD(DataObjectReference, dataObjectToExport, setDataObjectToExport);
/// Whether to ignore pipeline errors or not during export.
DECLARE_MODIFIABLE_PROPERTY_FIELD(bool, ignorePipelineErrors, setIgnorePipelineErrors);
};
OVITO_END_INLINE_NAMESPACE
......
......@@ -60,7 +60,7 @@ MainWindow::MainWindow() : _datasetContainer(this)
setContextMenuPolicy(Qt::NoContextMenu);
// Create input manager.
_viewportInputManager = new ViewportInputManager(this);
_viewportInputManager = new ViewportInputManager(this, datasetContainer());
// Create actions.
_actionManager = new ActionManager(this);
......@@ -185,7 +185,7 @@ MainWindow::MainWindow() : _datasetContainer(this)
bottomDockLayout->setSpacing(0);
bottomDockLayout->setRowStretch(0, 1);
DataInspectorPanel* dataInspector = new DataInspectorPanel(this);
bottomDockLayout->addWidget(dataInspector, 0, 0, 1, 5);
bottomDockLayout->addWidget(dataInspector, 0, 0, 1, 5);
QTimer::singleShot(0, dataInspector, &DataInspectorPanel::collapse);
QFrame* separatorLine = new QFrame();
QPalette pal = separatorLine->palette();
......@@ -494,7 +494,7 @@ void MainWindow::setWindowFilePath(const QString& filePath)
}
/******************************************************************************
* Called by the system when a drag is in progress and the mouse enters this
* Called by the system when a drag is in progress and the mouse enters this
* window.
******************************************************************************/
void MainWindow::dragEnterEvent(QDragEnterEvent* event)
......
......@@ -72,9 +72,10 @@ void ViewportsPanel::onViewportConfigurationReplaced(ViewportConfiguration* newV
// Create windows for the new viewports.
try {
ViewportInputManager* inputManager = MainWindow::fromDataset(newViewportConfiguration->dataset())->viewportInputManager();
for(Viewport* vp : newViewportConfiguration->viewports()) {
OVITO_ASSERT(vp->window() == nullptr);
ViewportWindow* viewportWindow = new ViewportWindow(vp, this);
ViewportWindow* viewportWindow = new ViewportWindow(vp, inputManager, this);
}
}
catch(const Exception& ex) {
......
......@@ -33,7 +33,6 @@
#include <gui/viewport/input/ViewportGizmo.h>
#include <gui/viewport/ViewportWindow.h>
#include <gui/mainwin/ViewportsPanel.h>
#include <gui/mainwin/MainWindow.h>
#include "ViewportSceneRenderer.h"
namespace Ovito { OVITO_BEGIN_INLINE_NAMESPACE(Rendering)
......@@ -84,14 +83,16 @@ void ViewportSceneRenderer::renderInteractiveContent()
renderModifiers(true);
// Render viewport gizmos.
if(MainWindow* mainWindow = MainWindow::fromDataset(renderDataset())) {
// First, render 3D content.
for(ViewportGizmo* gizmo : mainWindow->viewportInputManager()->viewportGizmos()) {
gizmo->renderOverlay3D(viewport(), this);
}
// Then, render 2D content on top.
for(ViewportGizmo* gizmo : mainWindow->viewportInputManager()->viewportGizmos()) {
gizmo->renderOverlay2D(viewport(), this);
if(ViewportWindow* viewportWindow = static_cast<ViewportWindow*>(viewport()->window())) {
if(ViewportInputManager* inputManager = viewportWindow->inputManager()) {
// First, render 3D content.
for(ViewportGizmo* gizmo : inputManager->viewportGizmos()) {
gizmo->renderOverlay3D(viewport(), this);
}
// Then, render 2D content on top.
for(ViewportGizmo* gizmo : inputManager->viewportGizmos()) {
gizmo->renderOverlay2D(viewport(), this);
}
}
}
}
......
......@@ -37,12 +37,9 @@ namespace Ovito { OVITO_BEGIN_INLINE_NAMESPACE(Gui) OVITO_BEGIN_INLINE_NAMESPACE
/******************************************************************************
* Constructor.
******************************************************************************/
ViewportWindow::ViewportWindow(Viewport* owner, QWidget* parentWidget) : QOpenGLWidget(parentWidget),
ViewportWindow::ViewportWindow(Viewport* owner, ViewportInputManager* inputManager, QWidget* parentWidget) : QOpenGLWidget(parentWidget),
_viewport(owner),
_updateRequested(false),
_mainWindow(MainWindow::fromDataset(owner->dataset())),
_renderDebugCounter(0),
_cursorInContextMenuArea(false)
_inputManager(inputManager)
{
setMouseTracking(true);
setFocusPolicy(Qt::ClickFocus);
......@@ -79,6 +76,14 @@ ViewportWindow::~ViewportWindow()
viewport()->setWindow(nullptr);
}
/******************************************************************************
* Returns the input manager handling mouse events of the viewport (if any).
******************************************************************************/
ViewportInputManager* ViewportWindow::inputManager() const
{
return _inputManager.data();
}
/******************************************************************************
* Puts an update request event for this viewport on the event loop.
******************************************************************************/
......@@ -329,14 +334,15 @@ void ViewportWindow::showEvent(QShowEvent* event)
******************************************************************************/
void ViewportWindow::mouseDoubleClickEvent(QMouseEvent* event)
{
ViewportInputMode* mode = _mainWindow->viewportInputManager()->activeMode();
if(mode) {
try {
mode->mouseDoubleClickEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
if(_inputManager) {
if(ViewportInputMode* mode = _inputManager->activeMode()) {
try {
mode->mouseDoubleClickEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
}
}
}
}
......@@ -354,14 +360,15 @@ void ViewportWindow::mousePressEvent(QMouseEvent* event)
return;
}
ViewportInputMode* mode = _mainWindow->viewportInputManager()->activeMode();
if(mode) {
try {
mode->mousePressEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
if(_inputManager) {
if(ViewportInputMode* mode = _inputManager->activeMode()) {
try {
mode->mousePressEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
}
}
}
}
......@@ -371,14 +378,15 @@ void ViewportWindow::mousePressEvent(QMouseEvent* event)
******************************************************************************/
void ViewportWindow::mouseReleaseEvent(QMouseEvent* event)
{
ViewportInputMode* mode = _mainWindow->viewportInputManager()->activeMode();
if(mode) {
try {
mode->mouseReleaseEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
if(_inputManager) {
if(ViewportInputMode* mode = _inputManager->activeMode()) {
try {
mode->mouseReleaseEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
}
}
}
}
......@@ -397,14 +405,15 @@ void ViewportWindow::mouseMoveEvent(QMouseEvent* event)
viewport()->updateViewport();
}
ViewportInputMode* mode = _mainWindow->viewportInputManager()->activeMode();
if(mode) {
try {
mode->mouseMoveEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
if(_inputManager) {
if(ViewportInputMode* mode = _inputManager->activeMode()) {
try {
mode->mouseMoveEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
}
}
}
}
......@@ -414,14 +423,15 @@ void ViewportWindow::mouseMoveEvent(QMouseEvent* event)
******************************************************************************/
void ViewportWindow::wheelEvent(QWheelEvent* event)
{
ViewportInputMode* mode = _mainWindow->viewportInputManager()->activeMode();
if(mode) {
try {
mode->wheelEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
if(_inputManager) {
if(ViewportInputMode* mode = _inputManager->activeMode()) {
try {
mode->wheelEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport mouse event handler:";
ex.logError();
}
}
}
}
......@@ -435,7 +445,8 @@ void ViewportWindow::leaveEvent(QEvent* event)
_cursorInContextMenuArea = false;
viewport()->updateViewport();
}
_mainWindow->statusBar()->clearMessage();
if(_inputManager && _inputManager->mainWindow())
_inputManager->mainWindow()->statusBar()->clearMessage();
}
/******************************************************************************
......@@ -443,14 +454,15 @@ void ViewportWindow::leaveEvent(QEvent* event)
******************************************************************************/
void ViewportWindow::focusOutEvent(QFocusEvent* event)
{
ViewportInputMode* mode = _mainWindow->viewportInputManager()->activeMode();
if(mode) {
try {
mode->focusOutEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport event handler:";
ex.logError();
if(_inputManager) {
if(ViewportInputMode* mode = _inputManager->activeMode()) {
try {
mode->focusOutEvent(this, event);
}
catch(const Exception& ex) {
qWarning() << "Uncaught exception in viewport event handler:";