in the AcDbPointCloudEx::traverseAllPointData function ,how to use parameter IAcDbPointCloudSpatialFilter *PSpatialFilter,please show me a example.
Acad::ErrorStatus traverseAllPointData( IAcDbPointCloudPointProcessor* processor, IAcDbPointCloudSpatialFilter* pSpatialFilter, Adesk::UInt32 dataTypes, int LODLevel ) const;
Solved! Go to Solution.
in the AcDbPointCloudEx::traverseAllPointData function ,how to use parameter IAcDbPointCloudSpatialFilter *PSpatialFilter,please show me a example.
Acad::ErrorStatus traverseAllPointData( IAcDbPointCloudPointProcessor* processor, IAcDbPointCloudSpatialFilter* pSpatialFilter, Adesk::UInt32 dataTypes, int LODLevel ) const;
Solved! Go to Solution.
Solved by tbrammer. Go to Solution.
Here is a simple buildable sample that shows how to use IAcDbPointCloudSpatialFilter, written for AutoCAD 2018. All code is in acrxEntryPoint.cpp. See function void testPC(). It will be called with the command MYCOMMAND.
My filter class MyFilterPositiveCoordinats : public IAcDbPointCloudSpatialFilter simply filters the points having p.x, p.y and p.z >= 0.0.
I'm using class MyProcessor: public IAcDbPointCloudPointProcessor that simply counts the points that "arrive" an the point processor.
I have also added a sample DWG. If you move the pointcloud entity to different positions relative to the WCS origin the count will change.
Here is a simple buildable sample that shows how to use IAcDbPointCloudSpatialFilter, written for AutoCAD 2018. All code is in acrxEntryPoint.cpp. See function void testPC(). It will be called with the command MYCOMMAND.
My filter class MyFilterPositiveCoordinats : public IAcDbPointCloudSpatialFilter simply filters the points having p.x, p.y and p.z >= 0.0.
I'm using class MyProcessor: public IAcDbPointCloudPointProcessor that simply counts the points that "arrive" an the point processor.
I have also added a sample DWG. If you move the pointcloud entity to different positions relative to the WCS origin the count will change.
Thanks for your post and example tbrammer. I would like to choose some points in autocad and pass them in as bounds to define the spatial filter, but I can't figure out how to do it. Could you please give some advice/example on way to pass in points to the IAcDbPointCloudSpatialFilter class? Thank you.
Thanks for your post and example tbrammer. I would like to choose some points in autocad and pass them in as bounds to define the spatial filter, but I can't figure out how to do it. Could you please give some advice/example on way to pass in points to the IAcDbPointCloudSpatialFilter class? Thank you.
Basicly you have to modify these virtual methods to your needs:
class MyFilterPositiveCoordinats : public IAcDbPointCloudSpatialFilter {
virtual FilterResult testCell(const AcGePoint3d& min, const AcGePoint3d& max) const;
virtual FilterResult testPoint(const AcGePoint3d& point) const;
}
Can you specify how these "some points" shall specify the bounds? The implementation depends entirely upon this.
I.e.:
Basicly you have to modify these virtual methods to your needs:
class MyFilterPositiveCoordinats : public IAcDbPointCloudSpatialFilter {
virtual FilterResult testCell(const AcGePoint3d& min, const AcGePoint3d& max) const;
virtual FilterResult testPoint(const AcGePoint3d& point) const;
}
Can you specify how these "some points" shall specify the bounds? The implementation depends entirely upon this.
I.e.:
Thank you for the reply, I am trying to pass in two points, a minimum and maximum, like this:
AcGePoint3d min = AcGePoint3d(0, 0, 0);
AcGePoint3d max = AcGePoint3d(0.1, 0.1, 0.1);
myFilter.testCell(min, max);
es = pointCloud->addSpatialFilter(&myFilter);
And here is my pretty terrible attempt at the testCell function:
virtual FilterResult testCell(const AcGePoint3d& min, const AcGePoint3d& max) const
{
//code from tbrammer
AcGePoint3d p[8]; // 8 corner points of the cell
p[0].x = p[1].x = p[2].x = p[3].x = min.x;
p[4].x = p[5].x = p[6].x = p[7].x = max.x;
p[0].y = p[1].y = p[6].y = p[7].y = min.y;
p[4].y = p[5].y = p[2].y = p[3].y = max.y;
p[0].z = p[5].z = p[2].z = p[7].z = min.z;
p[4].z = p[1].z = p[6].z = p[3].z = max.z;
int i, nInside = 0, nOutside = 0;
AcGePoint3d pTest;
for (i = 0; i < 8; ++i)//for each corner point
{
pTest = mECS * p[i]; // Transform with ECS.
if (pTest.x < min.x && pTest.x > max.x)
++nOutside;
else if (pTest.y < min.y && pTest.y > max.y)
++nOutside;
else if (pTest.z < min.z && pTest.z > max.z)
++nOutside;
else
++nInside;
if ((nInside > 0) && (nOutside))
return FILTER_INTERSECTS;
}
return (nInside > 0) ? FILTER_INSIDE : FILTER_OUTSIDE;
return FILTER_INSIDE;
}
I'm not sure if all that code is even necessary, or how to use the min/max points in the testPoint function.
Thank you in advance.
Thank you for the reply, I am trying to pass in two points, a minimum and maximum, like this:
AcGePoint3d min = AcGePoint3d(0, 0, 0);
AcGePoint3d max = AcGePoint3d(0.1, 0.1, 0.1);
myFilter.testCell(min, max);
es = pointCloud->addSpatialFilter(&myFilter);
And here is my pretty terrible attempt at the testCell function:
virtual FilterResult testCell(const AcGePoint3d& min, const AcGePoint3d& max) const
{
//code from tbrammer
AcGePoint3d p[8]; // 8 corner points of the cell
p[0].x = p[1].x = p[2].x = p[3].x = min.x;
p[4].x = p[5].x = p[6].x = p[7].x = max.x;
p[0].y = p[1].y = p[6].y = p[7].y = min.y;
p[4].y = p[5].y = p[2].y = p[3].y = max.y;
p[0].z = p[5].z = p[2].z = p[7].z = min.z;
p[4].z = p[1].z = p[6].z = p[3].z = max.z;
int i, nInside = 0, nOutside = 0;
AcGePoint3d pTest;
for (i = 0; i < 8; ++i)//for each corner point
{
pTest = mECS * p[i]; // Transform with ECS.
if (pTest.x < min.x && pTest.x > max.x)
++nOutside;
else if (pTest.y < min.y && pTest.y > max.y)
++nOutside;
else if (pTest.z < min.z && pTest.z > max.z)
++nOutside;
else
++nInside;
if ((nInside > 0) && (nOutside))
return FILTER_INTERSECTS;
}
return (nInside > 0) ? FILTER_INSIDE : FILTER_OUTSIDE;
return FILTER_INSIDE;
}
I'm not sure if all that code is even necessary, or how to use the min/max points in the testPoint function.
Thank you in advance.
This won't work. The AcGePoint3ds min, max, point passed to the methods are the points that shall be tested! You have to add the min/max point of your boundary to class MyFilterPositiveCoordinats and check point coordinates against these boundary points like this:
class MyFilterPositiveCoordinats : public IAcDbPointCloudSpatialFilter
{
private:
AcGeMatrix3d mECS;
AcGePoint3d mPtMax; //Max point of your bounding box
AcGePoint3d mPtMin; //Min point of your bounding box
public:
MyFilterPositiveCoordinats(AcGePoint3d min, AcGePoint3d max)
: mPtMin(min), mPtMin(max)
{}
virtual FilterResult testCell(const AcGePoint3d& min, const AcGePoint3d& max) const {
...
if (pTest.x < mPtMin.x && pTest.x > mPtMax.x)
++nOutside;
else if (pTest.y < mPtMin.y && pTest.y > mPtMax.y)
++nOutside;
else if (pTest.z < mPtMin.z && pTest.z > mPtMax.z)
++nOutside;
...
}
virtual FilterResult testPoint(const AcGePoint3d& point) const
{
AcGePoint3d pTest = mECS * point;
if ((pTest.x < mPtMin.x) || (pTest.x > mPtMax.x))
return FILTER_OUTSIDE;
else if ((pTest.y < mPtMin.y) || (pTest.x > mPtMax.y))
return FILTER_OUTSIDE;
else if ((pTest.z < mPtMin.z) || (pTest.x > mPtMax.z))
return FILTER_OUTSIDE;
else
return FILTER_INSIDE;
}
}
...and you should rename class MyFilterPositiveCoordinats to something else like MyFilterBoundingBox 😉.
This won't work. The AcGePoint3ds min, max, point passed to the methods are the points that shall be tested! You have to add the min/max point of your boundary to class MyFilterPositiveCoordinats and check point coordinates against these boundary points like this:
class MyFilterPositiveCoordinats : public IAcDbPointCloudSpatialFilter
{
private:
AcGeMatrix3d mECS;
AcGePoint3d mPtMax; //Max point of your bounding box
AcGePoint3d mPtMin; //Min point of your bounding box
public:
MyFilterPositiveCoordinats(AcGePoint3d min, AcGePoint3d max)
: mPtMin(min), mPtMin(max)
{}
virtual FilterResult testCell(const AcGePoint3d& min, const AcGePoint3d& max) const {
...
if (pTest.x < mPtMin.x && pTest.x > mPtMax.x)
++nOutside;
else if (pTest.y < mPtMin.y && pTest.y > mPtMax.y)
++nOutside;
else if (pTest.z < mPtMin.z && pTest.z > mPtMax.z)
++nOutside;
...
}
virtual FilterResult testPoint(const AcGePoint3d& point) const
{
AcGePoint3d pTest = mECS * point;
if ((pTest.x < mPtMin.x) || (pTest.x > mPtMax.x))
return FILTER_OUTSIDE;
else if ((pTest.y < mPtMin.y) || (pTest.x > mPtMax.y))
return FILTER_OUTSIDE;
else if ((pTest.z < mPtMin.z) || (pTest.x > mPtMax.z))
return FILTER_OUTSIDE;
else
return FILTER_INSIDE;
}
}
...and you should rename class MyFilterPositiveCoordinats to something else like MyFilterBoundingBox 😉.
Thank you very much for the detailed explanation, I am now understanding how the spatial filtering works.
Thank you very much for the detailed explanation, I am now understanding how the spatial filtering works.
Can't find what you're looking for? Ask the community or share your knowledge.