highlighting/selecting a point in cloud

Any question about the main GUI application (frontend)
Post Reply
vinayan
Posts: 27
Joined: Thu Nov 03, 2016 4:11 pm

highlighting/selecting a point in cloud

Post by vinayan »

hi,

I managed to highlight and zoom to a line object referring the centerAndZoom functionality in mainwindow.

Code: Select all

ccHObject* lineObj = getLineObj();
bbox = lineObj->getOwnBB();
m_app->setSelectedInDB(lineObj, true);
glWindow->updateConstellationCenterAndZoom(&bbox); 
but the same code for point does not show a bounding box on screen for selection. Is there any way to add this box to a point? Since there was no bounding box for point, I added a one unit bbox like shown below and it is zooming to the point box. Is there some way I can show that selection box there?

Code: Select all

ccHObject* pointObj = pcloud->getChild(pointIndex);
m_app->setSelectedInDB(pointObj, true);
bbox = ccBBox(CCVector3(point->x - 1, point->y - 1, point->z - 1), CCVector3(point->x + 1, point->y + 1, point->z + 1));
glWindow->updateConstellationCenterAndZoom(&bbox);
daniel
Site Admin
Posts: 7713
Joined: Wed Oct 13, 2010 7:34 am
Location: Grenoble, France
Contact:

Re: highlighting/selecting a point in cloud

Post by daniel »

I'm not sure about the call to

Code: Select all

ccHObject* pointObj = pcloud->getChild(pointIndex);
Well, assuming it's the case, then indeed the bounding-box of a cloud with a single point inside has a null dimension (this is why the zoom doesn't work, and this is why you can't see it in the 3D view). Therefore you are right to 'enlarge' the bounding-box so as to provide a scale for the 'updateConstellationCenterAndZoom' method.

One clean way to fix this would be to create a child class of ccPointCloud, that only re-implements the 'getOwnBB' method and returns a box with a fixed size in the case there's only one point in the cloud. This way you won't have to enlarge the box yourself, and the selection box would be visible. Of course this only works if you create the clouds yourself (in your plugin).
Daniel, CloudCompare admin
vinayan
Posts: 27
Joined: Thu Nov 03, 2016 4:11 pm

Re: highlighting/selecting a point in cloud

Post by vinayan »

thanks..i will give this a try..I am creating the clouds myself. This is just a plugin to let user capture a few points from cloud.
returns a box with a fixed size in the case there's only one point in the cloud.
does this mean I need to create a temporary cloud just for zooming to a point?

Code: Select all

ccHObject* pointObj = pcloud->getChild(pointIndex);
Suppose I subclass the ccPointCloud. Now is there anything that I can override so that it will return a box for the ccHObject* obtained above in the case the bbox is null?
daniel
Site Admin
Posts: 7713
Joined: Wed Oct 13, 2010 7:34 am
Location: Grenoble, France
Contact:

Re: highlighting/selecting a point in cloud

Post by daniel »

No you don't need to create a cloud only for zooming. Instead of creating ccPointCloud instances for each point the user has picked, you would create your own point cloud instance that you have subclassed from ccPointCloud. And this subclass only needs to re-implement the 'getOwnBB' method.

P.S.: just to be sure: you know the 'Point list picking' tool, don't you?
Daniel, CloudCompare admin
vinayan
Posts: 27
Joined: Thu Nov 03, 2016 4:11 pm

Re: highlighting/selecting a point in cloud

Post by vinayan »

okay it is clear now. I will try it out. Of course i know the point list picking tool :)
vinayan
Posts: 27
Joined: Thu Nov 03, 2016 4:11 pm

Re: highlighting/selecting a point in cloud

Post by vinayan »

I have to admit my c++ is rather weak. I managed to do like below.

ccHighlightCloud .h

Code: Select all

#include<ccPointCloud.h>

class ccHighlightCloud : public ccPointCloud
{
public:
	ccHighlightCloud();

	ccBBox getOwnBB(bool withGLFeatures/*=false*/);
};
ccHighlightCloud.cpp

Code: Select all

#include "ccHighlightCloud.h"

ccHighlightCloud::ccHighlightCloud()
{
}


ccBBox ccHighlightCloud::getOwnBB(bool withGLFeatures/*=false*/)
{

	ccBBox box;

	const CCVector3* point = getPoint(0);

	if (!point) return box;

	box = ccBBox(CCVector3(point->x - 1, point->y - 1, point->z - 1), CCVector3(point->x + 1, point->y + 1, point->z + 1));

	if (size())
	{
		getBoundingBox(box.minCorner(), box.maxCorner());
		box.setValidity(true);
	}

	return box;
}
I created a cloud, added it to DbTree(is it required?) and invoked the below code hoping my above adventure would yield something.

Code: Select all

ccPointCloud* tempCloud = createTempCloud(Pglobal);
		m_app->addToDB(tempCloud);	

		ccHighlightCloud*  highCloud = static_cast<ccHighlightCloud*>(tempCloud);
		ccHObject* pointObj = highCloud->getChild(pointIndex);
		m_app->setSelectedInDB(pointObj, true);

When i debugged, this is giving false to the below code..Is there something that I have done horribly wrong here?

Code: Select all

void MainWindow::setSelectedInDB(ccHObject* obj, bool selected)
{
	if (obj && m_ccRoot) //this is giving false :( 
daniel
Site Admin
Posts: 7713
Joined: Wed Oct 13, 2010 7:34 am
Location: Grenoble, France
Contact:

Re: highlighting/selecting a point in cloud

Post by daniel »

First, I believe you should rewrite your 'ccHighlightCloud::getOwnBB' method to something like this:

Code: Select all

ccBBox ccHighlightCloud::getOwnBB(bool withGLFeatures/*=false*/)
{
  ccBBox box;

  if (size() == 1)
  {
	//specific case with only one point
	const CCVector3* point = getPoint(0);
	box = ccBBox(CCVector3(point->x - 1, point->y - 1, point->z - 1), CCVector3(point->x + 1, point->y + 1, point->z + 1));
  }
  else if (size() > 1)
  {
	//generic case
	return ccPointCloud::getOwnBB(withGLFeatures);
  }
  else
  {
  	//empty cloud
  }
  
   return box;
}
Then, what does your 'createTempCloud' method do? And why are you looking at the children of the ccHighlightCloud instance? I thought that the ccHighlightCloud instances would be the children of the original cloud... Not the opposite. It's not surprising that the call to highCloud->getChild(pointIndex) returns no object (i.e. obj == 0).

Last remark: you don't need to cast a 'ccPointCloud' instance to 'ccHighlightCloud' to call 'getChild' (as it's a member of the ccHObject class which is a parent of both 'ccPointCloud' and 'ccHighlightCloud'). Anyway I think the issue is probably in your 'createTempCloud' method and you should actually select the 'ccHighlightCloud' instance directly and not one of its children (it shouldn't have any children ;).
Daniel, CloudCompare admin
vinayan
Posts: 27
Joined: Thu Nov 03, 2016 4:11 pm

Re: highlighting/selecting a point in cloud

Post by vinayan »

ah..it never really occurred to me that I should add this subclassed cloud to the existing cloud as a child. This works perfectly now. Thanks a lot for reviewing the code. So I guess I should take care of removing this child and adding a new one everything a highlight is needed. At present I have not removed it but seems to work fine.

Code: Select all

CCVector3d Pglobal = pcloud->toGlobal3d<PointCoordinateType>(*point);
ccHighlightCloud* highCloud = createTempCloud(Pglobal);
pcloud->addChild(highCloud, 24, 0);
Post Reply