qtSimple.cpp 10.5 KB
Newer Older
Sylvain Thery's avatar
Sylvain Thery committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg                *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: https://iggservis.u-strasbg.fr/CGoGN/                              *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Utils/qtSimple.h"
#include "Utils/qtgl.h"
27
28
29
#include "Utils/GLSLShader.h"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_precision.hpp"
30
#include "glm/gtc/type_ptr.hpp"
Sylvain Thery's avatar
Sylvain Thery committed
31

Sylvain Thery's avatar
Sylvain Thery committed
32
33
#include <QtGui/QTextEdit>

Sylvain Thery's avatar
Sylvain Thery committed
34
35
namespace CGoGN
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
36

Sylvain Thery's avatar
Sylvain Thery committed
37
38
namespace Utils
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
39

Sylvain Thery's avatar
Sylvain Thery committed
40
41
42
43
44
45
46
47
48
49
namespace QT
{

SimpleQT::SimpleQT():
m_dock(NULL)
{
	m_glWidget = new GLWidget(this);
	setCentralWidget(m_glWidget);
	setWindowTitle(tr("CGoGN"));

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
50
	m_fileMenu = menuBar()->addMenu(tr("&File"));
Sylvain Thery's avatar
Sylvain Thery committed
51

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
52
	QAction* action = new QAction(tr("New"), this);
Sylvain Thery's avatar
Sylvain Thery committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
	connect(action, SIGNAL(triggered()), this, SLOT(cb_New()));
	m_fileMenu->addAction(action);

	action= new QAction(tr("Open"), this);
	connect(action, SIGNAL(triggered()), this, SLOT(cb_Open()));
	m_fileMenu->addAction(action);

	action= new QAction(tr("Save"), this);
	connect(action, SIGNAL(triggered()), this, SLOT(cb_Save()));
	m_fileMenu->addAction(action);

	m_fileMenu->addSeparator();

	action= new QAction(tr("Quit"), this);
	connect(action, SIGNAL(triggered()), this, SLOT(cb_Quit()));
	m_fileMenu->addAction(action);

	m_appMenu = menuBar()->addMenu(tr("&Application"));

	QMenu* m_helpMenu = menuBar()->addMenu(tr("&Help"));

74
75
76
77
78
79
80
81
	action= new QAction(tr("console on/off"), this);
	connect(action, SIGNAL(triggered()), this, SLOT(cb_consoleOnOff()));
	m_helpMenu->addAction(action);

	action= new QAction(tr("console clear"), this);
	connect(action, SIGNAL(triggered()), this, SLOT(cb_consoleClear()));
	m_helpMenu->addAction(action);

Sylvain Thery's avatar
Sylvain Thery committed
82
83
84
85
86
87
88
89
	action= new QAction(tr("About"), this);
	connect(action, SIGNAL(triggered()), this, SLOT(cb_about()));
	m_helpMenu->addAction(action);

	action= new QAction(tr("About CGoGN"), this);
	connect(action, SIGNAL(triggered()), this, SLOT(cb_about_cgogn()));
	m_helpMenu->addAction(action);

Sylvain Thery's avatar
Sylvain Thery committed
90
91
92
93
94
95
96
97
98
99
100
101
102
	m_dockConsole = new QDockWidget(tr("Console"), this);
	m_dockConsole->setAllowedAreas(Qt::BottomDockWidgetArea);
	m_dockConsole->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetClosable);
	addDockWidget(Qt::BottomDockWidgetArea, m_dockConsole);

	m_textConsole = new QTextEdit();
	m_textConsole->setLineWrapMode(QTextEdit::NoWrap);
	m_textConsole->setTabStopWidth(20);
	m_textConsole->setReadOnly(true);

	m_dockConsole->setWidget(m_textConsole);

	m_dockConsole->hide();
103
104

	m_transfo_matrix = glm::mat4(1.0f);
Sylvain Thery's avatar
Sylvain Thery committed
105
106
107
108
109
110
111
}

SimpleQT::~SimpleQT()
{
	delete m_glWidget; // ??
}

112
113
std::string SimpleQT::selectFile(const std::string& title, const std::string& dir, const std::string& filters)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
114
    QString fileName = QFileDialog::getOpenFileName(this, tr(title.c_str()), tr(dir.c_str()), tr(filters.c_str()), 0, 0);
115
116
117
    return fileName.toStdString();
}

118
119
120
121
122
123
std::string SimpleQT::selectFileSave(const std::string& title, const std::string& dir, const std::string& filters)
{
    QString fileName = QFileDialog::getSaveFileName(this, tr(title.c_str()), tr(dir.c_str()), tr(filters.c_str()), 0, 0);
    return fileName.toStdString();
}

Sylvain Thery's avatar
Sylvain Thery committed
124
125
126
void SimpleQT::cb_about_cgogn()
{
	QString str("CGoGN:\nCombinatorial and Geometric modeling\n"
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
127
128
129
130
				"with Generic N-dimensional Maps\n"
				"Web site: https://cgogn.u-strasbg.fr \n"
				"Contact information: cgogn@unistra.fr");
	QMessageBox::about(this, tr("About CGoGN"), str);
Sylvain Thery's avatar
Sylvain Thery committed
131
132
133
134
135
136
137
138
139
140
141
142
}

void SimpleQT::cb_about()
{
   QMessageBox::about(this, tr("About App"), m_helpString.c_str());
}

void SimpleQT::setHelpMsg(const std::string& msg)
{
	m_helpString = msg;
}

143
144
145
146
void SimpleQT::glMousePosition(int& x, int& y)
{
	QPoint xy = m_glWidget->mapFromGlobal(QCursor::pos());
	x = xy.x();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
147
	y = m_glWidget->getHeight() - xy.y();
148
149
}

Sylvain Thery's avatar
Sylvain Thery committed
150
151
QDockWidget* SimpleQT::addEmptyDock()
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
152
153
154
155
	m_dock = new QDockWidget(tr("Control"), this);
	m_dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	m_dock->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetClosable);
	addDockWidget(Qt::RightDockWidgetArea, m_dock);
Sylvain Thery's avatar
Sylvain Thery committed
156

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
157
158
	m_dock->hide();
	return m_dock;
Sylvain Thery's avatar
Sylvain Thery committed
159
160
161
162
163
164
165
166
167
168
}

void SimpleQT::visibilityDock(bool visible)
{
	if (visible)
		m_dock->show();
	else
		m_dock->hide();
}

Sylvain Thery's avatar
Sylvain Thery committed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
void SimpleQT::visibilityConsole(bool visible)
{
	if (visible)
		m_dockConsole->show();
	else
		m_dockConsole->hide();
}

void SimpleQT::toggleVisibilityDock()
{
	if (m_dock->isHidden())
		m_dock->show();
	else
		m_dock->hide();
}

void SimpleQT::toggleVisibilityConsole()
{
	if (m_dockConsole->isHidden())
		m_dockConsole->show();
	else
		m_dockConsole->hide();
}

Sylvain Thery's avatar
Sylvain Thery committed
193
194
195
196
197
198
199
200
201
202
203
void SimpleQT::windowTitle(const char* windowTitle)
{
	setWindowTitle(tr(windowTitle));
}

void SimpleQT::dockTitle(const char* dockTitle)
{
	if (m_dock)
		m_dock->setWindowTitle(tr(dockTitle));
}

Sylvain Thery's avatar
Sylvain Thery committed
204
void SimpleQT::statusMsg(const char* msg, int timeoutms)
205
206
207
208
{
	if (msg)
	{
		QString message = tr(msg);
Sylvain Thery's avatar
Sylvain Thery committed
209
		statusBar()->showMessage(message,timeoutms);
210
211
	}
	else
Sylvain Thery's avatar
Sylvain Thery committed
212
213
214
215
216
217
	{
		if (statusBar()->isHidden())
			statusBar()->show();
		else
			statusBar()->hide();
	}
218
}
Sylvain Thery's avatar
Sylvain Thery committed
219
220
221
222
223
224
225
226

void SimpleQT::setCallBack( const QObject* sender, const char* signal, const char* method)
{
	connect(sender, signal, this, method);
}

void SimpleQT::keyPressEvent(QKeyEvent *e)
{
Sylvain Thery's avatar
Sylvain Thery committed
227
	if (e->modifiers() & Qt::ShiftModifier)
Sylvain Thery's avatar
Sylvain Thery committed
228
	{
Sylvain Thery's avatar
Sylvain Thery committed
229
230
		if ((e->key() == Qt::Key_Return))
			toggleVisibilityConsole();
Sylvain Thery's avatar
Sylvain Thery committed
231
	}
Sylvain Thery's avatar
Sylvain Thery committed
232
233
234
235
236
237
	else
	{
		if ((e->key() == Qt::Key_Return) && m_dock != NULL)
			toggleVisibilityDock();
	}

Sylvain Thery's avatar
Sylvain Thery committed
238
239
240
241
242
243

    if (e->key() == Qt::Key_Escape)
    	close();
    else
        QWidget::keyPressEvent(e);

Sylvain Thery's avatar
Sylvain Thery committed
244
    m_glWidget->keyPressEvent(e); // ?
Sylvain Thery's avatar
Sylvain Thery committed
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
}

void SimpleQT::keyReleaseEvent(QKeyEvent *e)
{
    m_glWidget->keyReleaseEvent(e);
}

void SimpleQT::setDock(QDockWidget *dock)
{
	m_dock = dock;
	addDockWidget(Qt::RightDockWidgetArea, m_dock);
	m_dock->show();
}

QDockWidget* SimpleQT::dockWidget()
{
	return m_dock;
}

void SimpleQT::updateGL()
{
	m_glWidget->updateGL();
}

269
270
void SimpleQT::updateGLMatrices()
{
271
	m_glWidget->modelModified();
272
273
274
275
276
	m_glWidget->updateGL();
}

void SimpleQT::cb_updateMatrix()
{
277
278
279
280
281
282
283
284
285
	if (GLSLShader::CURRENT_OGL_VERSION == 1)
	{
		glMatrixMode(GL_PROJECTION);
		glLoadMatrixf(glm::value_ptr(m_projection_matrix));

		glMatrixMode(GL_MODELVIEW);
		glLoadMatrixf(glm::value_ptr(m_modelView_matrix));
	}
	else
286
	{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
287
288
289
		for(std::set< std::pair<void*, GLSLShader*> >::iterator it = GLSLShader::m_registeredShaders.begin();
			it != GLSLShader::m_registeredShaders.end();
			++it)
290
		{
291
292
293
294
			if ((it->first == NULL) || (it->first == this))
			{
				it->second->updateMatrices(m_projection_matrix, m_modelView_matrix);
			}
295
		}
296
297
298
299
300
301
302
	}
}

void SimpleQT::synchronize(SimpleQT* sqt)
{
	m_projection_matrix = sqt->m_projection_matrix;
	m_modelView_matrix = sqt->m_modelView_matrix;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
303
	for (unsigned int i = 0; i < 4; ++i)
304
305
306
307
308
309
310
311
312
313
314
315
316
317
	{
		m_curquat[i] = sqt->m_curquat[i];
		m_lastquat[i] = sqt->m_lastquat[i];
	}
	m_trans_x = sqt->trans_x();
	m_trans_y = sqt->trans_y();
	m_trans_z = sqt->trans_z();

	SimpleQT::cb_updateMatrix();

	m_glWidget->modelModified();
	m_glWidget->updateGL();
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
318
void SimpleQT::add_menu_entry(const std::string label, const char* method)
Sylvain Thery's avatar
Sylvain Thery committed
319
320
321
322
323
324
325
{
	QAction * action = new QAction(tr(label.c_str()), this);
	connect(action, SIGNAL(triggered()), this, method);
	m_appMenu->addAction(action);
}

/**
326
 * initialize app menu
Sylvain Thery's avatar
Sylvain Thery committed
327
328
329
330
331
332
 */
void SimpleQT::init_app_menu()
{
	m_appMenu->clear();
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
333
void SimpleQT::registerShader(GLSLShader* ptr)
334
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
335
	GLSLShader::registerShader(this, ptr) ;
336
337
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
338
void SimpleQT::unregisterShader(GLSLShader* ptr)
339
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
340
	GLSLShader::unregisterShader(this, ptr) ;
341
342
343
344
345
346
347
348
}

GLfloat SimpleQT::getOrthoScreenRay(int x, int y, Geom::Vec3f& rayA, Geom::Vec3f& rayB, int radius)
{
	// get Z from depth buffer
//	int yy =  m_glWidget->getHeight() - y;
	int yy = y;
	GLfloat depth;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
349
	glReadPixels(x, yy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
350
351

	glm::i32vec4 viewport;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
352
	glGetIntegerv(GL_VIEWPORT, &(viewport[0]));
353
354
355
356
357
358
359
360
361

	glm::vec3 win(x, yy, 0.0f);

	glm::vec3 P = glm::unProject(win, m_modelView_matrix, m_projection_matrix, viewport);

	rayA[0] = P[0];
	rayA[1] = P[1];
	rayA[2] = P[2];

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
362
	win[2] = depth;
363

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
364
	P = glm::unProject(win, m_modelView_matrix, m_projection_matrix, viewport);
365
366
367
368
369
370
371
372
373
	rayB[0] = P[0];
	rayB[1] = P[1];
	rayB[2] = P[2];

	if (depth == 1.0f)	// depth vary in [0-1]
		depth = 0.5f;

	win[0] += radius;

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
374
	P = glm::unProject(win, m_modelView_matrix, m_projection_matrix, viewport);
375
376
377
378
379
380
381
382
383
384
	Geom::Vec3f Q;
	Q[0] = P[0];
	Q[1] = P[1];
	Q[2] = P[2];

	// compute & return distance
	Q -= rayB;
	return float(Q.norm());
}

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

void SimpleQT::transfoRotate(float angle, float x, float y, float z)
{
	transfoMatrix() = glm::rotate(transfoMatrix(), angle, glm::vec3(x,y,z));
}

void SimpleQT::transfoTranslate(float tx, float ty, float tz)
{
	transfoMatrix() = glm::translate(transfoMatrix(), glm::vec3(tx,ty,tz));
}

void SimpleQT::transfoScale(float sx, float sy, float sz)
{
	transfoMatrix() = glm::scale(transfoMatrix(), glm::vec3(sx,sy,sz));
}

void SimpleQT::pushTransfoMatrix()
{
	m_stack_trf.push(transfoMatrix());
}

bool SimpleQT::popTransfoMatrix()
{
	if (m_stack_trf.empty())
		return false;
	transfoMatrix() = m_stack_trf.top();
	m_stack_trf.pop();
	return true;
}


Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
416
} // namespace QT
Sylvain Thery's avatar
Sylvain Thery committed
417

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
418
} // namespace Utils
Sylvain Thery's avatar
Sylvain Thery committed
419

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
420
} // namespace CGoGN