cc2.5DimEditor.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. //##########################################################################
  2. //# #
  3. //# CLOUDCOMPARE #
  4. //# #
  5. //# This program is free software; you can redistribute it and/or modify #
  6. //# it under the terms of the GNU General Public License as published by #
  7. //# the Free Software Foundation; version 2 or later of the License. #
  8. //# #
  9. //# This program is distributed in the hope that it will be useful, #
  10. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  11. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  12. //# GNU General Public License for more details. #
  13. //# #
  14. //# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
  15. //# #
  16. //##########################################################################
  17. #include "cc2.5DimEditor.h"
  18. //Local
  19. #include "ccBoundingBoxEditorDlg.h"
  20. #include "ccPersistentSettings.h"
  21. #include "mainwindow.h"
  22. //qCC_db
  23. #include <ccGenericPointCloud.h>
  24. #include <ccPointCloud.h>
  25. #include <ccScalarField.h>
  26. #include <ccProgressDialog.h>
  27. #include <ccColorTypes.h>
  28. //qCC_gl
  29. #include <ccGLWindowInterface.h>
  30. //Qt
  31. #include <QFrame>
  32. #include <QSettings>
  33. #include <QCoreApplication>
  34. //System
  35. #include <assert.h>
  36. cc2Point5DimEditor::cc2Point5DimEditor()
  37. : m_bbEditorDlg(nullptr)
  38. , m_glWindow(nullptr)
  39. , m_rasterCloud(nullptr)
  40. {
  41. }
  42. cc2Point5DimEditor::~cc2Point5DimEditor()
  43. {
  44. if (m_rasterCloud)
  45. {
  46. if (m_glWindow)
  47. m_glWindow->removeFromOwnDB(m_rasterCloud);
  48. delete m_rasterCloud;
  49. m_rasterCloud = nullptr;
  50. }
  51. }
  52. bool cc2Point5DimEditor::showGridBoxEditor()
  53. {
  54. if (m_bbEditorDlg)
  55. {
  56. unsigned char projDim = getProjectionDimension();
  57. assert(projDim < 3);
  58. m_bbEditorDlg->set2DMode(true, projDim);
  59. if (m_bbEditorDlg->exec())
  60. {
  61. gridIsUpToDate(false); // will call updateGridInfo
  62. return true;
  63. }
  64. }
  65. return false;
  66. }
  67. void cc2Point5DimEditor::createBoundingBoxEditor(const ccBBox& gridBBox, QWidget* parent)
  68. {
  69. if (!m_bbEditorDlg)
  70. {
  71. m_bbEditorDlg = new ccBoundingBoxEditorDlg(false, true, parent);
  72. m_bbEditorDlg->setBaseBBox(gridBBox, false);
  73. }
  74. }
  75. void cc2Point5DimEditor::create2DView(QFrame* parentFrame)
  76. {
  77. if (!m_glWindow)
  78. {
  79. QWidget* glWidget = nullptr;
  80. ccGLWindowInterface::Create(m_glWindow, glWidget, false, true);
  81. assert(m_glWindow && glWidget);
  82. ccGui::ParamStruct params = m_glWindow->getDisplayParameters();
  83. //black (text) & white (background) display by default
  84. params.backgroundCol = ccColor::white;
  85. params.textDefaultCol = ccColor::black;
  86. params.drawBackgroundGradient = false;
  87. params.decimateMeshOnMove = false;
  88. params.displayCross = false;
  89. params.colorScaleUseShader = false;
  90. m_glWindow->setDisplayParameters(params, true);
  91. m_glWindow->setPerspectiveState(false, true);
  92. m_glWindow->setInteractionMode(ccGLWindowInterface::INTERACT_PAN | ccGLWindowInterface::INTERACT_ZOOM_CAMERA | ccGLWindowInterface::INTERACT_CLICKABLE_ITEMS);
  93. m_glWindow->setPickingMode(ccGLWindowInterface::NO_PICKING);
  94. m_glWindow->displayOverlayEntities(true, false);
  95. m_glWindow->setSunLight(true);
  96. m_glWindow->setCustomLight(false);
  97. //add window to the input frame (if any)
  98. if (parentFrame)
  99. {
  100. auto layout = new QHBoxLayout;
  101. layout->setContentsMargins( 0, 0, 0, 0 );
  102. layout->addWidget( glWidget) ;
  103. parentFrame->setLayout( layout );
  104. }
  105. }
  106. }
  107. bool cc2Point5DimEditor::getGridSize(unsigned& gridWidth, unsigned& gridHeight) const
  108. {
  109. //vertical dimension
  110. const unsigned char Z = getProjectionDimension();
  111. //cloud bounding-box --> grid size
  112. ccBBox box = getCustomBBox();
  113. //grid step
  114. double gridStep = getGridStep();
  115. return ccRasterGrid::ComputeGridSize(Z, box, gridStep, gridWidth, gridHeight);
  116. }
  117. QString cc2Point5DimEditor::getGridSizeAsString() const
  118. {
  119. unsigned gridWidth = 0;
  120. unsigned gridHeight = 0;
  121. if (!getGridSize(gridWidth, gridHeight))
  122. {
  123. return QObject::tr("invalid grid box");
  124. }
  125. return QString("%1 x %2 (%3 cells)").arg(gridWidth).arg(gridHeight).arg(QLocale::system().toString(gridWidth * gridHeight));
  126. }
  127. ccBBox cc2Point5DimEditor::getCustomBBox() const
  128. {
  129. return (m_bbEditorDlg ? m_bbEditorDlg->getBox() : ccBBox());
  130. }
  131. void cc2Point5DimEditor::update2DDisplayZoom(ccBBox& box)
  132. {
  133. if (!m_glWindow || !m_grid.isValid())
  134. return;
  135. //equivalent to 'ccGLWindow::updateConstellationCenterAndZoom' but we take aspect ratio into account
  136. //we set the pivot point on the box center
  137. CCVector3 P = box.getCenter();
  138. m_glWindow->setPivotPoint(P);
  139. m_glWindow->setCameraPos(P);
  140. //we compute the pixel size (in world coordinates)
  141. {
  142. double realGridWidth = m_grid.width * m_grid.gridStep;
  143. double realGridHeight = m_grid.height * m_grid.gridStep;
  144. static const int screnMargin = 20;
  145. int screenWidth = std::max(1, m_glWindow->glWidth() - 2 * screnMargin);
  146. int screenHeight = std::max(1, m_glWindow->glHeight() - 2 * screnMargin);
  147. int pointSize = 1;
  148. if ( static_cast<int>(m_grid.width) < screenWidth
  149. && static_cast<int>(m_grid.height) < screenHeight)
  150. {
  151. int vPointSize = static_cast<int>(ceil(static_cast<float>(screenWidth) / m_grid.width));
  152. int hPointSize = static_cast<int>(ceil(static_cast<float>(screenHeight) / m_grid.height));
  153. pointSize = std::min(vPointSize, hPointSize);
  154. //if the grid is too small (i.e. necessary point size > 10)
  155. if (pointSize > 10)
  156. {
  157. pointSize = 10;
  158. screenWidth = m_grid.width * pointSize;
  159. screenHeight = m_grid.height * pointSize;
  160. }
  161. }
  162. double targetWidth = realGridWidth;
  163. if (realGridHeight / screenHeight > realGridWidth / screenWidth)
  164. {
  165. targetWidth = (realGridHeight * screenWidth) / screenHeight;
  166. }
  167. m_glWindow->setCameraFocalToFitWidth(static_cast<float>(targetWidth));
  168. m_glWindow->setPointSize(pointSize);
  169. }
  170. m_glWindow->invalidateViewport();
  171. m_glWindow->invalidateVisualization();
  172. m_glWindow->deprecate3DLayer();
  173. m_glWindow->redraw();
  174. }
  175. ccPointCloud* cc2Point5DimEditor::convertGridToCloud( bool exportHeightStats,
  176. bool exportSFStats,
  177. const std::vector<ccRasterGrid::ExportableFields>& exportedStatistics,
  178. bool projectSFs,
  179. bool projectColors,
  180. bool resampleInputCloudXY,
  181. bool resampleInputCloudZ,
  182. ccGenericPointCloud* inputCloud,
  183. double percentileValue,
  184. bool exportToOriginalCS,
  185. bool appendGridSizeToSFNames,
  186. ccProgressDialog* progressDialog/*=nullptr*/) const
  187. {
  188. //projection dimension
  189. const unsigned char Z = getProjectionDimension();
  190. assert(Z <= 2);
  191. //cloud bounding-box
  192. ccBBox box = getCustomBBox();
  193. assert(box.isValid());
  194. return m_grid.convertToCloud( exportHeightStats,
  195. exportSFStats,
  196. exportedStatistics,
  197. projectSFs,
  198. projectColors,
  199. resampleInputCloudXY,
  200. resampleInputCloudZ,
  201. inputCloud,
  202. Z,
  203. box,
  204. percentileValue,
  205. exportToOriginalCS,
  206. appendGridSizeToSFNames,
  207. progressDialog );
  208. }
  209. ccRasterGrid::EmptyCellFillOption cc2Point5DimEditor::getFillEmptyCellsStrategy(QComboBox* comboBox) const
  210. {
  211. if (!comboBox)
  212. {
  213. assert(false);
  214. return ccRasterGrid::LEAVE_EMPTY;
  215. }
  216. switch (comboBox->currentIndex())
  217. {
  218. case 0:
  219. return ccRasterGrid::LEAVE_EMPTY;
  220. case 1:
  221. return ccRasterGrid::FILL_MINIMUM_HEIGHT;
  222. case 2:
  223. return ccRasterGrid::FILL_AVERAGE_HEIGHT;
  224. case 3:
  225. return ccRasterGrid::FILL_MAXIMUM_HEIGHT;
  226. case 4:
  227. return ccRasterGrid::FILL_CUSTOM_HEIGHT;
  228. case 5:
  229. return ccRasterGrid::INTERPOLATE_DELAUNAY;
  230. case 6:
  231. return ccRasterGrid::KRIGING;
  232. default:
  233. //shouldn't be possible for this option!
  234. assert(false);
  235. }
  236. return ccRasterGrid::LEAVE_EMPTY;
  237. }