Page 1 of 1
highlighting/selecting a point in cloud
Posted: Wed May 17, 2017 3:41 pm
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);
Re: highlighting/selecting a point in cloud
Posted: Wed May 17, 2017 5:45 pm
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).
Re: highlighting/selecting a point in cloud
Posted: Thu May 18, 2017 3:17 am
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?
Re: highlighting/selecting a point in cloud
Posted: Thu May 18, 2017 6:05 am
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?
Re: highlighting/selecting a point in cloud
Posted: Thu May 18, 2017 7:08 am
by vinayan
okay it is clear now. I will try it out. Of course i know the point list picking tool :)
Re: highlighting/selecting a point in cloud
Posted: Sun May 28, 2017 1:21 pm
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 :(
Re: highlighting/selecting a point in cloud
Posted: Sun May 28, 2017 5:42 pm
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 ;).
Re: highlighting/selecting a point in cloud
Posted: Mon May 29, 2017 8:23 am
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);