|
[code]#pragma once
#include <set>
#include <vector>
#include <algorithm>
class CDPoint
{
public:
double x,y,z,w;
__forceinline CDPoint(void) : x(0.0),y(0.0),z(0.0),w(0.0){}
__forceinline CDPoint(double X,double Y, double Z,double dist)
: x(X),y(Y),z(Z),w(dist){}
__forceinline CDPoint(const AcGePoint3d &p,double dist)
: x(p.x),y(p.y),z(p.z),w(dist){}
static bool byZ (const CDPoint &pt1, const CDPoint &pt2) {
return (pt1.z > pt2.z);
}
double distanceTo(const CDPoint &pt) const
{
double dx = x - pt.x;
double dy = y - pt.y;
double dz = z - pt.z;
return sqrt(dx*dx + dy*dy + dz*dz);
}
double distanceTo(const AcGePoint3d &pt) const
{
double dx = x - pt.x;
double dy = y - pt.y;
double dz = z - pt.z;
return sqrt(dx*dx + dy*dy + dz*dz);
}
AcGePoint3d toPoint3d() const
{
return AcGePoint3d(x,y,z);
}
bool operator == (const CDPoint &pt) const{
return (w == pt.w);
}
bool operator < (const CDPoint &pt) const{
if(w == pt.w){ return ( z < pt.z); }
return ( w > pt.w);
}
};
typedef std::set<CDPoint> sDPoints;
typedef std::vector<CDPoint> vDPoints;
typedef std::vector<AcGeLine3d> vLines;
inline static void addPoint(sDPoints &points, const CDPoint &p)
{
points.insert(p);
}
static void sortPoints(vDPoints &sPoints)
{
sort( sPoints.begin(), sPoints.end());
}
static void setPointDist(const AcGePoint3d &basePt, vDPoints &sPoints)
{
for(int i = 0; i < sPoints.size();i++)
{
sPoints[i].w = sPoints[i].distanceTo(basePt);
}
}
static int fillPoints(vDPoints &sPoints)
{
int cnt = 0;
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTableRecord *pRec;
if(acdbOpenAcDbObject((AcDbObject *&) pRec,
pDb->currentSpaceId(), AcDb::kForRead) == Acad::eOk)
{
AcDbBlockTableRecordIterator *pIter;
if(pRec->newIterator(pIter) == Acad::eOk) {
for(pIter->start(); !pIter->done(); pIter->step()) {
AcDbObjectId objId;
AcDbEntity *pEnt;
if(pIter->getEntity(pEnt, AcDb::kForRead) == Acad::eOk){
AcDbPoint *pPoint = AcDbPoint::cast(pEnt);
if(pPoint) {
CDPoint p(pPoint->position(),0);
sPoints.push_back(p);
cnt++;
}
pEnt->close();
}
}
delete pIter;
}
pRec->close();
}
return cnt;
}
static void ArxShortestPl_doit(void)
{
AcDbObjectId plid;
vDPoints sPoints;
vDPoints::const_iterator sIter;
vLines lineVec;
int cnt = fillPoints(sPoints);
sortPoints(sPoints);
if (cnt < 2)
return;
AcDbPolyline *pl = new AcDbPolyline(cnt);
AcGePoint3d basePt(0.0,0.0,0.0);
AcGePoint3d lastpt = basePt;
for(int i = 0 ; i < cnt ; i++)
{
unsigned int last = sPoints.size() -1;
setPointDist(basePt,sPoints);
sortPoints(sPoints);
lastpt = sPoints[last].toPoint3d();
pl->addVertexAt(pl->numVerts(),AcGePoint2d(lastpt.x,lastpt.y));
basePt = lastpt;
sPoints.pop_back();
}
pl->setClosed(Adesk::kTrue);
double dist,endparam;
pl->getEndParam(endparam);
pl->getDistAtParam(endparam,dist);
acutPrintf(_T("Length = %g"), dist);
AddEntityToDataBase(pl,plid);
}
static void
AddEntityToDataBase(AcDbEntity *pEnt, AcDbObjectId &pOutputId,
Adesk::UInt16 color = 7)
{
pOutputId = AcDbObjectId::kNull;
AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTableRecordPointer pBTR(pDb->currentSpaceId(), AcDb::kForWrite);
if (pEnt && Acad::eOk == pBTR.openStatus())
{
pEnt->setDatabaseDefaults();
pEnt->setColorIndex(color);
pBTR->appendAcDbEntity(pOutputId, pEnt);
pEnt->close();
}
}[/code] |
|