ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IAcDbPointCloudSpatialFilter help

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
Anonymous
945 Views, 6 Replies

IAcDbPointCloudSpatialFilter help

Anonymous
Not applicable

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;

0 Likes

IAcDbPointCloudSpatialFilter help

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;

6 REPLIES 6
Message 2 of 7
tbrammer
in reply to: Anonymous

tbrammer
Advisor
Advisor
Accepted 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.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

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.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 3 of 7
Jkirkla
in reply to: tbrammer

Jkirkla
Contributor
Contributor

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.

0 Likes

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.

Message 4 of 7
tbrammer
in reply to: Anonymous

tbrammer
Advisor
Advisor

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.:

  • 2 points that specify the min/max point of a bounding box
  • 4 points that specify the corners of a tetrahedron
  • N points that define a polyhedron which represent the "convex hull" around the points
  • N points that define the smallest sphere that holds all points
  • ...?

Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

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.:

  • 2 points that specify the min/max point of a bounding box
  • 4 points that specify the corners of a tetrahedron
  • N points that define a polyhedron which represent the "convex hull" around the points
  • N points that define the smallest sphere that holds all points
  • ...?

Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 5 of 7
Jkirkla
in reply to: tbrammer

Jkirkla
Contributor
Contributor

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.

0 Likes

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.

Message 6 of 7
tbrammer
in reply to: Anonymous

tbrammer
Advisor
Advisor

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 😉.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

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 😉.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 7 of 7
Jkirkla
in reply to: tbrammer

Jkirkla
Contributor
Contributor

Thank you very much for the detailed explanation, I am now understanding how the spatial filtering works.

0 Likes

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.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report