ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ccThicknessTool.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 "ccThicknessTool.h"
9 
10 #include "ccCompass.h"
11 #include "ccGeoObject.h"
12 
15 
17 
19 
20 // called when the selection is changed while this tool is active
22  const ccHObject::Container& selectedEntities) {
23  for (ccHObject* h : selectedEntities) {
24  ccPlane* p = dynamic_cast<ccPlane*>(h);
25  if (p && p->isDisplayed()) // this is a plane? [and it's shown - avoids
26  // confusion]
27  {
28  if (m_referencePlane) {
30  false); // go back to normal colour
31  }
32 
33  // store plane
34  m_referencePlane = p; // set the reference plane used to calculate
35  // the thickness
36 
37  // change colour
40 
41  // make all point clouds visible again
42  for (int i : m_hiddenObjects) {
43  ccHObject* cld = m_app->dbRootObject()->find(i);
44  cld->setVisible(true);
45  }
46  m_hiddenObjects.clear();
47 
48  // now hide all visible planes
49  recurseChildren(m_app->dbRootObject(), false, true);
50 
51  // make the reference plane visible
53 
54  // display instructions
56  "Select measurement point.",
58 
59  // redraw
60  ecvDisplayTools::RedrawDisplay(false, false);
61 
62  // done
63  return;
64  }
65  }
66 }
67 
68 // called when a point in a point cloud gets picked while this tool is active
70  unsigned itemIdx,
71  ccHObject* pickedObject,
72  const CCVector3& P) {
73  if (pickedObject->isA(
74  CV_TYPES::PLANE)) // we want to be able to pick planes
75  {
76  // select the object
77  m_app->setSelectedInDB(pickedObject, true);
78 
79  // call to update selection
81  }
82 }
83 
84 // called when a point in a point cloud gets picked while this tool is active
86  unsigned itemIdx,
87  ccPointCloud* cloud,
88  const CCVector3& P) {
89  // no plane, no deal
90  if (!m_referencePlane) {
92  "[ccCompass] Please select a fit-plane to constrain "
93  "true-thickness calculations.",
95  return;
96  }
97 
98  // get modified insert point (thicknesses are always added to GeoObject
99  // interiors if possible)
100  insertPoint = getInsertInterior(insertPoint);
101 
102  if (!ccThicknessTool::TWO_POINT_MODE) // one point mode - calculate plane
103  // to point distance and finish
104  {
105  float dist = planeToPointDistance(m_referencePlane, P);
106 
107  // build graphic
108  ccHObject* g = buildGraphic(P, dist);
109 
110  // add to scene graph
111  insertPoint->addChild(g);
112  m_app->addToDB(g, false, true, false, true);
113  } else // two point mode... which points have been defined?
114  {
115  if (!m_startPoint) // first point not yet defined - store it
116  {
117  // store point
118  m_startPoint = new CCVector3(P);
119 
120  // create temporary graphic
121  ccPointPair* temp = new ccPointPair(cloud);
122  temp->addPointIndex(itemIdx);
123  temp->showNameIn3D(true);
124  temp->setName("P1");
125  m_graphic_id = temp->getUniqueID();
126  insertPoint->addChild(temp);
127  m_app->addToDB(temp, false, false, false, true);
128 
129  // display instructions
131  "Select second measurement point.",
133 
134  } else {
135  // delete temporary graphic
137 
138  // calculate distance
139  float dist = planeToPointDistance(m_referencePlane, P) -
140  planeToPointDistance(m_referencePlane, *m_startPoint);
141 
142  ccHObject* g = buildGraphic(P, dist);
143 
144  // add to scene graph
145  insertPoint->addChild(g);
146  m_app->addToDB(g, false, true, false, true);
147 
148  // finish
149  delete m_startPoint;
150  m_startPoint = nullptr;
151  }
152  }
153 }
154 
155 ccHObject* ccThicknessTool::getInsertInterior(ccHObject* insertPoint) {
156  ccHObject* p = insertPoint;
157  while (p != nullptr) {
158  // object is a geoObject
159  if (ccGeoObject::isGeoObject(p)) {
160  ccGeoObject* obj = dynamic_cast<ccGeoObject*>(p);
161  if (obj) {
162  return obj->getRegion(
163  ccGeoObject::INTERIOR); // return the interior
164  }
165  }
166 
167  // try next parent
168  p = p->getParent();
169  }
170 
171  // haven't found a geoObject - use the supplied insertPoint
172  return insertPoint; // todo
173 }
174 
175 ccHObject* ccThicknessTool::buildGraphic(CCVector3 endPoint, float thickness) {
176  // back calculate the start point
177  CCVector3 start = endPoint - m_referencePlane->getNormal() * thickness;
178 
179  // create point cloud and add start/end points too it
180  ccPointCloud* verts = new ccPointCloud("vertices");
181  assert(verts);
182  verts->reserve(2);
183  verts->addPoint(start);
184  verts->addPoint(endPoint);
185  verts->invalidateBoundingBox();
186  verts->setEnabled(false); // this is used for storage only!
187  verts->setVisible(false); // this is used for storage only!
188 
189  // create a "thickness" graphic to display
190  ccThickness* graphic = new ccThickness(verts);
191  graphic->addPointIndex(0);
192  graphic->addPointIndex(1);
193  graphic->addChild(verts); // store the verts
194  graphic->invalidateBoundingBox();
195  graphic->updateMetadata();
196  graphic->setName(QString::asprintf("%.3fT", std::fabs(thickness)));
198 
199  // return
200  return graphic;
201 }
202 
203 // called when the tool is set to active (for initialization)
205  // hide all visible point clouds
206  recurseChildren(m_app->dbRootObject(), true, false);
207 
208  // display instructions
210  "Select reference plane for thickness measurement.",
212 
213  // redraw
214  ecvDisplayTools::RedrawDisplay(false, false);
215 }
216 
217 // called when the tool is set to disactive (for cleanup)
219  // delete start point object
220  if (m_startPoint) {
221  delete m_startPoint;
222  m_startPoint = nullptr;
223  }
224 
225  if (m_referencePlane) {
226  m_referencePlane->enableTempColor(false); // go back to normal colour
227  m_referencePlane = nullptr;
228  }
229 
230  // make all point clouds visible again
231  for (int i : m_hiddenObjects) {
232  ccHObject* cld = m_app->dbRootObject()->find(i);
233  cld->setVisible(true);
234  }
235  m_hiddenObjects.clear();
236 
237  // redraw
238  // m_app->getActiveWindow()->refresh();
239  ecvDisplayTools::RedrawDisplay(false, false);
240 }
241 
242 void ccThicknessTool::recurseChildren(ccHObject* obj,
243  bool hidePointClouds,
244  bool hidePlanes) {
245  // is this a point cloud?
246  if (hidePointClouds && obj->isA(CV_TYPES::POINT_CLOUD)) {
247  if (obj->isVisible()) {
248  obj->setVisible(false);
249  m_hiddenObjects.push_back(obj->getUniqueID());
250  }
251  return;
252  }
253 
254  // is this a plane?
255  if (hidePlanes && obj->isA(CV_TYPES::PLANE)) {
256  if (obj->isVisible()) {
257  obj->setVisible(false);
258  m_hiddenObjects.push_back(obj->getUniqueID());
259  }
260  return;
261  }
262 
263  // recurse on children
264  for (unsigned i = 0; i < obj->getChildrenNumber(); i++) {
265  recurseChildren(obj->getChild(i), hidePointClouds, hidePlanes);
266  }
267 }
268 
269 // called when "Return" or "Space" is pressed, or the "Accept Button" is clicked
271  // Reset the tool
273 
274  // go back to "plane pick mode"
275  toolActivated();
276 }
277 
278 // called when the "Escape" is pressed, or the "Cancel" button is clicked
280 
281 float ccThicknessTool::planeToPointDistance(ccPlane* plane, CCVector3 P) {
282  // declare array of 4 pointcoordtypes
283  PointCoordinateType pEq[4];
284 
285  // build equation of plane
286  pEq[0] = plane->getNormal().x;
287  pEq[1] = plane->getNormal().y;
288  pEq[2] = plane->getNormal().z;
289  pEq[3] = plane->getCenter().dot(
290  plane->getNormal()); // a point on the plane dot the plane normal
291 
292  // return distance
294  &P, pEq);
295 }
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
Definition: CVGeom.h:798
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
Type y
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
Type dot(const Vector3Tpl &v) const
Dot product.
Definition: CVGeom.h:408
static bool drawName
Definition: ccCompass.h:258
virtual bool isVisible() const
Returns whether entity is visible or not.
virtual void setTempColor(const ecvColor::Rgb &col, bool autoActivate=true)
Sets current temporary (unique)
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showNameIn3D(bool state)
Sets whether name should be displayed in 3D.
virtual void enableTempColor(bool state)
Set temporary color activation state.
static const int INTERIOR
Definition: ccGeoObject.h:54
ccHObject * getRegion(int mappingRegion)
Definition: ccGeoObject.cpp:73
static bool isGeoObject(ccHObject *object)
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
ccHObject * find(unsigned uniqueID)
Finds an entity in this object hierarchy.
virtual bool isDisplayed() const
Returns whether the object is actually displayed (visible) or not.
unsigned getChildrenNumber() const
Returns the number of children.
Definition: ecvHObject.h:312
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getParent() const
Returns parent object.
Definition: ecvHObject.h:245
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
Definition: ecvHObject.h:337
ccHObject * getChild(unsigned childPos) const
Returns the ith child.
Definition: ecvHObject.h:325
virtual unsigned getUniqueID() const
Returns object unique ID.
Definition: ecvObject.h:86
bool isA(CV_CLASS_ENUM type) const
Definition: ecvObject.h:131
virtual void setName(const QString &name)
Sets object name.
Definition: ecvObject.h:75
virtual void setEnabled(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:102
Plane (primitive)
Definition: ecvPlane.h:18
CCVector3 getCenter() const
Returns the center.
Definition: ecvPlane.h:56
CCVector3 getNormal() const override
Returns the entity normal.
Definition: ecvPlane.h:73
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void invalidateBoundingBox() override
Invalidates bounding box.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
virtual void onNewSelection(const ccHObject::Container &selectedEntities) override
virtual void toolActivated() override
std::vector< int > m_hiddenObjects
virtual void toolDisactivated() override
ccPlane * m_referencePlane
static ecvColor::Rgb ACTIVE_COLOR
static bool TWO_POINT_MODE
void cancel() override
virtual ~ccThicknessTool()
CCVector3 * m_startPoint
virtual void pointPicked(ccHObject *insertPoint, unsigned itemIdx, ccHObject *pickedObject, const CCVector3 &P) override
void accept() override
void updateMetadata() override
Definition: ccThickness.cpp:20
Definition: ccTool.h:18
ecvMainAppInterface * m_app
Definition: ccTool.h:67
static ScalarType computePoint2PlaneDistance(const CCVector3 *P, const PointCoordinateType *planeEquation)
Computes the (signed) distance between a point and a plane.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
void invalidateBoundingBox()
Invalidates the bounding-box.
RGB color structure.
Definition: ecvColorTypes.h:49
static void DisplayNewMessage(const QString &message, MessagePosition pos, bool append=false, int displayMaxDelay_sec=2, MessageType type=CUSTOM_MESSAGE)
Displays a status message in the bottom-left corner.
static void RedrawDisplay(bool only2D=false, bool forceRedraw=true)
virtual ccHObject * dbRootObject()=0
Returns DB root (as a ccHObject)
virtual const ccHObject::Container & getSelectedEntities() const =0
Returns currently selected entities ("read only")
virtual void setSelectedInDB(ccHObject *obj, bool selected)=0
Selects or unselects an entity (in db tree)
virtual void addToDB(ccHObject *obj, bool updateZoom=false, bool autoExpandDBTree=true, bool checkDimensions=false, bool autoRedraw=true)=0
virtual void dispToConsole(QString message, ConsoleMessageLevel level=STD_CONSOLE_MESSAGE)=0
virtual void removeFromDB(ccHObject *obj, bool autoDelete=true)=0
Removes an entity from main db tree.
__host__ __device__ float2 fabs(float2 v)
Definition: cutil_math.h:1254
static double dist(double x1, double y1, double x2, double y2)
Definition: lsd.c:207
@ POINT_CLOUD
Definition: CVTypes.h:104
@ PLANE
Definition: CVTypes.h:120
constexpr Rgb red(MAX, 0, 0)