Add Camera sharing through WebSockets

This commit is contained in:
Maxime Gimeno 2019-09-12 16:09:35 +02:00
parent b1a8ec6d76
commit b9e9dcc09b
6 changed files with 170 additions and 58 deletions

View File

@ -64,7 +64,7 @@ include(${CGAL_USE_FILE})
find_package(Qt5
QUIET
COMPONENTS OpenGL Script
OPTIONAL_COMPONENTS ScriptTools)
OPTIONAL_COMPONENTS ScriptTools WebSockets)
if(Qt5_FOUND)
@ -199,6 +199,11 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND)
target_link_libraries(demo_framework
PUBLIC Qt5::OpenGL Qt5::Widgets Qt5::Gui Qt5::Script
)
if(TARGET Qt5::WebSockets)
target_link_libraries(demo_framework PUBLIC Qt5::WebSockets)
message(STATUS "Qt5WebSockets was found. Using WebSockets is therefore possible.")
endif()
cgal_add_compilation_test(demo_framework)
# Let's define `three_EXPORT` during the compilation of `demo_framework`,
# in addition of `demo_framework_EXPORT` (defined automatically by
@ -337,6 +342,9 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND)
add_definitions(-DCGAL_USE_SSH)
target_link_libraries(polyhedron_demo PUBLIC ${LIBSSH_LIBRARIES})
endif() #libssh
if(TARGET Qt5::WebSockets)
target_link_libraries(polyhedron_demo PUBLIC Qt5::WebSockets)
endif()
add_executable ( Polyhedron_3 Polyhedron_3.cpp )
target_link_libraries( Polyhedron_3 PRIVATE polyhedron_demo )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Polyhedron_3 )

View File

@ -2198,10 +2198,6 @@ void MainWindow::on_actionPreferences_triggered()
QDialog dialog(this);
Ui::PreferencesDialog prefdiag;
prefdiag.setupUi(&dialog);
#ifdef CGAL_USE_SSH
prefdiag.sshButton->setEnabled(true);
#endif
float lineWidth[2];
if(!viewer->isOpenGL_4_3())
viewer->glGetFloatv(GL_LINE_WIDTH_RANGE, lineWidth);
@ -2345,6 +2341,12 @@ void MainWindow::on_actionPreferences_triggered()
QDialog dialog(this);
Ui::SSHDialog sshdiag;
sshdiag.setupUi(&dialog);
#ifdef CGAL_USE_SSH
sshdiag.userBox->setEnabled(true);
sshdiag.serverBox->setEnabled(true);
sshdiag.pkBox->setEnabled(true);
sshdiag.privkBox->setEnabled(true);
sshdiag.userEdit->setText(settings.value("ssh_user", QString()).toString());
sshdiag.serverEdit->setText(settings.value("ssh_server", QString()).toString());
sshdiag.publicEdit->setText(settings.value("ssh_public_key", QString()).toString());
@ -2371,11 +2373,18 @@ void MainWindow::on_actionPreferences_triggered()
return;
sshdiag.privkEdit->setText(diag.selectedFiles().front());
});
connect(prefdiag.sshButton, &QPushButton::clicked,
this, [this, prefdiag](){});
#else
sshdiag.userBox->setEnabled(false);
sshdiag.serverBox->setEnabled(false);
sshdiag.pkBox->setEnabled(false);
sshdiag.privkBox->setEnabled(false);
#endif
sshdiag.wsEdit->setText(settings.value("ws_server_url", QString()).toString());
dialog.exec();
if ( dialog.result() )
{
#ifdef CGAL_USE_SSH
settings.setValue("ssh_user",
sshdiag.userEdit->text());
settings.setValue("ssh_server",
@ -2384,8 +2393,13 @@ void MainWindow::on_actionPreferences_triggered()
sshdiag.publicEdit->text());
settings.setValue("ssh_priv_key",
sshdiag.privkEdit->text());
#endif
settings.setValue("ws_server_url",
sshdiag.wsEdit->text());
setProperty("ws_url", sshdiag.wsEdit->text());
}
});
dialog.exec();
if ( dialog.result() )
@ -2871,7 +2885,7 @@ QByteArray file_to_string(const char* filename)
//ss.write( << f.rdbuf(); // reading data
f.close();
std::string st = ss.str();
QByteArray ba(st.c_str(), st.size());
QByteArray ba(st.c_str(), static_cast<int>(st.size()));
return ba;
}
@ -3212,6 +3226,11 @@ void MainWindow::setupViewer(Viewer* viewer, SubViewer* subviewer)
information(s);
});
action= subviewer->findChild<QAction*>("actionShareCamera");
connect(action, SIGNAL(toggled(bool)),
viewer, SLOT(setShareCam(bool)));
}
void MainWindow::on_actionAdd_Viewer_triggered()
@ -3363,6 +3382,11 @@ SubViewer::SubViewer(QWidget *parent, MainWindow* mw, Viewer* mainviewer)
QAction* actionTotalPass = new QAction("Set Transparency Pass &Number...",this);
actionTotalPass->setObjectName("actionTotalPass");
viewMenu->addAction(actionTotalPass);
QAction* actionShareCamera= new QAction("Join WS Server",this);
actionShareCamera->setObjectName("actionShareCamera");
actionShareCamera->setCheckable(true);
actionShareCamera->setChecked(false);
viewMenu->addAction(actionShareCamera);
if(mainviewer)
setAttribute(Qt::WA_DeleteOnClose);
setWindowIcon(QIcon(":/cgal/icons/resources/menu.png"));
@ -3521,6 +3545,7 @@ void MainWindow::on_actionLoad_a_Scene_from_a_Script_File_triggered()
if(do_download)
{
#ifdef CGAL_USE_SSH
using namespace CGAL::ssh_internal;
QString server = settings.value("ssh_server", QString()).toString();
QString pk = settings.value("ssh_public_key", QString()).toString();
@ -3567,6 +3592,7 @@ void MainWindow::on_actionLoad_a_Scene_from_a_Script_File_triggered()
std::cout << "Error during connection : ";
std::cout << e.getError() << std::endl;
}
#endif
}
else
{

View File

@ -288,10 +288,10 @@
<item>
<widget class="QPushButton" name="sshButton">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="text">
<string>SSH Settings</string>
<string>Network Settings</string>
</property>
</widget>
</item>

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>466</width>
<height>399</height>
<width>415</width>
<height>441</height>
</rect>
</property>
<property name="windowTitle">
@ -17,63 +17,84 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="userBox">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>User</string>
<string>SSH Preferences</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLineEdit" name="userEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="serverBox">
<property name="title">
<string>Server</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="serverEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="pkBox">
<property name="title">
<string>Public Key </string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="publicEdit"/>
</item>
<item>
<widget class="QPushButton" name="pubButton">
<property name="text">
<string>Browse...</string>
<widget class="QGroupBox" name="userBox">
<property name="title">
<string>User</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="userEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="serverBox">
<property name="title">
<string>Server</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="serverEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="pkBox">
<property name="title">
<string>Public Key </string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="publicEdit"/>
</item>
<item>
<widget class="QPushButton" name="pubButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="privkBox">
<property name="title">
<string>Private Key</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="privkEdit"/>
</item>
<item>
<widget class="QPushButton" name="privButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="privkBox">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Private Key</string>
<string>Camera Synchronization Server</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLineEdit" name="privkEdit"/>
</item>
<item>
<widget class="QPushButton" name="privButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
<widget class="QLineEdit" name="wsEdit"/>
</item>
</layout>
</widget>

View File

@ -16,6 +16,7 @@
#include <QApplication>
#include <QOpenGLDebugLogger>
#include <QStyleFactory>
#include <QtWebSockets/QWebSocket>
#include <CGAL/Three/Three.h>
@ -40,6 +41,7 @@ public:
bool inDrawWithNames;
bool clipping;
bool projection_is_ortho;
bool cam_sharing;
GLfloat gl_point_size;
QVector4D clipbox[6];
QPainter *painter;
@ -107,6 +109,9 @@ public:
{
return shader_programs;
}
QWebSocket m_webSocket;
QUrl m_url;
};
class LightingDialog :
@ -254,6 +259,7 @@ void Viewer::doBindings()
d->spec_power = viewer_settings.value("spec_power", 51.8).toFloat();
d->scene = 0;
d->projection_is_ortho = false;
d->cam_sharing = false;
d->twosides = false;
this->setProperty("draw_two_sides", false);
d->macro_mode = false;
@ -589,7 +595,7 @@ void Viewer::mousePressEvent(QMouseEvent* event)
d->showDistance(event->pos());
event->accept();
}
else {
else{
makeCurrent();
CGAL::QGLViewer::mousePressEvent(event);
}
@ -1836,5 +1842,51 @@ bool Viewer::isClipping() const
return d->clipping;
}
#include "Viewer.moc"
void Viewer::setShareCam(bool b)
{
static bool init = false;
if(b)
{
d->cam_sharing = b;
QString ws_url
= CGAL::Three::Three::mainWindow()->property("ws_url").toString();
if(ws_url.isEmpty())
{
QMessageBox::warning(this, "Error", "No Server configured. Please go to Edit->Preferences->Network Settings and fill the \"Camera Synchronization Server\" Field.");
}
else{
if(!init)
{
connect(&d->m_webSocket, &QWebSocket::connected, this, &Viewer::onSocketConnected);
connect(&d->m_webSocket, &QWebSocket::disconnected, this, &Viewer::socketClosed);
init = true;
}
d->m_webSocket.open(QUrl(ws_url));
}
}
else
{
d->m_webSocket.close();
}
}
void Viewer::onSocketConnected()
{
connect(&d->m_webSocket, &QWebSocket::textMessageReceived,
this, &Viewer::onTextMessageSocketReceived);
connect(camera()->frame(), &CGAL::qglviewer::ManipulatedCameraFrame::manipulated,
this, [this](){
if(d->cam_sharing){
QString cam_state = dumpCameraCoordinates();
//send to server
d->m_webSocket.sendTextMessage(cam_state);
}
});
}
void Viewer::onTextMessageSocketReceived(QString message)
{
moveCameraToCoordinates(message, 0.05f);
}
#include "Viewer.moc"

View File

@ -95,6 +95,7 @@ public:
Q_SIGNALS:
void sendMessage(QString);
void doneInitGL(CGAL::Three::Viewer_interface*);
void socketClosed();
public Q_SLOTS:
//! Sets the antialiasing to true or false.
void setAntiAliasing(bool b) Q_DECL_OVERRIDE;
@ -130,6 +131,10 @@ public Q_SLOTS:
void messageLogged(QOpenGLDebugMessage);
void setShareCam(bool);
void onSocketConnected();
void onTextMessageSocketReceived(QString message);
protected:
void paintEvent(QPaintEvent *)Q_DECL_OVERRIDE;
void paintGL()Q_DECL_OVERRIDE;