ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ccCompassDlg.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "ccCompassDlg.h"
9 
10 // CV_DB_LIB
11 #include <CVLog.h>
12 
13 // Qt
14 #include <qaction.h>
15 #include <qmenu.h>
16 
17 #include <QApplication>
18 #include <QEvent>
19 #include <QKeyEvent>
20 
21 // system
22 #include <assert.h>
23 
24 ccCompassDlg::ccCompassDlg(QWidget* parent /*=0*/)
25  : ccOverlayDialog(parent), Ui::compassDlg() {
26  setupUi(this);
27 
28  // setup "algorithm" dropdown
29  m_cost_algorithm_menu = new QMenu(this);
30  m_cost_algorithm_menu->setTitle("Algorithm");
31  m_dark = new QAction("Darkness", this);
32  m_dark->setCheckable(true);
33  m_dark->setChecked(true);
34  m_light = new QAction("Lightness", this);
35  m_light->setCheckable(true);
36  m_rgb = new QAction("RGB similarity", this);
37  m_rgb->setCheckable(true);
38  m_grad = new QAction("RGB gradient", this);
39  m_grad->setCheckable(true); // m_grad->setEnabled(true);
40  m_curve = new QAction("Curvature", this);
41  m_curve->setCheckable(true); // m_curve->setEnabled(false);
42  m_dist = new QAction("Distance", this);
43  m_dist->setCheckable(true);
44  m_scalar = new QAction("Scalar field", this);
45  m_scalar->setCheckable(true);
46  m_scalar_inv = new QAction("Inverse scalar field", this);
47  m_scalar_inv->setCheckable(true);
48  m_recalculate = new QAction("Recalculate selection",
49  this); // used to recalculate selected traces
50  // with new cost function
51  m_plane_fit = new QAction("Fit planes", this);
52  m_plane_fit->setCheckable(true);
53  m_plane_fit->setChecked(true);
54 
55  // setup tool-tips
56  m_dark->setToolTip(
57  "Traces follow 'dark' points. Good for shadowed fracture traces.");
58  m_light->setToolTip(
59  "Traces follow 'light' points. Good for thin quartz veins etc.");
60  m_rgb->setToolTip(
61  "Traces follow points that have a similar color to the start and "
62  "end points. Useful if structures being traced have a distinct "
63  "color.");
64  m_grad->setToolTip(
65  "Traces follow points in neighbourhoods with high colour "
66  "gradients. Good for contacts.");
67  m_curve->setToolTip(
68  "Traces follow ridges and valleys. Good for fractures with high "
69  "relief, especially in combination with \"Darkness\".");
70  m_dist->setToolTip(
71  "Traces take the shortest euclidean path (how booring...)");
72  m_scalar->setToolTip(
73  "Use the active scalar field to define path cost (i.e. the path "
74  "follows low scalar values).");
75  m_scalar_inv->setToolTip(
76  "Use the inverse of the active scalar field to define path cost "
77  "(i.e. the path follows high scalar values).");
78  m_recalculate->setToolTip(
79  "Recalculate the selected traces using the latest cost function");
80 
81  // add to menu
82  m_cost_algorithm_menu->addAction(m_dark);
83  m_cost_algorithm_menu->addAction(m_light);
84  m_cost_algorithm_menu->addAction(m_rgb);
85  m_cost_algorithm_menu->addAction(m_grad);
86  m_cost_algorithm_menu->addAction(m_curve);
87  m_cost_algorithm_menu->addAction(m_dist);
88  m_cost_algorithm_menu->addAction(m_scalar);
89  m_cost_algorithm_menu->addAction(m_scalar_inv);
90  m_cost_algorithm_menu->addSeparator();
92 
93  // add callbacks
94  ccCompassDlg::connect(m_dark, SIGNAL(triggered()), this,
95  SLOT(setDarkCost()));
96  ccCompassDlg::connect(m_light, SIGNAL(triggered()), this,
97  SLOT(setLightCost()));
98  ccCompassDlg::connect(m_rgb, SIGNAL(triggered()), this, SLOT(setRGBCost()));
99  ccCompassDlg::connect(m_grad, SIGNAL(triggered()), this,
100  SLOT(setGradCost()));
101  ccCompassDlg::connect(m_curve, SIGNAL(triggered()), this,
102  SLOT(setCurveCost()));
103  ccCompassDlg::connect(m_dist, SIGNAL(triggered()), this,
104  SLOT(setDistCost()));
105  ccCompassDlg::connect(m_scalar, SIGNAL(triggered()), this,
106  SLOT(setScalarCost()));
107  ccCompassDlg::connect(m_scalar_inv, SIGNAL(triggered()), this,
108  SLOT(setInvScalarCost()));
109 
110  // setup settings menu
111  m_settings_menu = new QMenu(this);
112  m_plane_fit = new QAction("Fit planes", this);
113  m_plane_fit->setCheckable(true);
114  m_plane_fit->setChecked(false);
115  m_showStippled = new QAction("Show stippled", this);
116  m_showStippled->setCheckable(true);
117  m_showStippled->setChecked(true);
118  m_showNormals = new QAction("Show normals", this);
119  m_showNormals->setCheckable(true);
120  m_showNormals->setChecked(true);
121  m_showNames = new QAction("Show names", this);
122  m_showNames->setCheckable(true);
123  m_showNames->setChecked(false);
124 
125  m_plane_fit->setToolTip(
126  "If checked, a plane will automatically be fitted to traces "
127  "matching the criteria defined in the ccCompass description.");
128  m_showStippled->setToolTip(
129  "If checked, planes will be drawn partially transparent "
130  "(stippled).");
131  m_showNormals->setToolTip("If checked, plane normals will be drawn.");
132  m_showNames->setToolTip(
133  "If checked, plane orientations will be displayed in the 3D view.");
134 
135  m_settings_menu->addAction(m_plane_fit);
136  m_settings_menu->addAction(m_showStippled);
137  m_settings_menu->addAction(m_showNormals);
138  m_settings_menu->addAction(m_showNames);
139  m_settings_menu->addSeparator();
141 
142  algorithmButton->setPopupMode(QToolButton::InstantPopup);
143  algorithmButton->setMenu(m_settings_menu); // add settings menu
144  algorithmButton->setEnabled(true);
145 
146  // setup pair picking menu
147  m_pairpicking_menu = new QMenu(this);
148  m_research_menu = new QMenu(this);
149  m_research_menu->setTitle("Research");
150 
151  m_loadFoliations = new QAction("Import foliations...", this);
152  m_loadLineations = new QAction("Import lineations...", this);
153  m_toSVG = new QAction("Export SVG...", this);
154  m_noteTool = new QAction("Add note", this);
155  m_pinchTool = new QAction("Add pinch nodes", this);
156  m_measure_thickness = new QAction("Measure one-point thickness", this);
158  new QAction("Measure two-point thickness", this);
159  m_youngerThan = new QAction("Assign \"Younger-Than\" relationship", this);
160  m_youngerThan->setEnabled(false); // todo
161  m_follows = new QAction("Assign \"Follows\" relationship", this);
162  m_follows->setEnabled(false);
163  m_equivalent = new QAction("Assign \"Equivalent\" relationship", this);
164  m_equivalent->setEnabled(false);
165  m_fitPlaneToGeoObject = new QAction("Fit plane to GeoObject", this);
166  m_mergeSelected = new QAction("Merge selected GeoObjects", this);
167  m_estimateNormals = new QAction("Estimate structure normals", this);
168 
169  m_pinchTool->setToolTip(
170  "Add Pinch Node objects to record features such as dyke tips or "
171  "sedimentary units that pinch-out.");
172  m_loadFoliations->setToolTip(
173  "Converts a point cloud containing points (measurement location) "
174  "and dip/dip-direction scalar fields to planes.");
175  m_loadLineations->setToolTip(
176  "Convert a point cloud containing measurement points and "
177  "trend->plunge scalar fields into foliation objects.");
178  m_toSVG->setToolTip(
179  "Export the currently visible trace to a SVG vector graphic using "
180  "an orthographic projection of the current view.");
181  m_noteTool->setToolTip(
182  "Add short notes to a point in a point cloud for future "
183  "reference.");
184  m_measure_thickness->setToolTip(
185  "Select a plane and then a point to measure plane-perpendicular "
186  "thickness.");
187  m_measure_thickness_twoPoint->setToolTip(
188  "Measure the plane-perpendicular distance between two points.");
189  m_youngerThan->setToolTip(
190  "Pick two GeoObjects to assign a \"younger-than\" (i.e. "
191  "crosscutting, superposition) relationshi.p");
192  m_follows->setToolTip(
193  "Select two GeoObjects to assign a \"follows\" (i.e. conformable) "
194  "relationship.");
195  m_equivalent->setToolTip(
196  "Select two GeoObjects to assign an \"equivalent\" (i.e. coeval) "
197  "relationship.");
198  m_fitPlaneToGeoObject->setToolTip(
199  "Calculates best fit planes for the entire upper/lower surfaces of "
200  "the GeoObject.");
201  m_mergeSelected->setToolTip(
202  "Merge all selected GeoObjects into a single GeoObject.");
203  m_estimateNormals->setToolTip(
204  "Estimate trace structure normals with maximum a-postiori plane "
205  "fitting algorithm.");
206 
207  m_pairpicking_menu->addAction(m_pinchTool);
210  m_pairpicking_menu->addAction(m_noteTool);
211  m_pairpicking_menu->addSeparator();
212  // m_pairpicking_menu->addAction(m_youngerThan); //TODO - reenable these
213  // once topology code has been fixed
214  // m_pairpicking_menu->addAction(m_follows);
215  // m_pairpicking_menu->addAction(m_equivalent);
216  // m_pairpicking_menu->addSeparator();
220  m_pairpicking_menu->addSeparator();
223  m_pairpicking_menu->addAction(m_toSVG);
224  m_pairpicking_menu->addSeparator();
226 
227  // Add tools to research menu
228  m_recalculateFitPlanes = new QAction("Recalculate fit-planes", this);
229  m_toPointCloud = new QAction("Convert to point cloud", this);
230  m_distributeSelection = new QAction("Distribute to GeoObjects", this);
231  m_estimateP21 = new QAction("Estimate P21 intensity", this);
232  m_estimateStrain = new QAction("Estimate strain", this);
233 
234  m_recalculateFitPlanes->setToolTip(
235  "Recalculates all fit-planes deriving from traces and GeoObjects "
236  "(but not those calculated with the Plane Tool).");
237  m_toPointCloud->setToolTip(
238  "Converts the selected GeoObject(s) or individual traces to a "
239  "point cloud (typically for proximity analysis).");
240  m_distributeSelection->setToolTip(
241  "Distributes the selected objects into GeoObjects that have "
242  "matching names.");
243  m_estimateP21->setToolTip(
244  "Uses structure traces and the mesh octree to measure fracture "
245  "intensity.");
246  m_estimateStrain->setToolTip(
247  "Estimate bulk strain tensor from Mode-I dykes and veins with "
248  "structure normal estimates.");
249 
251  m_research_menu->addAction(m_estimateP21);
252  m_research_menu->addAction(m_estimateStrain);
254  m_research_menu->addAction(m_toPointCloud);
255 
256  extraModeButton->setPopupMode(QToolButton::InstantPopup);
257  extraModeButton->setMenu(m_pairpicking_menu);
258 
259  // set background color
260  QPalette p;
261  p.setColor(backgroundRole(), QColor(240, 240, 240, 200));
262  setPalette(p);
263  setAutoFillBackground(true);
264 
265  // add shortcuts
266  addOverridenShortcut(Qt::Key_Escape); // escape key for the "cancel" button
267  addOverridenShortcut(Qt::Key_Return); // return key for the "apply" button
268  addOverridenShortcut(Qt::Key_Space); // space key also hits the "apply"
269  // button (easier for some)
270  connect(this, SIGNAL(shortcutTriggered(int)), this,
271  SLOT(onShortcutTriggered(int)));
272 }
273 
275  int out = 0;
276  if (m_dark->isChecked()) out = out | ccTrace::MODE::DARK;
277  if (m_light->isChecked()) out = out | ccTrace::MODE::LIGHT;
278  if (m_rgb->isChecked()) out = out | ccTrace::MODE::RGB;
279  if (m_curve->isChecked()) out = out | ccTrace::MODE::CURVE;
280  if (m_grad->isChecked()) out = out | ccTrace::MODE::GRADIENT;
281  if (m_dist->isChecked()) out = out | ccTrace::MODE::DISTANCE;
282  if (m_scalar->isChecked()) out = out | ccTrace::MODE::SCALAR;
283  if (m_scalar_inv->isChecked()) out = out | ccTrace::MODE::INV_SCALAR;
284 
285  if (out == 0)
286  return ccTrace::MODE::DISTANCE; // default to distance if everything
287  // has been unchecked
288 
289  return out;
290 }
291 
292 bool ccCompassDlg::planeFitMode() { return m_plane_fit->isChecked(); }
293 
295  switch (key) {
296  case Qt::Key_Return:
297  acceptButton->click();
298  return;
299  case Qt::Key_Space:
300  acceptButton->click();
301  return;
302  case Qt::Key_Escape:
303  closeButton->click();
304  return;
305  default:
306  // nothing to do
307  break;
308  }
309 }
void setDarkCost()
Definition: ccCompassDlg.h:89
QAction * m_equivalent
Definition: ccCompassDlg.h:62
void setInvScalarCost()
Definition: ccCompassDlg.h:117
QAction * m_showStippled
Definition: ccCompassDlg.h:49
ccCompassDlg(QWidget *parent=0)
Default constructor.
QAction * m_fitPlaneToGeoObject
Definition: ccCompassDlg.h:65
QAction * m_measure_thickness_twoPoint
Definition: ccCompassDlg.h:57
void setRGBCost()
Definition: ccCompassDlg.h:97
QAction * m_toPointCloud
Definition: ccCompassDlg.h:73
QAction * m_distributeSelection
Definition: ccCompassDlg.h:74
void setDistCost()
Definition: ccCompassDlg.h:109
QAction * m_measure_thickness
Definition: ccCompassDlg.h:56
QAction * m_estimateNormals
Definition: ccCompassDlg.h:68
QMenu * m_pairpicking_menu
Definition: ccCompassDlg.h:44
QMenu * m_cost_algorithm_menu
Definition: ccCompassDlg.h:42
QAction * m_showNormals
Definition: ccCompassDlg.h:50
QAction * m_estimateP21
Definition: ccCompassDlg.h:69
QAction * m_mergeSelected
Definition: ccCompassDlg.h:72
QAction * m_estimateStrain
Definition: ccCompassDlg.h:71
void setCurveCost()
Definition: ccCompassDlg.h:105
void setLightCost()
Definition: ccCompassDlg.h:93
QAction * m_toSVG
Definition: ccCompassDlg.h:82
QAction * m_follows
Definition: ccCompassDlg.h:60
QAction * m_plane_fit
Definition: ccCompassDlg.h:48
QAction * m_noteTool
Definition: ccCompassDlg.h:79
QAction * m_loadLineations
Definition: ccCompassDlg.h:81
QAction * m_youngerThan
Definition: ccCompassDlg.h:59
QAction * m_pinchTool
Definition: ccCompassDlg.h:55
QAction * m_showNames
Definition: ccCompassDlg.h:51
void setScalarCost()
Definition: ccCompassDlg.h:113
bool planeFitMode()
QAction * m_loadFoliations
Definition: ccCompassDlg.h:80
QAction * m_recalculateFitPlanes
Definition: ccCompassDlg.h:67
QMenu * m_research_menu
Definition: ccCompassDlg.h:45
QAction * m_recalculate
Definition: ccCompassDlg.h:52
void setGradCost()
Definition: ccCompassDlg.h:101
void onShortcutTriggered(int)
To capture overridden shortcuts (pause button, etc.)
QMenu * m_settings_menu
Definition: ccCompassDlg.h:43
Generic overlay dialog interface.
void shortcutTriggered(int key)
Signal emitted when an overridden key shortcut is pressed.
void addOverridenShortcut(Qt::Key key)