ccviewer.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449
  1. //##########################################################################
  2. //# #
  3. //# CLOUDCOMPARE LIGHT VIEWER #
  4. //# #
  5. //# This project has been initiated under funding from ANR/CIFRE #
  6. //# #
  7. //# This program is free software; you can redistribute it and/or modify #
  8. //# it under the terms of the GNU General Public License as published by #
  9. //# the Free Software Foundation; version 2 or later of the License. #
  10. //# #
  11. //# This program is distributed in the hope that it will be useful, #
  12. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  13. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  14. //# GNU General Public License for more details. #
  15. //# #
  16. //# +++ COPYRIGHT: EDF R&D + TELECOM ParisTech (ENST-TSI) +++ #
  17. //# #
  18. //##########################################################################
  19. #include "ccviewer.h"
  20. #include "ccViewerApplication.h"
  21. //Qt
  22. #include <QMessageBox>
  23. //qCC_glWindow
  24. #include <ccGLWindowInterface.h>
  25. //common dialogs
  26. #include <ccCameraParamEditDlg.h>
  27. #include <ccDisplaySettingsDlg.h>
  28. #include <ccStereoModeDlg.h>
  29. //qCC_db
  30. #include <ccGenericMesh.h>
  31. #include <ccHObjectCaster.h>
  32. #include <ccPointCloud.h>
  33. //plugins
  34. #include "ccGLPluginInterface.h"
  35. #include "ccIOPluginInterface.h"
  36. #include "ccPluginManager.h"
  37. //3D mouse handler
  38. #ifdef CC_3DXWARE_SUPPORT
  39. #include "Mouse3DInput.h"
  40. #endif
  41. //Gamepads
  42. #ifdef CC_GAMEPAD_SUPPORT
  43. #include "ccGamepadManager.h"
  44. #endif
  45. //Camera parameters dialog
  46. static ccCameraParamEditDlg* s_cpeDlg = nullptr;
  47. ccViewer::ccViewer(QWidget *parent, Qt::WindowFlags flags)
  48. : QMainWindow(parent, flags)
  49. , m_glWindow(nullptr)
  50. , m_selectedObject(nullptr)
  51. , m_3dMouseInput(nullptr)
  52. , m_gamepadManager(nullptr)
  53. {
  54. ui.setupUi(this);
  55. #ifdef Q_OS_LINUX
  56. //we reset the whole stylesheet but we keep the StatusBar style
  57. setStyleSheet(QString());
  58. setStyleSheet("QStatusBar{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 rgb(200,200,200), stop:1 rgb(255,255,255));}");
  59. #endif
  60. setWindowTitle(QString("ccViewer v%1").arg(ccApp->versionLongStr(false)));
  61. //insert GL window in a vertical layout
  62. {
  63. QVBoxLayout* verticalLayout = new QVBoxLayout(ui.GLframe);
  64. verticalLayout->setSpacing(0);
  65. const int margin = 10;
  66. verticalLayout->setContentsMargins(margin, margin, margin, margin);
  67. bool stereoMode = ccGLWindowInterface::TestStereoSupport();
  68. QWidget* glWidget = nullptr;
  69. ccGLWindowInterface::Create(m_glWindow, glWidget, stereoMode);
  70. assert(m_glWindow && glWidget);
  71. verticalLayout->addWidget(glWidget);
  72. }
  73. updateGLFrameGradient();
  74. m_glWindow->setRectangularPickingAllowed(false); //multiple entities picking not supported
  75. //UI/display synchronization
  76. ui.actionFullScreen->setChecked(false);
  77. ui.menuSelected->setEnabled(false);
  78. reflectLightsState();
  79. reflectPerspectiveState();
  80. reflectPivotVisibilityState();
  81. #ifdef CC_3DXWARE_SUPPORT
  82. enable3DMouse(true);
  83. #else
  84. ui.actionEnable3DMouse->setEnabled(false);
  85. #endif
  86. #ifdef CC_GAMEPAD_SUPPORT
  87. m_gamepadManager = new ccGamepadManager(this, this);
  88. ui.menuOptions->insertMenu(ui.menu3DMouse->menuAction(), m_gamepadManager->menu());
  89. #endif
  90. //Signals & slots connection
  91. connect(m_glWindow->signalEmitter(), &ccGLWindowSignalEmitter::filesDropped, this, qOverload<QStringList>(&ccViewer::addToDB), Qt::QueuedConnection);
  92. connect(m_glWindow->signalEmitter(), &ccGLWindowSignalEmitter::entitySelectionChanged, this, &ccViewer::selectEntity);
  93. connect(m_glWindow->signalEmitter(), &ccGLWindowSignalEmitter::exclusiveFullScreenToggled,this, &ccViewer::onExclusiveFullScreenToggled);
  94. //"Options" menu
  95. connect(ui.actionDisplayParameters, &QAction::triggered, this, &ccViewer::showDisplayParameters);
  96. connect(ui.actionEditCamera, &QAction::triggered, this, &ccViewer::doActionEditCamera);
  97. //"Display > Standard views" menu
  98. connect(ui.actionSetViewTop, &QAction::triggered, this, &ccViewer::setTopView);
  99. connect(ui.actionSetViewBottom, &QAction::triggered, this, &ccViewer::setBottomView);
  100. connect(ui.actionSetViewFront, &QAction::triggered, this, &ccViewer::setFrontView);
  101. connect(ui.actionSetViewBack, &QAction::triggered, this, &ccViewer::setBackView);
  102. connect(ui.actionSetViewLeft, &QAction::triggered, this, &ccViewer::setLeftView);
  103. connect(ui.actionSetViewRight, &QAction::triggered, this, &ccViewer::setRightView);
  104. connect(ui.actionSetViewIso1, &QAction::triggered, this, &ccViewer::setIsoView1);
  105. connect(ui.actionSetViewIso2, &QAction::triggered, this, &ccViewer::setIsoView2);
  106. //"Options > Perspective" menu
  107. connect(ui.actionSetOrthoView, &QAction::triggered, this, &ccViewer::setOrthoView);
  108. connect(ui.actionSetCenteredPerspectiveView, &QAction::triggered, this, &ccViewer::setCenteredPerspectiveView);
  109. connect(ui.actionSetViewerPerspectiveView, &QAction::triggered, this, &ccViewer::setViewerPerspectiveView);
  110. //"Options > Rotation symbol" menu
  111. connect(ui.actionSetPivotAlwaysOn, &QAction::triggered, this, &ccViewer::setPivotAlwaysOn);
  112. connect(ui.actionSetPivotRotationOnly, &QAction::triggered, this, &ccViewer::setPivotRotationOnly);
  113. connect(ui.actionSetPivotOff, &QAction::triggered, this, &ccViewer::setPivotOff);
  114. //"Options > 3D mouse" menu
  115. connect(ui.actionEnable3DMouse, &QAction::toggled, this, &ccViewer::enable3DMouse);
  116. //"Display > Lights & Materials" menu
  117. connect(ui.actionToggleSunLight, &QAction::toggled, this, &ccViewer::toggleSunLight);
  118. connect(ui.actionToggleCustomLight, &QAction::toggled, this, &ccViewer::toggleCustomLight);
  119. //"Options" menu
  120. connect(ui.actionGlobalZoom, &QAction::triggered, this, &ccViewer::setGlobalZoom);
  121. connect(ui.actionEnableStereo, &QAction::toggled, this, &ccViewer::toggleStereoMode);
  122. connect(ui.actionFullScreen, &QAction::toggled, this, &ccViewer::toggleFullScreen);
  123. connect(ui.actionLockRotationVertAxis, &QAction::triggered, this, &ccViewer::toggleRotationAboutVertAxis);
  124. //"Options > Selected" menu
  125. connect(ui.actionShowColors, &QAction::toggled, this, &ccViewer::toggleColorsShown);
  126. connect(ui.actionShowNormals, &QAction::toggled, this, &ccViewer::toggleNormalsShown);
  127. connect(ui.actionShowMaterials, &QAction::toggled, this, &ccViewer::toggleMaterialsShown);
  128. connect(ui.actionShowScalarField, &QAction::toggled, this, &ccViewer::toggleScalarShown);
  129. connect(ui.actionShowColorRamp, &QAction::toggled, this, &ccViewer::toggleColorbarShown);
  130. connect(ui.actionZoomOnSelectedEntity, &QAction::triggered, this, &ccViewer::zoomOnSelectedEntity);
  131. connect(ui.actionDelete, &QAction::triggered, this, &ccViewer::doActionDeleteSelectedEntity);
  132. //"Shaders" menu
  133. connect(ui.actionNoFilter, &QAction::triggered, this, &ccViewer::doDisableGLFilter);
  134. //"Help" menu
  135. connect(ui.actionAbout, &QAction::triggered, this, &ccViewer::doActionAbout);
  136. connect(ui.actionHelpShortcuts, &QAction::triggered, this, &ccViewer::doActionDisplayShortcuts);
  137. loadPlugins();
  138. }
  139. ccViewer::~ccViewer()
  140. {
  141. release3DMouse();
  142. #ifdef CC_GAMEPAD_SUPPORT
  143. delete m_gamepadManager;
  144. m_gamepadManager = nullptr;
  145. #endif
  146. if (s_cpeDlg)
  147. {
  148. delete s_cpeDlg;
  149. s_cpeDlg = nullptr;
  150. }
  151. ccHObject* currentRoot = m_glWindow->getSceneDB();
  152. if (currentRoot)
  153. {
  154. m_glWindow->setSceneDB(nullptr);
  155. //m_glWindow->redraw();
  156. delete currentRoot;
  157. }
  158. }
  159. void ccViewer::loadPlugins()
  160. {
  161. ui.menuPlugins->setEnabled(false);
  162. ccPluginManager::Get().loadPlugins();
  163. for (ccPluginInterface* plugin : ccPluginManager::Get().pluginList())
  164. {
  165. if (plugin == nullptr)
  166. {
  167. Q_ASSERT(false);
  168. continue;
  169. }
  170. // is this a GL plugin?
  171. if (plugin->getType() == CC_GL_FILTER_PLUGIN)
  172. {
  173. ccGLPluginInterface* glPlugin = static_cast<ccGLPluginInterface*>(plugin);
  174. const QString pluginName = glPlugin->getName();
  175. Q_ASSERT(!pluginName.isEmpty());
  176. if (pluginName.isEmpty())
  177. {
  178. // should be unreachable - we have already checked for this in ccPlugins::Find()
  179. continue;
  180. }
  181. ccLog::Print(QStringLiteral("Plugin name: [%1] (GL filter)").arg(pluginName));
  182. QAction* action = new QAction(pluginName, this);
  183. action->setToolTip(glPlugin->getDescription());
  184. action->setIcon(glPlugin->getIcon());
  185. // store the plugin's interface pointer in the QAction data so we can access it in doEnableGLFilter()
  186. QVariant v;
  187. v.setValue(glPlugin);
  188. action->setData(v);
  189. connect(action, &QAction::triggered, this, &ccViewer::doEnableGLFilter);
  190. ui.menuPlugins->addAction(action);
  191. ui.menuPlugins->setEnabled(true);
  192. ui.menuPlugins->setVisible(true);
  193. }
  194. }
  195. }
  196. void ccViewer::doDisableGLFilter()
  197. {
  198. if (m_glWindow)
  199. {
  200. m_glWindow->setGlFilter(nullptr);
  201. m_glWindow->redraw();
  202. }
  203. }
  204. void ccViewer::doEnableGLFilter()
  205. {
  206. if (!m_glWindow)
  207. {
  208. ccLog::Warning("[GL filter] No active 3D view!");
  209. return;
  210. }
  211. QAction* action = qobject_cast<QAction*>(sender());
  212. if (action == nullptr)
  213. {
  214. Q_ASSERT(false);
  215. return;
  216. }
  217. ccGLPluginInterface *plugin = action->data().value<ccGLPluginInterface *>();
  218. if (plugin == nullptr)
  219. {
  220. return;
  221. }
  222. Q_ASSERT(plugin->getType() == CC_GL_FILTER_PLUGIN);
  223. ccGlFilter* filter = plugin->getFilter();
  224. if (filter != nullptr)
  225. {
  226. if (m_glWindow->areGLFiltersEnabled())
  227. {
  228. m_glWindow->setGlFilter(filter);
  229. ccLog::Print("Note: go to << Display > Shaders & Filters > No filter >> to disable GL filter");
  230. }
  231. else
  232. {
  233. ccLog::Error("GL filters not supported");
  234. }
  235. }
  236. else
  237. {
  238. ccLog::Error("Can't load GL filter (an error occurred)!");
  239. }
  240. }
  241. void ccViewer::doActionDeleteSelectedEntity()
  242. {
  243. ccHObject* currentRoot = m_glWindow->getSceneDB();
  244. if (!currentRoot)
  245. return;
  246. ccHObject::Container toCheck;
  247. toCheck.push_back(currentRoot);
  248. while (!toCheck.empty())
  249. {
  250. ccHObject* obj = toCheck.back();
  251. toCheck.pop_back();
  252. if (obj->isSelected())
  253. {
  254. if (obj->getParent())
  255. {
  256. obj->getParent()->addDependency(obj,ccHObject::DP_DELETE_OTHER); //we force deletion!
  257. obj->getParent()->removeChild(obj);
  258. }
  259. else
  260. {
  261. delete obj;
  262. obj = nullptr;
  263. }
  264. }
  265. else
  266. {
  267. for (unsigned i = 0; i < obj->getChildrenNumber(); ++i)
  268. {
  269. toCheck.push_back(obj->getChild(i));
  270. }
  271. }
  272. }
  273. m_glWindow->redraw();
  274. }
  275. void ccViewer::selectEntity(ccHObject* toSelect)
  276. {
  277. ccHObject* currentRoot = m_glWindow->getSceneDB();
  278. if (!currentRoot)
  279. return;
  280. currentRoot->setSelected_recursive(false);
  281. ui.menuSelectSF->clear();
  282. ui.menuSelected->setEnabled(false);
  283. if (toSelect)
  284. {
  285. toSelect->setSelected(true);
  286. ui.actionShowColors->blockSignals(true);
  287. ui.actionShowNormals->blockSignals(true);
  288. ui.actionShowMaterials->blockSignals(true);
  289. ui.actionShowScalarField->blockSignals(true);
  290. ui.actionShowColorRamp->blockSignals(true);
  291. ui.actionShowColors->setEnabled(toSelect->hasColors());
  292. ui.actionShowColors->setChecked(toSelect->colorsShown());
  293. ui.actionShowNormals->setEnabled(toSelect->hasNormals());
  294. ui.actionShowNormals->setChecked(toSelect->normalsShown());
  295. if (toSelect->isKindOf(CC_TYPES::MESH))
  296. {
  297. ccGenericMesh* mesh = static_cast<ccGenericMesh*>(toSelect);
  298. ui.actionShowMaterials->setEnabled(mesh->hasMaterials());
  299. ui.actionShowMaterials->setChecked(mesh->materialsShown());
  300. }
  301. else
  302. {
  303. ui.actionShowMaterials->setEnabled(false);
  304. ui.actionShowMaterials->setChecked(false);
  305. }
  306. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(toSelect);
  307. bool hasSF = (cloud ? cloud->hasScalarFields() : false);
  308. ui.actionShowScalarField->setEnabled(hasSF);
  309. ui.actionShowScalarField->setChecked(toSelect->sfShown());
  310. ui.actionShowColorRamp->setEnabled(hasSF);
  311. ui.actionShowColorRamp->setChecked(cloud ? cloud->sfColorScaleShown() && cloud->sfShown() : false);
  312. unsigned sfCount = (cloud ? cloud->getNumberOfScalarFields() : 0);
  313. ui.menuSelectSF->setEnabled(hasSF && sfCount>1);
  314. if (hasSF && sfCount > 1)
  315. {
  316. int currentSFIndex = cloud->getCurrentDisplayedScalarFieldIndex();
  317. //ui.menuSelectSF->clear();
  318. for (unsigned i = 0; i < sfCount; ++i)
  319. {
  320. QAction* action = ui.menuSelectSF->addAction(QString::fromStdString(cloud->getScalarFieldName(i)));
  321. action->setData(i);
  322. action->setCheckable(true);
  323. if (currentSFIndex == static_cast<int>(i))
  324. action->setChecked(true);
  325. connect(action, &QAction::toggled, this, &ccViewer::changeCurrentScalarField);
  326. }
  327. }
  328. ui.menuSelected->setEnabled(true);
  329. ui.actionShowColors->blockSignals(false);
  330. ui.actionShowNormals->blockSignals(false);
  331. ui.actionShowMaterials->blockSignals(false);
  332. ui.actionShowScalarField->blockSignals(false);
  333. ui.actionShowColorRamp->blockSignals(false);
  334. m_selectedObject = toSelect;
  335. }
  336. m_glWindow->redraw();
  337. }
  338. bool ccViewer::checkForLoadedEntities()
  339. {
  340. bool loadedEntities = true;
  341. m_glWindow->displayNewMessage(QString(), ccGLWindowInterface::SCREEN_CENTER_MESSAGE); //clear (any) message in the middle area
  342. if (!m_glWindow->getSceneDB())
  343. {
  344. m_glWindow->displayNewMessage("Drag & drop files on the 3D window to load them!", ccGLWindowInterface::SCREEN_CENTER_MESSAGE, true, 3600);
  345. loadedEntities = false;
  346. }
  347. if (m_glWindow->getDisplayParameters().displayCross != loadedEntities)
  348. {
  349. ccGui::ParamStruct params = m_glWindow->getDisplayParameters();
  350. params.displayCross = loadedEntities;
  351. m_glWindow->setDisplayParameters(params);
  352. }
  353. return loadedEntities;
  354. }
  355. void ccViewer::updateDisplay()
  356. {
  357. updateGLFrameGradient();
  358. m_glWindow->redraw();
  359. }
  360. void ccViewer::updateGLFrameGradient()
  361. {
  362. //display parameters
  363. static const ccColor::Rgbub s_black(0, 0, 0);
  364. static const ccColor::Rgbub s_white(255, 255, 255);
  365. bool stereoModeEnabled = m_glWindow->stereoModeIsEnabled();
  366. const ccColor::Rgbub& bkgCol = stereoModeEnabled ? s_black : m_glWindow->getDisplayParameters().backgroundCol;
  367. const ccColor::Rgbub& forCol = stereoModeEnabled ? s_white : m_glWindow->getDisplayParameters().pointsDefaultCol;
  368. QString styleSheet = QString("QFrame#GLframe{border: 2px solid white; border-radius: 10px; background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 rgb(%1,%2,%3), stop:1 rgb(%4,%5,%6));}")
  369. .arg(bkgCol.r)
  370. .arg(bkgCol.g)
  371. .arg(bkgCol.b)
  372. .arg(255-forCol.r)
  373. .arg(255-forCol.g)
  374. .arg(255-forCol.b);
  375. ui.GLframe->setStyleSheet(styleSheet);
  376. }
  377. ccHObject* ccViewer::addToDB(QStringList filenames)
  378. {
  379. ccHObject* currentRoot = m_glWindow->getSceneDB();
  380. if (currentRoot)
  381. {
  382. m_selectedObject = nullptr;
  383. m_glWindow->setSceneDB(nullptr);
  384. m_glWindow->redraw();
  385. delete currentRoot;
  386. currentRoot = nullptr;
  387. }
  388. bool scaleAlreadyDisplayed = false;
  389. FileIOFilter::LoadParameters parameters;
  390. parameters.alwaysDisplayLoadDialog = false;
  391. parameters.shiftHandlingMode = ccGlobalShiftManager::NO_DIALOG_AUTO_SHIFT;
  392. parameters.parentWidget = this;
  393. const ccOptions& options = ccOptions::Instance();
  394. FileIOFilter::ResetSesionCounter();
  395. ccHObject* firstLoadedEntity = nullptr;
  396. for (int i = 0; i < filenames.size(); ++i)
  397. {
  398. CC_FILE_ERROR result = CC_FERR_NO_ERROR;
  399. ccHObject* newGroup = FileIOFilter::LoadFromFile(filenames[i], parameters, result);
  400. if (newGroup)
  401. {
  402. if (!options.normalsDisplayedByDefault)
  403. {
  404. //disable the normals on all loaded clouds!
  405. ccHObject::Container clouds;
  406. newGroup->filterChildren(clouds, true, CC_TYPES::POINT_CLOUD);
  407. for (ccHObject* cloud : clouds)
  408. {
  409. if (cloud)
  410. {
  411. static_cast<ccGenericPointCloud*>(cloud)->showNormals(false);
  412. }
  413. }
  414. }
  415. addToDB(newGroup);
  416. if (!scaleAlreadyDisplayed)
  417. {
  418. for (unsigned i = 0; i < newGroup->getChildrenNumber(); ++i)
  419. {
  420. ccHObject* ent = newGroup->getChild(i);
  421. if (ent->isA(CC_TYPES::POINT_CLOUD))
  422. {
  423. ccPointCloud* pc = static_cast<ccPointCloud*>(ent);
  424. if (pc->hasScalarFields())
  425. {
  426. pc->setCurrentDisplayedScalarField(0);
  427. pc->showSFColorsScale(true);
  428. scaleAlreadyDisplayed = true;
  429. }
  430. }
  431. else if (ent->isKindOf(CC_TYPES::MESH))
  432. {
  433. ccGenericMesh* mesh = static_cast<ccGenericMesh*>(ent);
  434. if (mesh->hasScalarFields())
  435. {
  436. mesh->showSF(true);
  437. scaleAlreadyDisplayed = true;
  438. ccPointCloud* pc = static_cast<ccPointCloud*>(mesh->getAssociatedCloud());
  439. pc->showSFColorsScale(true);
  440. }
  441. }
  442. }
  443. }
  444. if (!firstLoadedEntity)
  445. {
  446. firstLoadedEntity = newGroup;
  447. }
  448. }
  449. if (result == CC_FERR_CANCELED_BY_USER)
  450. {
  451. //stop importing the file if the user has cancelled the current process!
  452. break;
  453. }
  454. }
  455. checkForLoadedEntities();
  456. return firstLoadedEntity;
  457. }
  458. void ccViewer::addToDB( ccHObject* entity,
  459. bool updateZoom/*=false*/,
  460. bool autoExpandDBTree/*=true*/,
  461. bool checkDimensions/*=false*/,
  462. bool autoRedraw/*=true*/)
  463. {
  464. assert(entity && m_glWindow);
  465. entity->setDisplay_recursive(m_glWindow);
  466. ccHObject* currentRoot = m_glWindow->getSceneDB();
  467. if (currentRoot)
  468. {
  469. //already a pure 'root'
  470. if (currentRoot->isA(CC_TYPES::HIERARCHY_OBJECT))
  471. {
  472. currentRoot->addChild(entity);
  473. }
  474. else
  475. {
  476. ccHObject* root = new ccHObject("root");
  477. root->addChild(currentRoot);
  478. root->addChild(entity);
  479. m_glWindow->setSceneDB(root);
  480. }
  481. }
  482. else
  483. {
  484. m_glWindow->setSceneDB(entity);
  485. }
  486. checkForLoadedEntities();
  487. }
  488. void ccViewer::removeFromDB(ccHObject* obj, bool autoDelete/*=true*/)
  489. {
  490. ccHObject* currentRoot = m_glWindow->getSceneDB();
  491. if (currentRoot)
  492. {
  493. if (currentRoot == obj)
  494. {
  495. m_glWindow->setSceneDB(nullptr);
  496. if (autoDelete)
  497. {
  498. delete currentRoot;
  499. }
  500. }
  501. else
  502. {
  503. currentRoot->removeChild(obj);
  504. }
  505. }
  506. m_glWindow->redraw();
  507. }
  508. void ccViewer::showDisplayParameters()
  509. {
  510. ccDisplaySettingsDlg clmDlg(this);
  511. connect(&clmDlg, &ccDisplaySettingsDlg::aspectHasChanged, this, &ccViewer::updateDisplay);
  512. clmDlg.exec();
  513. disconnect(&clmDlg, nullptr, nullptr, nullptr);
  514. }
  515. void ccViewer::doActionEditCamera()
  516. {
  517. if (!s_cpeDlg)
  518. {
  519. s_cpeDlg = new ccCameraParamEditDlg(this, nullptr);
  520. s_cpeDlg->linkWith(m_glWindow);
  521. }
  522. s_cpeDlg->show();
  523. }
  524. void ccViewer::reflectPerspectiveState()
  525. {
  526. if ( m_glWindow == nullptr )
  527. return;
  528. bool objectCentered = false;
  529. bool perspectiveEnabled = m_glWindow->getPerspectiveState(objectCentered);
  530. ui.actionSetOrthoView->setChecked(!perspectiveEnabled);
  531. ui.actionSetCenteredPerspectiveView->setChecked(perspectiveEnabled && objectCentered);
  532. ui.actionSetViewerPerspectiveView->setChecked(perspectiveEnabled && !objectCentered);
  533. }
  534. bool ccViewer::checkStereoMode()
  535. {
  536. if ( m_glWindow
  537. && m_glWindow->getViewportParameters().perspectiveView
  538. && m_glWindow->stereoModeIsEnabled())
  539. {
  540. if (QMessageBox::question(this,"Stereo mode", "Stereo-mode only works in perspective mode. Do you want to enable it?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
  541. {
  542. return false;
  543. }
  544. else
  545. {
  546. toggleStereoMode(false);
  547. }
  548. }
  549. return true;
  550. }
  551. void ccViewer::setOrthoView()
  552. {
  553. if (m_glWindow)
  554. {
  555. if (!checkStereoMode())
  556. return;
  557. m_glWindow->setPerspectiveState(false,true);
  558. m_glWindow->redraw();
  559. }
  560. reflectPerspectiveState();
  561. }
  562. void ccViewer::setCenteredPerspectiveView()
  563. {
  564. if (m_glWindow)
  565. {
  566. m_glWindow->setPerspectiveState(true, true);
  567. m_glWindow->redraw();
  568. }
  569. reflectPerspectiveState();
  570. }
  571. void ccViewer::setViewerPerspectiveView()
  572. {
  573. if (m_glWindow)
  574. {
  575. m_glWindow->setPerspectiveState(true,false);
  576. m_glWindow->redraw();
  577. }
  578. reflectPerspectiveState();
  579. }
  580. void ccViewer::reflectPivotVisibilityState()
  581. {
  582. if ( m_glWindow == nullptr )
  583. return;
  584. ccGLWindowInterface::PivotVisibility vis = m_glWindow->getPivotVisibility();
  585. ui.actionSetPivotAlwaysOn->setChecked(vis == ccGLWindowInterface::PIVOT_ALWAYS_SHOW);
  586. ui.actionSetPivotRotationOnly->setChecked(vis == ccGLWindowInterface::PIVOT_SHOW_ON_MOVE);
  587. ui.actionSetPivotOff->setChecked(vis == ccGLWindowInterface::PIVOT_HIDE);
  588. }
  589. void ccViewer::setPivotAlwaysOn()
  590. {
  591. if (m_glWindow)
  592. {
  593. m_glWindow->setPivotVisibility(ccGLWindowInterface::PIVOT_ALWAYS_SHOW);
  594. m_glWindow->redraw();
  595. }
  596. reflectPivotVisibilityState();
  597. }
  598. void ccViewer::setPivotRotationOnly()
  599. {
  600. if (m_glWindow)
  601. {
  602. m_glWindow->setPivotVisibility(ccGLWindowInterface::PIVOT_SHOW_ON_MOVE);
  603. m_glWindow->redraw();
  604. }
  605. reflectPivotVisibilityState();
  606. }
  607. void ccViewer::setPivotOff()
  608. {
  609. if (m_glWindow)
  610. {
  611. m_glWindow->setPivotVisibility(ccGLWindowInterface::PIVOT_HIDE);
  612. m_glWindow->redraw();
  613. }
  614. reflectPivotVisibilityState();
  615. }
  616. void ccViewer::reflectLightsState()
  617. {
  618. if ( m_glWindow == nullptr )
  619. return;
  620. ui.actionToggleSunLight->blockSignals(true);
  621. ui.actionToggleCustomLight->blockSignals(true);
  622. ui.actionToggleSunLight->setChecked(m_glWindow->sunLightEnabled());
  623. ui.actionToggleCustomLight->setChecked(m_glWindow->customLightEnabled());
  624. ui.actionToggleSunLight->blockSignals(false);
  625. ui.actionToggleCustomLight->blockSignals(false);
  626. }
  627. void ccViewer::toggleSunLight(bool state)
  628. {
  629. if (m_glWindow)
  630. m_glWindow->setSunLight(state);
  631. reflectLightsState();
  632. }
  633. void ccViewer::toggleCustomLight(bool state)
  634. {
  635. if (m_glWindow)
  636. m_glWindow->setCustomLight(state);
  637. reflectLightsState();
  638. }
  639. void ccViewer::toggleStereoMode(bool state)
  640. {
  641. if (!m_glWindow)
  642. return;
  643. bool isActive = m_glWindow->stereoModeIsEnabled();
  644. if (isActive == state)
  645. {
  646. //nothing to do
  647. return;
  648. }
  649. if (isActive)
  650. {
  651. m_glWindow->disableStereoMode();
  652. if ( m_glWindow->getStereoParams().glassType == ccGLWindowInterface::StereoParams::NVIDIA_VISION
  653. || m_glWindow->getStereoParams().glassType == ccGLWindowInterface::StereoParams::GENERIC_STEREO_DISPLAY)
  654. {
  655. //disable full screen
  656. ui.actionFullScreen->setChecked(false);
  657. }
  658. }
  659. else
  660. {
  661. //display a parameters dialog
  662. ccStereoModeDlg smDlg(this);
  663. smDlg.setParameters(m_glWindow->getStereoParams());
  664. if (!smDlg.exec())
  665. {
  666. //cancelled by the user
  667. ui.actionEnableStereo->blockSignals(true);
  668. ui.actionEnableStereo->setChecked(false);
  669. ui.actionEnableStereo->blockSignals(false);
  670. return;
  671. }
  672. ccGLWindowInterface::StereoParams params = smDlg.getParameters();
  673. if (!ccGLWindowInterface::StereoSupported() && !params.isAnaglyph())
  674. {
  675. ccLog::Error(tr("It seems your graphic card doesn't support Quad Buffered Stereo rendering"));
  676. //activation of the stereo mode failed: cancel selection
  677. ui.actionEnableStereo->blockSignals(true);
  678. ui.actionEnableStereo->setChecked(false);
  679. ui.actionEnableStereo->blockSignals(false);
  680. return;
  681. }
  682. //force perspective state!
  683. if (!m_glWindow->getViewportParameters().perspectiveView)
  684. {
  685. m_glWindow->setPerspectiveState(true, true);
  686. reflectPerspectiveState();
  687. }
  688. if ( params.glassType == ccGLWindowInterface::StereoParams::NVIDIA_VISION
  689. || params.glassType == ccGLWindowInterface::StereoParams::GENERIC_STEREO_DISPLAY)
  690. {
  691. //force full screen
  692. ui.actionFullScreen->setChecked(true);
  693. }
  694. if (!m_glWindow->enableStereoMode(params))
  695. {
  696. //activation of the stereo mode failed: cancel selection
  697. ui.actionEnableStereo->blockSignals(true);
  698. ui.actionEnableStereo->setChecked(false);
  699. ui.actionEnableStereo->blockSignals(false);
  700. }
  701. }
  702. updateDisplay();
  703. }
  704. void ccViewer::toggleFullScreen(bool state)
  705. {
  706. if (m_glWindow)
  707. {
  708. if ( m_glWindow->stereoModeIsEnabled()
  709. && ( m_glWindow->getStereoParams().glassType == ccGLWindowInterface::StereoParams::NVIDIA_VISION
  710. || m_glWindow->getStereoParams().glassType == ccGLWindowInterface::StereoParams::GENERIC_STEREO_DISPLAY)
  711. )
  712. {
  713. //auto disable stereo mode as NVidia Vision only works in full screen mode!
  714. ui.actionEnableStereo->setChecked(false);
  715. }
  716. m_glWindow->toggleExclusiveFullScreen(state);
  717. }
  718. }
  719. void ccViewer::onExclusiveFullScreenToggled(bool state)
  720. {
  721. ui.actionFullScreen->blockSignals(true);
  722. ui.actionFullScreen->setChecked(m_glWindow ? m_glWindow->exclusiveFullScreen() : false);
  723. ui.actionFullScreen->blockSignals(false);
  724. if ( !state
  725. && m_glWindow
  726. && m_glWindow->stereoModeIsEnabled()
  727. && ( m_glWindow->getStereoParams().glassType == ccGLWindowInterface::StereoParams::NVIDIA_VISION
  728. || m_glWindow->getStereoParams().glassType == ccGLWindowInterface::StereoParams::GENERIC_STEREO_DISPLAY)
  729. )
  730. {
  731. //auto disable stereo mode as NVidia Vision only works in full screen mode!
  732. ui.actionEnableStereo->setChecked(false);
  733. }
  734. }
  735. void ccViewer::toggleRotationAboutVertAxis()
  736. {
  737. if (!m_glWindow)
  738. return;
  739. bool wasLocked = m_glWindow->isRotationAxisLocked();
  740. bool isLocked = !wasLocked;
  741. m_glWindow->lockRotationAxis(isLocked, CCVector3d(0.0, 0.0, 1.0));
  742. ui.actionLockRotationVertAxis->blockSignals(true);
  743. ui.actionLockRotationVertAxis->setChecked(isLocked);
  744. ui.actionLockRotationVertAxis->blockSignals(false);
  745. if (isLocked)
  746. {
  747. m_glWindow->displayNewMessage(QString("[ROTATION LOCKED]"), ccGLWindowInterface::UPPER_CENTER_MESSAGE, false, 24 * 3600, ccGLWindowInterface::ROTAION_LOCK_MESSAGE);
  748. }
  749. else
  750. {
  751. m_glWindow->displayNewMessage(QString(), ccGLWindowInterface::UPPER_CENTER_MESSAGE, false, 0, ccGLWindowInterface::ROTAION_LOCK_MESSAGE);
  752. }
  753. m_glWindow->redraw();
  754. }
  755. void ccViewer::doActionDisplayShortcuts()
  756. {
  757. QMessageBox msgBox;
  758. QString text;
  759. text += "Shortcuts:\n\n";
  760. text += "F2 : Set orthographic view\n";
  761. text += "F3 : Set object-centered perspective\n";
  762. text += "F4 : Set viewer-based perspective\n";
  763. text += "F6 : Toggle sun light\n";
  764. text += "F7 : Toggle custom light\n";
  765. text += "F8 : Toggle Console display\n";
  766. text += "F9 : Toggle full screen\n";
  767. text += "F11: Toggle exclusive full screen\n";
  768. text += "Z : Zoom on selected entity\n";
  769. text += "L : Lock rotation around Z\n";
  770. text += "B : Enter/leave bubble view mode\n";
  771. text += "DEL: Delete selected entity\n";
  772. text += "+ : Zoom in\n";
  773. text += "- : Zoom out\n";
  774. text += "\n";
  775. text += "Shift + C: Toggle color ramp visibility\n";
  776. text += "Shift + up arrow: activate previous SF\n";
  777. text += "Shift + down arrow: activate next SF\n";
  778. text += "\n";
  779. text += "Ctrl + D: Display parameters\n";
  780. text += "Ctrl + C: Camera parameters\n";
  781. text += "\n";
  782. text += "Left click: Select entity\n";
  783. //text += "Ctrl + left click: Select multiple entities (toggle)\n";
  784. //text += "Alt + left button hold: Select multiple entities (rectangular area)\n";
  785. text += "Shift + left click (on a point/triangle): spawn a label\n";
  786. text += "Right click (on a label): expand/collapse\n";
  787. msgBox.setText(text);
  788. msgBox.exec();
  789. }
  790. void ccViewer::setTopView()
  791. {
  792. m_glWindow->setView(CC_TOP_VIEW);
  793. }
  794. void ccViewer::setBottomView()
  795. {
  796. m_glWindow->setView(CC_BOTTOM_VIEW);
  797. }
  798. void ccViewer::setFrontView()
  799. {
  800. m_glWindow->setView(CC_FRONT_VIEW);
  801. }
  802. void ccViewer::setBackView()
  803. {
  804. m_glWindow->setView(CC_BACK_VIEW);
  805. }
  806. void ccViewer::setLeftView()
  807. {
  808. m_glWindow->setView(CC_LEFT_VIEW);
  809. }
  810. void ccViewer::setRightView()
  811. {
  812. m_glWindow->setView(CC_RIGHT_VIEW);
  813. }
  814. void ccViewer::setIsoView1()
  815. {
  816. m_glWindow->setView(CC_ISO_VIEW_1);
  817. }
  818. void ccViewer::setIsoView2()
  819. {
  820. m_glWindow->setView(CC_ISO_VIEW_2);
  821. }
  822. void ccViewer::toggleColorsShown(bool state)
  823. {
  824. if (!m_selectedObject)
  825. return;
  826. m_selectedObject->showColors(state);
  827. m_glWindow->redraw();
  828. }
  829. void ccViewer::toggleNormalsShown(bool state)
  830. {
  831. if (!m_selectedObject)
  832. return;
  833. m_selectedObject->showNormals(state);
  834. m_glWindow->redraw();
  835. }
  836. void ccViewer::toggleMaterialsShown(bool state)
  837. {
  838. if (m_selectedObject && m_selectedObject->isKindOf(CC_TYPES::MESH))
  839. {
  840. static_cast<ccGenericMesh*>(m_selectedObject)->showMaterials(state);
  841. m_glWindow->redraw();
  842. }
  843. }
  844. void ccViewer::toggleScalarShown(bool state)
  845. {
  846. if (!m_selectedObject)
  847. return;
  848. m_selectedObject->showSF(state);
  849. m_glWindow->redraw();
  850. }
  851. void ccViewer::toggleColorbarShown(bool state)
  852. {
  853. if (!m_selectedObject)
  854. return;
  855. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_selectedObject);
  856. if (!cloud)
  857. return;
  858. cloud->showSFColorsScale(state);
  859. m_glWindow->redraw(true, false);
  860. }
  861. void ccViewer::changeCurrentScalarField(bool state)
  862. {
  863. if (!m_selectedObject)
  864. return;
  865. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_selectedObject);
  866. if (!cloud)
  867. return;
  868. QAction* action = qobject_cast<QAction*>(QObject::sender());
  869. if (!action)
  870. return;
  871. //disable all other actions
  872. const QObjectList& children = ui.menuSelectSF->children();
  873. for (int i = 0; i < children.size(); ++i)
  874. {
  875. QAction* act = static_cast<QAction*>(children[i]);
  876. act->blockSignals(true);
  877. act->setChecked(act == action);
  878. act->blockSignals(false);
  879. }
  880. int sfIndex = action->data().toInt();
  881. if (sfIndex < static_cast<int>(cloud->getNumberOfScalarFields()))
  882. {
  883. cloud->setCurrentDisplayedScalarField(sfIndex);
  884. //when 'setCurrentDisplayedScalarField' is called, scalar field is automatically shown!
  885. ui.actionShowScalarField->blockSignals(true);
  886. ui.actionShowScalarField->setChecked(true);
  887. ui.actionShowScalarField->blockSignals(false);
  888. m_glWindow->redraw();
  889. }
  890. }
  891. void ccViewer::setGlobalZoom()
  892. {
  893. if (m_glWindow)
  894. m_glWindow->zoomGlobal();
  895. }
  896. void ccViewer::zoomOnSelectedEntity()
  897. {
  898. if (!m_glWindow || !m_selectedObject)
  899. return;
  900. ccBBox box = m_selectedObject->getDisplayBB_recursive(false, m_glWindow);
  901. m_glWindow->updateConstellationCenterAndZoom(&box);
  902. m_glWindow->redraw();
  903. }
  904. #include <ui_ccviewerAbout.h>
  905. void ccViewer::doActionAbout()
  906. {
  907. QDialog aboutDialog(this);
  908. Ui::AboutDialog ui;
  909. ui.setupUi(&aboutDialog);
  910. ui.textEdit->setHtml(ui.textEdit->toHtml().arg(ccApp->versionLongStr( true )));
  911. aboutDialog.exec();
  912. }
  913. /*** 3D MOUSE SUPPORT ***/
  914. void ccViewer::release3DMouse()
  915. {
  916. #ifdef CC_3DXWARE_SUPPORT
  917. if (m_3dMouseInput)
  918. {
  919. m_3dMouseInput->disconnect(); //disconnect from the driver
  920. disconnect(m_3dMouseInput); //disconnect from Qt ;)
  921. delete m_3dMouseInput;
  922. m_3dMouseInput = 0;
  923. }
  924. #endif
  925. }
  926. void ccViewer::enable3DMouse(bool state)
  927. {
  928. #ifdef CC_3DXWARE_SUPPORT
  929. if (m_3dMouseInput)
  930. release3DMouse();
  931. if (state)
  932. {
  933. m_3dMouseInput = new Mouse3DInput(this);
  934. if (m_3dMouseInput->connect(this,"ccViewer"))
  935. {
  936. QObject::connect(m_3dMouseInput, &Mouse3DInput::sigMove3d, this, &ccViewer::on3DMouseMove);
  937. QObject::connect(m_3dMouseInput, &Mouse3DInput::sigReleased, this, &ccViewer::on3DMouseReleased);
  938. QObject::connect(m_3dMouseInput, &Mouse3DInput::sigOn3dmouseKeyDown, this, &ccViewer::on3DMouseKeyDown);
  939. QObject::connect(m_3dMouseInput, &Mouse3DInput::sigOn3dmouseKeyUp, this, &ccViewer::on3DMouseKeyUp);
  940. QObject::connect(m_3dMouseInput, &Mouse3DInput::sigOn3dmouseCMDKeyDown, this, &ccViewer::on3DMouseCMDKeyDown);
  941. QObject::connect(m_3dMouseInput, &Mouse3DInput::sigOn3dmouseCMDKeyUp, this, &ccViewer::on3DMouseCMDKeyUp);
  942. }
  943. else
  944. {
  945. delete m_3dMouseInput;
  946. m_3dMouseInput = 0;
  947. ccLog::Warning("[3D Mouse] No device found");
  948. state = false;
  949. }
  950. }
  951. else
  952. {
  953. ccLog::Warning("[3D Mouse] Device has been disabled");
  954. }
  955. #else
  956. state = false;
  957. #endif
  958. ui.actionEnable3DMouse->blockSignals(true);
  959. ui.actionEnable3DMouse->setChecked(state);
  960. ui.actionEnable3DMouse->blockSignals(false);
  961. }
  962. void ccViewer::on3DMouseKeyUp(int)
  963. {
  964. //nothing right now
  965. }
  966. // ANY CHANGE/BUG FIX SHOULD BE REFLECTED TO THE EQUIVALENT METHODS IN QCC "MainWindow.cpp" FILE!
  967. void ccViewer::on3DMouseKeyDown(int key)
  968. {
  969. #ifdef CC_3DXWARE_SUPPORT
  970. switch(key)
  971. {
  972. case Mouse3DInput::V3DK_MENU:
  973. //should be handled by the driver now!
  974. break;
  975. case Mouse3DInput::V3DK_FIT:
  976. {
  977. if (m_selectedObject)
  978. zoomOnSelectedEntity();
  979. else
  980. setGlobalZoom();
  981. }
  982. break;
  983. case Mouse3DInput::V3DK_TOP:
  984. setTopView();
  985. break;
  986. case Mouse3DInput::V3DK_LEFT:
  987. setLeftView();
  988. break;
  989. case Mouse3DInput::V3DK_RIGHT:
  990. setRightView();
  991. break;
  992. case Mouse3DInput::V3DK_FRONT:
  993. setFrontView();
  994. break;
  995. case Mouse3DInput::V3DK_BOTTOM:
  996. setBottomView();
  997. break;
  998. case Mouse3DInput::V3DK_BACK:
  999. setBackView();
  1000. break;
  1001. case Mouse3DInput::V3DK_ROTATE:
  1002. //should be handled by the driver now!
  1003. break;
  1004. case Mouse3DInput::V3DK_PANZOOM:
  1005. //should be handled by the driver now!
  1006. break;
  1007. case Mouse3DInput::V3DK_ISO1:
  1008. setIsoView1();
  1009. break;
  1010. case Mouse3DInput::V3DK_ISO2:
  1011. setIsoView2();
  1012. break;
  1013. case Mouse3DInput::V3DK_PLUS:
  1014. //should be handled by the driver now!
  1015. break;
  1016. case Mouse3DInput::V3DK_MINUS:
  1017. //should be handled by the driver now!
  1018. break;
  1019. case Mouse3DInput::V3DK_DOMINANT:
  1020. //should be handled by the driver now!
  1021. break;
  1022. case Mouse3DInput::V3DK_CW:
  1023. case Mouse3DInput::V3DK_CCW:
  1024. {
  1025. if (m_glWindow)
  1026. {
  1027. CCVector3d axis(0,0,-1);
  1028. CCVector3d trans(0,0,0);
  1029. ccGLMatrixd mat;
  1030. double angle = M_PI/2;
  1031. if (key == Mouse3DInput::V3DK_CCW)
  1032. angle = -angle;
  1033. mat.initFromParameters(angle,axis,trans);
  1034. m_glWindow->rotateBaseViewMat(mat);
  1035. m_glWindow->redraw();
  1036. }
  1037. }
  1038. break;
  1039. case Mouse3DInput::V3DK_ESC:
  1040. case Mouse3DInput::V3DK_ALT:
  1041. case Mouse3DInput::V3DK_SHIFT:
  1042. case Mouse3DInput::V3DK_CTRL:
  1043. default:
  1044. ccLog::Warning("[3D mouse] This button is not handled (yet)");
  1045. //TODO
  1046. break;
  1047. }
  1048. #endif
  1049. }
  1050. void ccViewer::on3DMouseCMDKeyUp(int cmd)
  1051. {
  1052. //nothing right now
  1053. }
  1054. void ccViewer::on3DMouseCMDKeyDown(int cmd)
  1055. {
  1056. #ifdef CC_3DXWARE_SUPPORT
  1057. switch (cmd)
  1058. {
  1059. //ccLog::Print(QString("on3DMouseCMDKeyDown Cmd = %1").arg(cmd));
  1060. case Mouse3DInput::V3DCMD_VIEW_FIT:
  1061. {
  1062. if (m_selectedObject)
  1063. zoomOnSelectedEntity();
  1064. else
  1065. setGlobalZoom();
  1066. }
  1067. break;
  1068. case Mouse3DInput::V3DCMD_VIEW_TOP:
  1069. setTopView();
  1070. break;
  1071. case Mouse3DInput::V3DCMD_VIEW_LEFT:
  1072. setLeftView();
  1073. break;
  1074. case Mouse3DInput::V3DCMD_VIEW_RIGHT:
  1075. setRightView();
  1076. break;
  1077. case Mouse3DInput::V3DCMD_VIEW_FRONT:
  1078. setFrontView();
  1079. break;
  1080. case Mouse3DInput::V3DCMD_VIEW_BOTTOM:
  1081. setBottomView();
  1082. break;
  1083. case Mouse3DInput::V3DCMD_VIEW_BACK:
  1084. setBackView();
  1085. break;
  1086. case Mouse3DInput::V3DCMD_VIEW_ISO1:
  1087. setIsoView1();
  1088. break;
  1089. case Mouse3DInput::V3DCMD_VIEW_ISO2:
  1090. setIsoView2();
  1091. break;
  1092. case Mouse3DInput::V3DCMD_VIEW_ROLLCW:
  1093. case Mouse3DInput::V3DCMD_VIEW_ROLLCCW:
  1094. {
  1095. if (m_glWindow)
  1096. {
  1097. CCVector3d axis(0, 0, -1);
  1098. CCVector3d trans(0, 0, 0);
  1099. ccGLMatrixd mat;
  1100. double angle = M_PI / 2;
  1101. if (cmd == Mouse3DInput::V3DCMD_VIEW_ROLLCCW)
  1102. angle = -angle;
  1103. mat.initFromParameters(angle, axis, trans);
  1104. m_glWindow->rotateBaseViewMat(mat);
  1105. m_glWindow->redraw();
  1106. }
  1107. }
  1108. break;
  1109. case Mouse3DInput::V3DCMD_VIEW_SPINCW:
  1110. case Mouse3DInput::V3DCMD_VIEW_SPINCCW:
  1111. {
  1112. if (m_glWindow)
  1113. {
  1114. CCVector3d axis(0, 1, 0);
  1115. CCVector3d trans(0, 0, 0);
  1116. ccGLMatrixd mat;
  1117. double angle = M_PI / 2;
  1118. if (cmd == Mouse3DInput::V3DCMD_VIEW_SPINCCW)
  1119. angle = -angle;
  1120. mat.initFromParameters(angle, axis, trans);
  1121. m_glWindow->rotateBaseViewMat(mat);
  1122. m_glWindow->redraw();
  1123. }
  1124. }
  1125. case Mouse3DInput::V3DCMD_VIEW_TILTCW:
  1126. case Mouse3DInput::V3DCMD_VIEW_TILTCCW:
  1127. {
  1128. if (m_glWindow)
  1129. {
  1130. CCVector3d axis(1, 0, 0);
  1131. CCVector3d trans(0, 0, 0);
  1132. ccGLMatrixd mat;
  1133. double angle = M_PI / 2;
  1134. if (cmd == Mouse3DInput::V3DCMD_VIEW_TILTCCW)
  1135. angle = -angle;
  1136. mat.initFromParameters(angle, axis, trans);
  1137. m_glWindow->rotateBaseViewMat(mat);
  1138. m_glWindow->redraw();
  1139. }
  1140. }
  1141. break;
  1142. default:
  1143. ccLog::Warning("[3D mouse] This button is not handled (yet)");
  1144. //TODO
  1145. break;
  1146. }
  1147. #endif
  1148. }
  1149. void ccViewer::on3DMouseMove(std::vector<float>& vec)
  1150. {
  1151. #ifdef CC_3DXWARE_SUPPORT
  1152. if (m_glWindow)
  1153. Mouse3DInput::Apply(vec, m_glWindow);
  1154. #endif
  1155. }
  1156. void ccViewer::on3DMouseReleased()
  1157. {
  1158. //active window?
  1159. if (m_glWindow && m_glWindow->getPivotVisibility() == ccGLWindowInterface::PIVOT_SHOW_ON_MOVE)
  1160. {
  1161. //we have to hide the pivot symbol!
  1162. m_glWindow->showPivotSymbol(false);
  1163. m_glWindow->redraw();
  1164. }
  1165. }
  1166. const ccHObject::Container& ccViewer::getSelectedEntities() const
  1167. {
  1168. static ccHObject::Container Empty;
  1169. return Empty;
  1170. }
  1171. void ccViewer::dispToConsole(QString message, ConsoleMessageLevel level)
  1172. {
  1173. printf("%s\n", qPrintable(message));
  1174. }
  1175. ccHObject* ccViewer::dbRootObject()
  1176. {
  1177. return m_glWindow->getSceneDB();
  1178. }
  1179. void ccViewer::redrawAll(bool only2D/*=false*/)
  1180. {
  1181. m_glWindow->redraw(only2D);
  1182. }
  1183. void ccViewer::refreshAll(bool only2D/*=false*/)
  1184. {
  1185. m_glWindow->refresh(only2D);
  1186. }
  1187. void ccViewer::enableAll()
  1188. {
  1189. m_glWindow->asWidget()->setEnabled(true);
  1190. }
  1191. void ccViewer::disableAll()
  1192. {
  1193. m_glWindow->asWidget()->setEnabled(false);
  1194. }
  1195. void ccViewer::disableAllBut(ccGLWindowInterface* win)
  1196. {
  1197. if (win != m_glWindow)
  1198. {
  1199. m_glWindow->asWidget()->setEnabled(false);
  1200. }
  1201. }
  1202. void ccViewer::setView(CC_VIEW_ORIENTATION view)
  1203. {
  1204. m_glWindow->setView(view, true);
  1205. }
  1206. void ccViewer::toggleActiveWindowCustomLight()
  1207. {
  1208. ui.actionToggleCustomLight->setChecked(!ui.actionToggleCustomLight->isChecked());
  1209. }
  1210. void ccViewer::toggleActiveWindowSunLight()
  1211. {
  1212. ui.actionToggleSunLight->setChecked(!ui.actionToggleSunLight->isChecked());
  1213. }
  1214. void ccViewer::toggleActiveWindowCenteredPerspective()
  1215. {
  1216. if (ui.actionSetCenteredPerspectiveView->isChecked())
  1217. {
  1218. ui.actionSetOrthoView->trigger();
  1219. }
  1220. else
  1221. {
  1222. ui.actionSetCenteredPerspectiveView->trigger();
  1223. }
  1224. }
  1225. void ccViewer::toggleActiveWindowViewerBasedPerspective()
  1226. {
  1227. if (ui.actionSetViewerPerspectiveView->isChecked())
  1228. {
  1229. ui.actionSetOrthoView->trigger();
  1230. }
  1231. else
  1232. {
  1233. ui.actionSetViewerPerspectiveView->trigger();
  1234. }
  1235. }
  1236. void ccViewer::increasePointSize()
  1237. {
  1238. m_glWindow->setPointSize(m_glWindow->getViewportParameters().defaultPointSize + 1);
  1239. m_glWindow->redraw();
  1240. }
  1241. void ccViewer::decreasePointSize()
  1242. {
  1243. m_glWindow->setPointSize(m_glWindow->getViewportParameters().defaultPointSize - 1);
  1244. m_glWindow->redraw();
  1245. }
  1246. ccUniqueIDGenerator::Shared ccViewer::getUniqueIDGenerator()
  1247. {
  1248. return ccObject::GetUniqueIDGenerator();
  1249. }