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

How get the points from point cloud entity by loading the pcg file?

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
100053011
1052 Views, 7 Replies

How get the points from point cloud entity by loading the pcg file?

 

Hello,

 

I had a look at the objectArx header files and I saw that there is a AcPointCloud.h file hinting at some Point cloud processing functions. 

I want to get every point and its properties from the point cloud data,In order to data mining;

 

 I did try to follow the article here:http://forums.autodesk.com/t5/ObjectARX/Accessing-point-cloud-entity-loaded-from-a-pcg-file/td-p/343...

it is topic form xerion and owenwengerd;

but,When I access the points by

// init AcPcPointProcessor
AcPcPointProcessor* ptProc = new AcPcPointProcessor();
//IAcPcPointProcessor* iptProc=0;
Acad::ErrorStatus err = acdbProcessPointCloudData(pEnt, boundingBox, 100, ptProc);
AcPcPointFloat* pt = ptProc->buffer()->floatPoints();

It is always has an error in Memory?

what can 1 do? unless I am missing something?

I put all the code  below, I hope  xerion and owenwengerd give me a reply . or other one give me a reply?

 

 thanks;

 

 

7 REPLIES 7
Message 2 of 8
100053011
in reply to: 100053011

#include "AcPointCloud.h"
#include <vector>
using namespace std;

class ACDB_PORT PcDataBuffer:public IAcPcDataBuffer
{
public:

PcDataBuffer(void);

~PcDataBuffer(void);

///<summary>Indicate if the points are in single or double precision.</summary>
bool nativeDbl();

///<summary>Resize the buffer. This may be a destructive operation.</summary>
bool resize(DWORD size);

///<summary>Shrink the buffer without destroying its contents.</summary>
bool shrink(DWORD size);

/// <summary>Return the number of points in the buffer.</summary>
DWORD size() const;

/// <summary>Return a array of single precision points.
/// This may return NULL if the buffer is not single precision.</summary>
AcPcPointFloat* floatPoints ();

/// <summary>Return a array of double precision points.
/// This may return NULL if the buffer is not double precision.</summary>
AcPcPointDouble* doublePoints();

AcPcPointAttributes* pointAttributes();

/// <summary>Return a point in single precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool floatPoint(DWORD ptIx, AcPcPointFloat& pt) const;

/// <summary>Return a point in double precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool doublePoint (DWORD ptIx, AcPcPointDouble& pt) const;

/// <summary>Set a point in single precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool setFloatPoint(DWORD ptIx, AcPcPointFloat& pt);

/// <summary>Set a point in double precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool setDoublePoint (DWORD ptIx, AcPcPointDouble& pt);

/// <summary>Get the translation offset of the points.
/// This offset needs to be added to each point in order to get the
/// original location of the point in the point cloud</summary>
bool offset(double& x, double& y, double& z) const;
/// <summary>This transform needs to be applied to the points to
/// get the points in world space.</summary>
bool entityTransform(AcGeMatrix3d& matrix) const;

/// <summary>Copy the contents of the given buffer.</summary>
void copyFrom(IAcPcDataBuffer const & from);

public:
std::vector<AcPcPointDouble> AcPcPointDoubleArray;
std::vector<AcPcPointFloat> AcPcPointFloatArray;
std::vector<AcPcPointAttributes> AcPcPointAttributesArray;
};

 

#include "stdafx.h"
#include "AcPcDataBuffer.h"


PcDataBuffer::PcDataBuffer(void)
{

}

PcDataBuffer::~PcDataBuffer(void)
{
if (AcPcPointDoubleArray.size()>0)
{
AcPcPointDoubleArray.clear();
}

if (AcPcPointFloatArray.size()>0)
{
AcPcPointFloatArray.clear();
}

if (AcPcPointAttributesArray.size())
{
AcPcPointAttributesArray.clear();
}

}
///<summary>Indicate if the points are in single or double precision.</summary>
bool PcDataBuffer::nativeDbl()
{
return true;
}

///<summary>Resize the buffer. This may be a destructive operation.</summary>
bool PcDataBuffer::resize(DWORD size)
{
try
{
this->AcPcPointDoubleArray.resize(size);
}
catch (...)
{
return false;
}

return true;
};

///<summary>Shrink the buffer without destroying its contents.</summary>
bool PcDataBuffer::shrink(DWORD size)
{
try
{
// just discard excess capacity
this->AcPcPointDoubleArray.shrink_to_fit();
}
catch (...)
{
return false;
}

return true;
}

/// <summary>Return the number of points in the buffer.</summary>
DWORD PcDataBuffer::size() const
{
return (DWORD)this->AcPcPointDoubleArray.size();
}

/// <summary>Return a array of single precision points.
/// This may return NULL if the buffer is not single precision.</summary>
AcPcPointFloat* PcDataBuffer::floatPoints ()
{
return &this->AcPcPointFloatArray[0];
}

/// <summary>Return a array of double precision points.
/// This may return NULL if the buffer is not double precision.</summary>
AcPcPointDouble* PcDataBuffer::doublePoints()
{
return &this->AcPcPointDoubleArray[0];
}

AcPcPointAttributes* PcDataBuffer::pointAttributes()
{
return &this->AcPcPointAttributesArray[0];
}
/// <summary>Return a point in single precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool PcDataBuffer::floatPoint(DWORD ptIx, AcPcPointFloat& pt) const
{
if (ptIx < this->AcPcPointDoubleArray.size())
{
pt = (AcPcPointFloat&)this->AcPcPointDoubleArray[ptIx];
return true;
}

return false;
}

/// <summary>Return a point in double precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool PcDataBuffer::doublePoint (DWORD ptIx, AcPcPointDouble& pt) const
{
if (ptIx < this->AcPcPointDoubleArray.size())
{
pt = this->AcPcPointDoubleArray[ptIx];
return true;
}

return false;
}

/// <summary>Set a point in single precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool PcDataBuffer::setFloatPoint(DWORD ptIx, AcPcPointFloat& pt)
{
if (ptIx < this->AcPcPointDoubleArray.size())
{
this->AcPcPointDoubleArray[ptIx] = (AcPcPointDouble&)pt;
return true;
}

return false;
}

/// <summary>Set a point in double precision.
/// This will work regardless of the native precision of the buffer.</summary>
bool PcDataBuffer::setDoublePoint (DWORD ptIx, AcPcPointDouble& pt)
{
if (ptIx < this->AcPcPointDoubleArray.size())
{
this->AcPcPointDoubleArray[ptIx] = pt;
return true;
}

return true;
}

/// <summary>Get the translation offset of the points.
/// This offset needs to be added to each point in order to get the
/// original location of the point in the point cloud</summary>
bool PcDataBuffer::offset(double& x, double& y, double& z) const
{
return true;
}
/// <summary>This transform needs to be applied to the points to
/// get the points in world space.</summary>
bool PcDataBuffer::entityTransform(AcGeMatrix3d& matrix) const
{
return true;
}

/// <summary>Copy the contents of the given buffer.</summary>
void PcDataBuffer::copyFrom(IAcPcDataBuffer const & from)
{
this->AcPcPointDoubleArray.clear();
AcPcPointDouble temp;

for (DWORD i = 0 ; i < from.size(); i++)
{
from.doublePoint(i,temp);
this->AcPcPointDoubleArray.push_back( temp );
}
}

Message 3 of 8
100053011
in reply to: 100053011

#include "AcPointCloud.h"

class ACDB_PORT AcPcPointFilter:public IAcPcPointFilter
{
public:

AcPcPointFilter(void);

~AcPcPointFilter(void);

void doFilter(const IAcPcDataBuffer& inBuffer, IAcPcDataBuffer& outBuffer);


};

 

#include "stdafx.h"
#include "AcPcPointFilter.h"


AcPcPointFilter::AcPcPointFilter(void)
{

}


AcPcPointFilter::~AcPcPointFilter(void)
{

}
void AcPcPointFilter::doFilter(const IAcPcDataBuffer& inBuffer, IAcPcDataBuffer& outBuffer)
{


}

Message 4 of 8
100053011
in reply to: 100053011


#include "AcPointCloud.h"
#include "AcPcDataBuffer.h"

class ACDB_PORT AcPcPointProcessor:public IAcPcPointProcessor
{
public:
AcPcPointProcessor();

~AcPcPointProcessor();

/// <summary>Return true to cancel processing.</summary>
bool cancel();

bool setCancel(bool b) ;

/// <summary>Called to abort the process</summary>
void abort();

/// <summary>Called after the last call to ProcessPoints</summary>
void finished();

/// <summary>Process point in buffer. This will be called repeatedly with
/// new buffer contents until all points have been processed.</summary>
bool processPoints();

/// <summary>Filter, if available, to filter points.
/// Called before processPoints() on the next batch of points.</summary>
IAcPcPointFilter* filter();

/// <summary> Set Filter, to filter points.
void setFilter(IAcPcPointFilter* newfilter);

 

private:
bool bCancel;
IAcPcPointFilter* ptFilter;
};

 

#include "stdafx.h"
#include "AcPcPointProcessor.h"

AcPcPointProcessor::AcPcPointProcessor(void)
{
PcDataBuffer *buf =new PcDataBuffer();
this->setBuffer(buf);
this->bCancel = false;
this->ptFilter = NULL;
};

AcPcPointProcessor::~AcPcPointProcessor()
{
if (this->buffer())
delete this->buffer();
}

/// <summary>Return true to cancel processing.</summary>
bool AcPcPointProcessor::cancel()
{
return false;
}

bool AcPcPointProcessor::setCancel(bool b)
{
this->bCancel = b;
return b;
}

/// <summary>Called to abort the process</summary>
void AcPcPointProcessor::abort()
{

}

/// <summary>Called after the last call to ProcessPoints</summary>
void AcPcPointProcessor::finished()
{
DWORD size = this->buffer()->size();
}

/// <summary>Process point in buffer. This will be called repeatedly with
/// new buffer contents until all points have been processed.</summary>
bool AcPcPointProcessor::processPoints()
{

DWORD size = this->buffer()->size();
return true;
}

/// <summary>Filter, if available, to filter points.
/// Called before processPoints() on the next batch of points.</summary>
IAcPcPointFilter* AcPcPointProcessor::filter()
{
if (ptFilter)
return this->ptFilter;
else
return NULL;
}

/// <summary> Set Filter, to filter points.
void AcPcPointProcessor::setFilter(IAcPcPointFilter* newfilter)
{
this->ptFilter = newfilter;
}

Message 5 of 8
100053011
in reply to: 100053011

the above is what I came up with and how I implmented the classes derived from the abstract implementations.

 Here is my main function calls:

void CPointCloudExtract::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
//DoSomethingWithEnt callBack

#pragma region
/*AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);

AcDbBlockTableIterator* pBlockIt;

Acad::ErrorStatus es = pBlockTable->newIterator(pBlockIt);

if(Acad::eOk != es)
{
pBlockTable->close();
return;
}
AcDbBlockTableRecord *pBlockTableRecord;

for(pBlockIt->start();!pBlockIt->done();pBlockIt->step())
{
es = pBlockIt->getRecord(pBlockTableRecord, AcDb::kForRead);
if(Acad::eOk == es)
{
AcDbBlockTableRecordIterator* pEntIt;
es = pBlockTableRecord->newIterator(pEntIt);

if(Acad::eOk == es)
{
for (pEntIt->start();!pEntIt->done();pEntIt->step())
{
AcDbEntity* pEnt;
es = pEntIt->getEntity(pEnt, AcDb::kForWrite);

AcDbObjectId objectid=pEnt->blockId();

AcRxClass* pRxPointCloud = (AcRxClass*)acrxClassDictionary->at(ACRX_T("AcDbPointCloud"));

if(pEnt->isKindOf(pRxPointCloud))
{
int i=0;
AcDbExtents boundBox;
pEnt->getGeomExtents(boundBox);
}

if (Acad::eOk == es)
{
pEnt->close();
}
}
delete pEntIt;
}
pBlockTableRecord->close();
}
}
delete pBlockIt;
pBlockTable->close();*/

#pragma endregion
AcGePoint3d ptmin(0,0,0);
AcGePoint3d ptmax(1000000000,1000000000,2000000);
const AcDbExtents boundingBox( ptmin, ptmax);

static const AcString className(L"AcDbPointCloud");

AcDbBlockTableRecordPointer pBlockRec(ACDB_MODEL_SPACE,acdbHostApplicationServices()->workingDatabase(),AcDb::kForRead);
if (Acad::eOk == pBlockRec.openStatus())
{
AcDbBlockTableRecordIterator* it = NULL;
if (Acad::eOk == pBlockRec->newIterator(it))
{
it->start();
while(!it->done())
{
AcDbObjectId entId;
it->getEntityId(entId);
// open for read should be sufficient in case you like to process point clouds
AcDbEntityPointer pEnt(entId,AcDb::kForRead);
if (Acad::eOk == pEnt.openStatus())
{
if(AcString(pEnt->isA()->name())==className)
{
// here you go with your point cloud entity
int k=0;
// init AcPcPointProcessor
AcPcPointProcessor* ptProc = new AcPcPointProcessor();
//IAcPcPointProcessor* iptProc=0;
Acad::ErrorStatus err = acdbProcessPointCloudData(pEnt, boundingBox, 100, ptProc);

AcPcPointFloat* pt = ptProc->buffer()->floatPoints();
//DWORD size = buf->size();
//ptProc->finished();
//bool ttd=ptProc->processPoints();
//Acad::ErrorStatus err = acdbProcessPointCloudData(pEnt, boundingBox,100,ptProc);
//DWORD size=iptProc->buffer()->size();
//IAcPcDataBuffer* buf = ptProc->buffer();
//DWORD size = buf->size();

}
}
it->step();
}
}
delete it;
}


}

 

Message 6 of 8
100053011
in reply to: 100053011

What am I doing wrong? Hope to be able to help me, thank

Message 7 of 8
owenwengerd
in reply to: 100053011

Please post inline code using the code formatting tags, and only the bare minumum required to describe your problem. What exactly is the problem? State it clearly and specifically, including complete error messages or error status results.

--
Owen Wengerd
ManuSoft
Message 8 of 8
100053011
in reply to: owenwengerd

 Owen Wengerd,

      thank you,I have solved the problem.

    I have a new problem。

AcPcPointProcessor* ptProc = new AcPcPointProcessor();
						
Acad::ErrorStatus err = acdbProcessPointCloudData(pEnt, boundingBox, 100, ptProc);
			    
for (int i=0;i<ptProc->m_pcDataBuffer.size();i++)
{	  
pcDataBuffer.push_back(ptProc->m_pcDataBuffer[i]);
}  

Here, I was able to get all of the point cloud data from pcg file。All the data points inside m_pcDataBuffer, including x, y, z。

Now, how do I change the color of each point and displays a different color for each point in autoccad?

what can 1 do?

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost