I quickly hacked something in order to test the concept and see if it works.
Here is what I came up with and how I implmented the classes derived from the abstract implementations.
class ACDB_PORT AcPcPointFilter : public IAcPcPointFilter
{
public:
AcPcPointFilter(){}
void doFilter(const IAcPcDataBuffer& inBuffer, IAcPcDataBuffer& outBuffer){ }
};
class ACDB_PORT AcPcDataBuffer : public IAcPcDataBuffer
{
public:
AcPcDataBuffer(){ }
///<summary>Indicate if the points are in single or double precision.</summary>
bool nativeDbl(){return true;}
///<summary>Resize the buffer. This may be a destructive operation.</summary>
bool resize(DWORD size)
{
try
{
this->AcPcPointDoubleArray.resize(size);
}
catch (...)
{
return false;
}
return true;
};
///<summary>Shrink the buffer without destroying its contents.</summary>
bool 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 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* floatPoints (){return NULL;}
/// <summary>Return a array of double precision points.
/// This may return NULL if the buffer is not double precision.</summary>
AcPcPointDouble* doublePoints()
{
return &this->AcPcPointDoubleArray[0];
}
/// <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
{
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 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 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 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 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 entityTransform(AcGeMatrix3d& matrix) const
{
return true;
}
/// <summary>Copy the contents of the given buffer.</summary>
void 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 );
}
}
public:
std::vector<AcPcPointDouble> AcPcPointDoubleArray;
};
class ACDB_PORT AcPcPointProcessor : public IAcPcPointProcessor
{
public:
AcPcPointProcessor()
{
AcPcDataBuffer *buf = new AcPcDataBuffer();
this->setBuffer(buf);
this->bCancel = false;
this->ptFilter = NULL;
};
~AcPcPointProcessor()
{
if (this->buffer())
delete this->buffer();
}
/// <summary>Return true to cancel processing.</summary>
bool cancel(){return false;}
bool setCancel(bool b) {this->bCancel = 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(){return true;}
/// <summary>Filter, if available, to filter points.
/// Called before processPoints() on the next batch of points.</summary>
IAcPcPointFilter* filter()
{
if (ptFilter)
return this->ptFilter;
else
return NULL;
}
/// <summary> Set Filter, to filter points.
void setFilter(IAcPcPointFilter* newfilter){this->ptFilter = newfilter;}
private:
bool bCancel;
IAcPcPointFilter* ptFilter;
};
And here is how I call the acdbProcessPointCloudData function
// set bounding box - just testing so nothing useful
AcGePoint3d ptmin(0,0,0);
AcGePoint3d ptmax(1000000000,1000000000,2000000);
const AcDbExtents boundingBox( ptmin, ptmax);
// init AcPcPointProcessor
AcPcPointProcessor* ptProc = new AcPcPointProcessor();
Acad::ErrorStatus err = acdbProcessPointCloudData(pEntity, boundingBox, 100, ptProc);
While the function returns eOK and the size of the buffer seems fine the actual data in the vector is garbage.
Do you see anything suspicious ?
Any idea is appreciated !