Files
envi-code/SourceCode/Code2026/CoreLibrary/geometry2json.cpp
T
2026-09-28 15:28:50 +08:00

2546 lines
60 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "StdAfx.h"
#include "geometry2json.h"
#include "CoreTools.h"
#include "shjson.h"
#include "KTCADUtilityEx.h"
#include "Base64.h"
#include "AecDb3dRoadAxisLine.h"
#include "dbobjptr.h"
#include "compare_double.h"
#define CLASS_CONVER(type, dist, src) type *dist = type::cast((src))
namespace
{
bool checkTriangle(const AcGePoint3d &pt0
, const AcGePoint3d &pt1
, const AcGePoint3d &pt2
, const double &tol = 2 )
{
if (pt0.distanceTo(pt1) <= tol && pt0.distanceTo(pt2) <= tol) return false;
if (pt1.distanceTo(pt0) <= tol && pt1.distanceTo(pt2) <= tol) return false;
if (pt2.distanceTo(pt0) <= tol && pt2.distanceTo(pt1) <= tol) return false;
return true;
}
DWORD getEntityColor(AcCmEntityColor clr)
{
if (clr.isByACI())
{
return acedGetRGB(clr.colorIndex());
}
else if (clr.isByColor())
{
return RGB(clr.red(), clr.green(), clr.blue());
}
return 0;
}
DWORD getEntityColor(AcDbEntity *pEnt)
{
AcCmEntityColor clr = pEnt->entityColor();
if (clr.isByACI() || clr.isByColor())
{
return getEntityColor(clr);
}
else if (clr.isByBlock())
{
}
else if (clr.isByLayer())
{
AcDbObjectId id = pEnt->layerId();
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbLayerTableRecord, pLayer)
if (pLayer)
return getEntityColor(pLayer->entityColor());
OPENOBJ_END()
}
return 0;
}
}
#define _CRV_SET_(TT, crvPtr)\
if (!crvPtr) return;\
TT *p = TT::cast(crvPtr);\
if (p)\
set(*p)
namespace GEO2JSON
{
#pragma region _geo
_geo::_geo(const _geo &g) {}
_geo::_geo() {}
std::wstring _geo::toString()
{
return write2Json(ToJson());
}
bool _geo::byString(const std::wstring &json)
{
WDocument doc;
doc.Parse(json);
if (doc.HasParseError()) return false;
return ByJson(doc);
}
void _geo::addType(WValue &v)
{
addMember(v, _T("_type_"), (int)type());
}
_geo::TYPE _geo::getType(const WValue &v)
{
if (v.HasMember(_T("_type_")))
{
return (TYPE)v[_T("_type_")].GetInt();
}
return eNone;
}
_geo *_geo::createGeo(const WValue &v)
{
switch (getType(v))
{
case ePoint: return newGeo<point>(v);
case ePlane: return newGeo<plane>(v);
case eLine: return newGeo<line>(v);
case eArc: return newGeo<arc>(v);
case eCircle: return newGeo<circle>(v);
case eEllipse: return newGeo<ellipse>(v);
case eExtruded: return newGeo<extruded>(v);
case eRevolved: return newGeo<revolved>(v);
case eLoft: return newGeo<loft>(v);
case eNone: break;
default: break;
}
return NULL;
}
void _geo::set(const std::wstring &s) { byString(s); }
void _geo::set(const WValue &v) { ByJson(v); }
void tools::asCurves(const std::vector<_geo *> &geos, AcDbVoidPtrArray &ar)
{
for (size_t i = 0; i < geos.size(); ++i)
{
_geo *p(geos[i]);
AcDbCurve *pCurve(p->asDbCurve());
if (pCurve)
ar.append(pCurve);
}
}
void collectRegions(AcDbRegion *pReg, std::vector<AcDbRegion *> &regs)
{
if (!pReg) return;
AcDbVoidPtrArray ar;
pReg->explode(ar);
// 只有Region和Region之间才可以进行BOOL操作
// 所以只要炸出一个region,则其它的也都是region
// 只要有一个不是,其它的也不会是
for (int i = 0; i < ar.length(); ++i)
{
CLASS_CONVER(AcDbRegion, pR, (AcDbEntity *)ar[i]);
CLASS_CONVER(AcDbCurve, pC, (AcDbEntity *)ar[i]);
if (pR)
{
collectRegions(pR, regs);
}
else
{
regs.push_back((AcDbRegion *)pReg->clone());
break;
}
}
deleteArrayVoidPtrs< AcDbEntity>(ar);
}
template <class T1, class T2>
void convertEntityByPlane(T1 *pCurve, path *pt, const AcGePlane &Plane)
{
AcGeMatrix3d matUCS, mat;
matUCS.setToPlaneToWorld(Plane);
AcGePoint3d ptUCS;
AcGeVector3d vtX, vtY, vtZ;
matUCS.getCoordSystem(ptUCS, vtX, vtY, vtZ);
mat = mat.setToAlignCoordSys(
ptUCS
, vtX
, vtY
, vtZ
, AcGePoint3d::kOrigin
, AcGeVector3d::kXAxis
, AcGeVector3d::kYAxis
, AcGeVector3d::kZAxis
);
T1 *pNew = (T1 *)pCurve->clone();
pNew->transformBy(mat);
pt->_profile.push_back(new T2(*pNew));
DELETE_PTR(pNew);
}
bool curve2Profile(AcDbCurve *pCurve, path *pt, AcGePlane *pPlane = NULL)
{
CLASS_CONVER(AcDbSpline, pSp, pCurve);
if (pSp)
{
pt->_profile.push_back(new spline(*pSp));
}
CLASS_CONVER(AcDbCircle, pCir, pCurve);
if (pCir)
{
if (!pPlane)
pt->_profile.push_back(new circle(*pCir));
else
convertEntityByPlane<AcDbCircle, circle>(pCir, pt, *pPlane);
return true;
}
CLASS_CONVER(AcDbEllipse, pEll, pCurve);
if (pEll)
{
if (!pPlane)
pt->_profile.push_back(new ellipse(*pEll));
else
convertEntityByPlane<AcDbEllipse, ellipse>(pEll, pt, *pPlane);
return true;
}
CLASS_CONVER(AcDbLine, pLine, pCurve);
if (pLine)
{
if (!pPlane)
pt->_profile.push_back(new line(*pLine));
else
convertEntityByPlane<AcDbLine, line>(pLine, pt, *pPlane);
return true;
}
CLASS_CONVER(AcDbArc, pArc, pCurve);
if (pArc)
{
if (!pPlane)
pt->_profile.push_back(new arc(*pArc));
else
convertEntityByPlane<AcDbArc, arc>(pArc, pt, *pPlane);
return true;
}
CLASS_CONVER(AcDb3dPolyline, p3d, pCurve);
if (p3d)
{
AcDb3dPolyline *p = (AcDb3dPolyline *)p3d->clone();
AcDbVoidPtrArray ar;
p->explode(ar);
for (int i = 0; i < ar.length(); ++i)
{
CLASS_CONVER(AcDbCurve, pC, (AcDbEntity *)ar[i]);
if (pC)
curve2Profile(pC, pt);
}
deleteArrayVoidPtrs< AcDbEntity>(ar);
return !pt->isEmpty();
}
CLASS_CONVER(AecDb3dRoadAxisLine, pRoad, pCurve);
if (pRoad)
{
int count = pRoad->GetCurveSegCount();
for (int i(0); i < count; ++i)
{
AcDbCurve *pC = pRoad->GetCurveSeg(i);
if (pC)
curve2Profile(pC, pt);
}
return !pt->isEmpty();
}
CLASS_CONVER(AcDbPolyline, pPoly, pCurve);
if (pPoly)
{
AcDbPolyline *p = (AcDbPolyline *)pPoly->clone();
AcDbVoidPtrArray ar;
// 如果 pPlane 不为空,则说明需要进行坐标转换
// 但是,polyline不用pPlane进行转换,而是使用自己的坐标系
if (pPlane)
{
AcGePlane PolyPlane;
AcDb::Planarity pty;
p->getPlane(PolyPlane, pty);
AcGeVector3d vt = p->normal();
double elev = p->elevation();
AcGePoint3d ptO;
AcGeVector3d vtx, vty, vtz;
PolyPlane.getCoordSystem(ptO, vtx, vty);
vtz = PolyPlane.normal();
// 按法向走 elev
AcDbPolyline *pp = (AcDbPolyline *)p->clone();
AcGeMatrix3d mat;
mat = mat.setToAlignCoordSys(
ptO, vtx, vty, vtz
, AcGePoint3d::kOrigin, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis
);
pp->transformBy(mat);
//mat.setToTranslation(pp->normal() * -elev);
//pp->transformBy(mat);
DELETE_PTR(p);
p = pp;
}
if (p->explode(ar) == Acad::eOk)
{
for (int i = 0; i < ar.length(); ++i)
{
CLASS_CONVER(AcDbCurve, pC, (AcDbEntity *)ar[i]);
if (pC)
curve2Profile(pC, pt);
}
deleteArrayVoidPtrs< AcDbEntity>(ar);
}
DELETE_PTR(p);
return !pt->isEmpty();
}
return false;
}
void tools::fromEntity(region::profiles &pfs, AcGePlane &plan, const AcDbEntity &ent, const bool &b2D)
{
// 先清空内存,防止泄漏
deleteContainerOfStd(pfs);
// 判断 ent 是否是 AcDbRegion 或 AcDbCurve,其它不处理
AcDbRegion *pReg = AcDbRegion::cast(&ent);
AcDbCurve *pCurve = AcDbCurve::cast(&ent);
if (!pReg && !pCurve) return;
// 先求出平面
plan = getPlane(ent);
std::vector<AcDbRegion *> regs;
if (pReg)
{
bool bHasEllipse(false);
AcGePlane regPlane;
pReg->getPlane(regPlane);
collectRegions(pReg, regs);
// 收集后的 regs 内不会再炸出 AcDbRegion 对象,只有AcDbCurve对象
// 那么,能构成Region的对象,只有 AcDbCircle和AcDbEllipse或AcDbPolyline三种
// AcDbCircle和AcDbEllipse生成的Region只能炸出一个实体
// AcDbPolyline生成的Region会炸出 AcdbLine和AcDbArc两种实体
for (size_t i = 0; i < regs.size(); ++i)
{
AcDbVoidPtrArray ar, others;
regs[i]->explode(ar);
// 如果只炸出一个,只可能是 circle ellipse
// 不可能是其它
for (int i = 0; i < ar.length(); ++i)
{
AcDbEntity *pEnt = (AcDbEntity *)ar[i];
CLASS_CONVER(AcDbCircle, pCir, pEnt);
CLASS_CONVER(AcDbEllipse, pEll, pEnt);
if (pCir)
{ // 圆形只能自己构成region,处理完离开
path *pt = new path();
pt->_profile.push_back( new circle(pCir->center()
, pCir->normal()
, pCir->radius()));
pfs.push_back(pt);
break;
}
if (pEll)
{
// 判读是 椭圆弧还是完整椭圆
AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin);
pEll->getStartPoint(ptS);
pEll->getEndPoint(ptE);
if (COMPARE_DOUBLE::equal_zero(ptS.distanceTo(ptE), .0001))
{ // 完只能自己构成region,处理完离开
ellipse *pE = new ellipse(pEll->center()
, pEll->majorAxis()
, pEll->minorAxis()
, pEll->majorAxis().length()
, pEll->minorAxis().length()
, 0
, 2 * PI );
path *pt = new path();
pt->_profile.push_back(pE);
pfs.push_back(pt);
break;
}
else
{
// 不完整,会有其他curve和它构成region,等待
others.append(pEll);
bHasEllipse = true;
continue;
}
}
// 现在只剩 AcDbLine 和 AcDbArc
CLASS_CONVER(AcDbLine, pL, pEnt);
CLASS_CONVER(AcDbArc, pA, pEnt);
if (pL || pA)
others.append(pEnt);
}
// 现在处理 others,others可以组一个或多个 pf
std::vector<AcDbPolyline *> polys;
if (!bHasEllipse)
{ // 没有ellipse,可以合成polyline
CoreTools::MakePolyline(others, polys);
for (size_t i = 0; i < polys.size(); ++i)
{
AcDbPolyline *p(polys[i]);
tools::MeragePolyline(p, 2);
path *pt = new path();
if (curve2Profile(p, pt, b2D ? &regPlane : NULL))
pfs.push_back(pt);
else
DELETE_PTR(pt);
}
deleteArrayVoidPtrs< AcDbEntity>(ar);
deleteContainerOfStd(polys);
}
else
{ // 有椭圆,不能合成polyline
path *pt = new path();
for (int i(0); i < others.length(); ++i)
{
curve2Profile((AcDbCurve *)others[i], pt, b2D ? &regPlane : NULL);
}
if (!pt->_profile.empty())
pfs.push_back(pt);
else
DELETE_PTR(pt);
}
}
deleteContainerOfStd(regs);
return;
}
if (pCurve)
{
path *pt = new path();
if (curve2Profile(pCurve, pt))
pfs.push_back(pt);
else
DELETE_PTR(pt);
return;
}
}
AcDbCurve *tools::asDbPolyline(const std::vector<_geo *> &geos)
{
AcDbVoidPtrArray ar(0);
asCurves(geos, ar);
if (ar.isEmpty()) return NULL;
// 如果 ar 内有 acdbcircle 或 acdbellipse 直接返回,如果有其它的对象直接删除
for (int i = 0; i < ar.length(); ++i)
{
AcDbEntity *p((AcDbEntity *)ar[i]);
AcDbCircle *pCir(AcDbCircle::cast(p));
AcDbEllipse *pEll(AcDbEllipse::cast(p));
if (pCir)
{
pCir = (AcDbCircle *)pCir->clone();
deleteArrayVoidPtrs< AcDbEntity>(ar);
return pCir;
}
if (pEll)
{
pEll = (AcDbEllipse *)pEll->clone();
deleteArrayVoidPtrs< AcDbEntity>(ar);
return pEll;
}
}
AcDbPolyline *pPoly(NULL);
std::vector<AcDbPolyline *> polys;
if (CoreTools::MakePolyline(ar, polys))
pPoly = (AcDbPolyline *)polys[0]->clone();
deleteContainerOfStd(polys);
deleteArrayVoidPtrs< AcDbEntity>(ar);
return pPoly;
}
AcDbRegion *tools::asDbRegion(const std::vector<_geo *> &geos)
{
AcDbVoidPtrArray ar(0);
asCurves(geos, ar);
if (ar.isEmpty()) return NULL;
AcDbRegion *pReg = CoreTools::createRegion(ar);
deleteArrayVoidPtrs< AcDbEntity>(ar);
return pReg;
}
AcGePlane tools::getPlane(const AcDbEntity &ent)
{
AcGePlane pln = AcGePlane::kXYPlane;
AcDb::Planarity pty = AcDb::kNonPlanar;
if (ent.getPlane(pln, pty) == Acad::eOk)
return pln;
CLASS_CONVER(AcDbCurve, pCurve, &ent);
CLASS_CONVER(AcDbRegion, pReg, &ent);
if (pCurve)
{
CLASS_CONVER(AcDbLine, pLine, &ent);
CLASS_CONVER(AcDbArc, pArc, &ent);
CLASS_CONVER(AcDbCircle, pCir, &ent);
CLASS_CONVER(AcDbEllipse, pEll, &ent);
CLASS_CONVER(AcDbPolyline, pPoly, &ent);
if (pLine)
return pln;
else if (pCir)
return AcGePlane(pCir->center(), pCir->normal());
else if (pArc)
return AcGePlane(pArc->center(), pArc->normal());
else if (pEll)
return AcGePlane(pEll->center(), pEll->normal());
else if (pPoly)
{
AcDbExtents ext;
pPoly->getGeomExtents(ext);
AcGePoint3d ptM = CoreTools::MidPt(ext.maxPoint(), ext.minPoint());
return AcGePlane(ptM, pPoly->normal());
}
}
else if (pReg)
{
AcDbExtents ext;
pReg->getGeomExtents(ext);
AcGePoint3d ptM = CoreTools::MidPt(ext.maxPoint(), ext.minPoint());
AcGeVector3d vt(AcGeVector3d::kIdentity);
pReg->getNormal(vt);
return AcGePlane(ptM, vt);
}
return pln;
}
void tools::MeragePolyline(AcDbPolyline *pPoly, const double &tol)
{
AcGeLineSeg3d segLine;
AcGeCircArc3d segArc;
double dBulge(.0), dSegLen(.0);
AcGePoint2d pt;
int nNumOfSeg(pPoly->numVerts() - 1);
if (nNumOfSeg <= 1) return;
for (int i(0); i < nNumOfSeg; ++i)
{
AcDbPolyline::SegType st = pPoly->segType(i);
if (st == AcDbPolyline::kLine)
{
pPoly->getLineSegAt(i, segLine);
dSegLen = segLine.length();
}
else if (st == AcDbPolyline::kArc)
{
pPoly->getArcSegAt(i, segArc);
dSegLen = segArc.length(segArc.paramOf(segArc.startPoint())
, segArc.paramOf(segArc.endPoint()));
}
else
continue;
if (dSegLen > tol || COMPARE_DOUBLE::equal_zero(dSegLen, 1e-6)) continue;
if (i == nNumOfSeg - 1) // 最后一段
{ // 删除最后一个节点,延长倒数第二个点
pPoly->getPointAt(i + 1, pt);
pPoly->setPointAt(i, pt);
pPoly->removeVertexAt(i + 1);
i = -1;
nNumOfSeg = pPoly->numVerts() - 1;
}
else
{ // 删除第一个点,第二个点延长
pPoly->getPointAt(i, pt);
pPoly->setPointAt(i + 1, pt);
pPoly->removeVertexAt(i);
i = -1;
nNumOfSeg = pPoly->numVerts() - 1;
}
continue;
}
}
int tools::makeVertexLoop(const AcGePoint3dArray &pts, AcGePoint3dArray &loop, const double &tol)
{
if (pts.length() < 3) return 0;
loop.append(pts.first());
for (int i(1); i < pts.length(); ++i)
{
if (loop.last().distanceTo(pts[i]) <= tol)
continue;
else
loop.append(pts[i]);
}
if (loop.length() < 3) return 0;
// 最后,比一下第一点和最后一点
if (loop.last().distanceTo(loop.first()) <= tol)
loop.removeLast();
if (loop.length() < 3) return 0;
return loop.length();
}
bool tools::fromFace(tessellations &ss, AcDbFace *pFace)
{
if (!pFace) return false;
int r(-1), g(-1), b(-1);
DWORD clr = getEntityColor(pFace);
AcGePoint3d pt0, pt1, pt2, pt3;
pFace->getVertexAt(0, pt0);
pFace->getVertexAt(1, pt1);
pFace->getVertexAt(2, pt2);
pFace->getVertexAt(3, pt3);
AcGePoint3dArray pts, _pts;
pts.append(pt0);
pts.append(pt1);
pts.append(pt2);
pts.append(pt3);
if (makeVertexLoop(pts, _pts))
ss.push_back(tessellation(_pts, clr));
else
return false;
return true;
}
int tools::solid2Face(AcDb3dSolid *pSolid, tessellations &ss)
{
if (!pSolid) return 0;
AcDbExtents ext;
pSolid->getGeomExtents(ext);
AcGeVector3d vt = ext.maxPoint() - ext.minPoint();
AcDbFaceterSettings faceter = {};
faceter.faceterMeshType = 2;
faceter.faceterMaxEdgeLength = vt.length() * .01;
AcGePoint3dArray vertexArray;
AcArray<Adesk::Int32> faceArray;
AcGiFaceData *faceData(NULL);
if (!acdbGetObjectMesh(pSolid, &faceter, vertexArray, faceArray, faceData) == Acad::eOk) return 0;
if (faceData)
{
delete[] faceData->trueColors();
delete[] faceData->materials();
delete faceData;
}
AcDbSubDMesh *pMesh = new AcDbSubDMesh();
pMesh->setSubDMesh(vertexArray, faceArray, 0);
int nRel((int)ss.size());
AcDbVoidPtrArray arptrs;
pMesh->explode(arptrs);
for (int i(0); i < arptrs.length(); ++i)
{
AcDbFace *pFace = AcDbFace::cast((AcDbEntity *)arptrs[i]);
if (pFace)
fromFace(ss, pFace);
else
acutPrintf(_T("\ndkdkdkddk"));
}
nRel = (int)ss.size() - nRel;
DELETE_PTR(pMesh);
deleteArrayVoidPtrs< AcDbEntity>(arptrs);
return nRel;
}
#pragma endregion
#pragma region point
point::point(const double &x, const double &y, const double &z): _x(x), _y(y), _z(z) {}
point::point(const AcGePoint3d &pt): _x(pt.x), _y(pt.y), _z(pt.z) {}
point::point(const AcGeVector3d &vt): _x(vt.x), _y(vt.y), _z(vt.z) {}
point::point(std::wstring &s): _x(.0), _y(.0), _z(.0) { _geo::set(s); }
point::point(const WValue &v): _x(.0), _y(.0), _z(.0) { _geo::set(v); }
void point::set(const double &x, const double &y, const double &z) { _x = x; _y = y; _z = z; }
void point::set(const AcGePoint3d &pt) { _x = pt.x; _y = pt.y; _z = pt.z; }
void point::set(const AcGeVector3d &vt) { _x = vt.x; _y = vt.y; _z = vt.z; }
AcGePoint3d point::asPnt3d() { return AcGePoint3d(_x, _y, _z); }
AcGeVector3d point::asVec3d() { return AcGeVector3d(_x, _y, _z); }
WValue &point::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("x"), _x);
addMember(v, _T("y"), _y);
addMember(v, _T("z"), _z);
return v;
}
bool point::ByJson(const WValue &v)
{
if (v.HasMember(_T("x")) && v.HasMember(_T("y")) && v.HasMember(_T("z")))
{
_x = v[_T("x")].GetDouble();
_y = v[_T("y")].GetDouble();
_z = v[_T("z")].GetDouble();
return true;
}
return false;
}
_geo *point::clone() { return new point(_x, _y, _z); }
_geo::TYPE point::type() { return _geo::ePoint; }
point &point::operator = (const point &pt) { _x = pt._x; _y = pt._y; _z = pt._z; return *this; }
point &point::operator = (const AcGeVector3d &vt) { _x = vt.x; _y = vt.y; _z = vt.z; return *this; }
point &point::operator = (const AcGePoint3d &pt) { _x = pt.x; _y = pt.y; _z = pt.z; return *this; }
point &point::operator=(const std::wstring &s) { _geo::set(s); return *this; }
point &point::operator=(const WValue &v) { _geo::set(v); return *this; }
byte* point::toBinary()
{
int _type((int)type());
byte *p = makeMem();
CMemTools mem(p);
mem.write<int>(&_type);
mem.write_point(this);
return p;
}
void point::byBinary(byte *p)
{
CMemTools mem(p);
int type;
mem.read<int>(&type);
*this = mem.read_point();
}
unsigned long point::memLen()
{
return 3 * sizeof(double) + sizeof(int);
}
#pragma endregion
#pragma region matrix
matrix::matrix() { }
matrix::~matrix() { }
matrix::matrix(const vector &x, const vector &y, const vector &z, const point &o)
: _x(x), _y(y), _z(z), _o(o) { }
matrix::matrix(const AcGeMatrix3d &m) { set(m); }
matrix::matrix(const matrix &m) { set(m); }
matrix::matrix(const std::wstring &s) { _geo::set(s); }
matrix::matrix(const WValue &v) { _geo::set(v); }
matrix &matrix::operator = (const AcGeMatrix3d &m) { set(m); return *this; }
matrix &matrix::operator = (std::wstring &s) { _geo::set(s); return *this; }
matrix &matrix::operator = (const matrix &m) { set(m); return *this; }
matrix &matrix::operator=(const WValue &v) { _geo::set(v); return *this; }
void matrix::set(const AcGeMatrix3d &m)
{
AcGeVector3d vtX, vtY, vtZ;
AcGePoint3d org;
m.getCoordSystem(org, vtX, vtY, vtZ);
_x = vector(vtX);
_y = vector(vtY);
_z = vector(vtZ);
_o = point(org);
}
void matrix::set(const matrix &m) { _x = m._x; _y = m._y; _z = m._z; _o = m._o; }
AcGeMatrix3d matrix::asMatrix3d()
{
AcGeMatrix3d mat;
mat.setCoordSystem(_o.asPnt3d(), _x.asVec3d(), _y.asVec3d(), _z.asVec3d());
return mat;
}
WValue &matrix::ToJson()
{
_v.SetObject();
addMember(_v, _T("x"), _x.ToJson());
addMember(_v, _T("y"), _y.ToJson());
addMember(_v, _T("z"), _z.ToJson());
addMember(_v, _T("o"), _o.ToJson());
return _v;
}
bool matrix::ByJson(const WValue &v)
{
MCIt itX(v.FindMember(_T("x")));
MCIt itY(v.FindMember(_T("y")));
MCIt itZ(v.FindMember(_T("z")));
MCIt itO(v.FindMember(_T("o")));
if (itX != v.MemberEnd() && itY != v.MemberEnd() && itZ != v.MemberEnd() && itO != v.MemberEnd())
{
_x.ByJson(itX->value);
_y.ByJson(itY->value);
_z.ByJson(itZ->value);
_o.ByJson(itO->value);
return true;
}
return false;
}
_geo *matrix::clone() { return new matrix(*this); }
_geo::TYPE matrix::type() { return eMatrix; }
unsigned long matrix::memLen()
{
return 4 * _x.memLen() + sizeof(int);
}
byte* matrix::toBinary()
{
byte *p = makeMem();
int _type((int)type());
CMemTools mem(p);
mem.write<int>(&_type);
mem.write_point(&_x);
mem.write_point(&_y);
mem.write_point(&_z);
mem.write_point(&_o);
return p;
}
void matrix::byBinary(byte *p)
{
CMemTools mem(p);
int type;
mem.read<int>(&type);
_x = mem.read_point();
_y = mem.read_point();
_z = mem.read_point();
_o = mem.read_point();
}
#pragma endregion
#pragma region binary
binary::binary(): _data(NULL), _len(0) { }
binary::~binary() { DELETE_ARR_(_data); _len = 0; }
binary::binary(const byte *data, const size_t &len): _data(NULL), _len(0) { set(data, len); }
binary::binary(const binary &b): _data(NULL), _len(0) { set(b._data, b._len); }
binary::binary(const std::wstring &s): _data(NULL), _len(0) { _geo::set(s); }
binary::binary(const WValue &v): _data(NULL), _len(0) { _geo::set(v); }
binary &binary::operator=(const binary &b) { set(b._data, b._len); return *this; }
binary &binary::operator=(const std::wstring &s) { _geo::set(s); return *this; }
binary &binary::operator=(const WValue &v) { _geo::set(v); return *this; }
void binary::set(const binary &b) { set(b._data, b._len); }
void binary::set(const byte *data, const size_t &len)
{
this->~binary();
_data = new byte[len];
_len = len;
::memset(_data, 0, sizeof(byte) * _len);
::memcpy(_data, data, sizeof(byte) * _len);
}
WValue &binary::ToJson()
{
WValue &v(_v);
v.SetObject();
std::wstring ws(_T(""));
addMember(v, _T("len"), _len);
if (_len)
{
std::string s = Base64::Encode((char *)_data, _len);
ws = Base64::ansii2Unicode(s.c_str(), CP_UTF8);
}
addMember(v, _T("data"), ws.c_str());
return v;
}
bool binary::ByJson(const WValue &v)
{
MCIt itLen = v.FindMember(_T("len"));
MCIt itData = v.FindMember(_T("data"));
if (itLen != v.MemberEnd() && itData != v.MemberEnd())
{
this->~binary();
_len = itLen->value.GetInt64();
std::wstring ws = itData->value.GetString();
std::string s = Base64::unicode2Ansii(ws.c_str(), CP_UTF8);
char *p(NULL);
// 这么写的原因是 decode() 函数有问题,反回的长度会大于原有长度,其内存会用0补齐
// 所以,这里直接用原有长度,并不会影响内存的释放。
if (Base64::Decode(s, p) >= _len)
{
_data = (byte *)p;
return true;
}
else
{
this->~binary();
DELETE_ARR_(p);
return false;
}
}
return false;
}
_geo *binary::clone() { return new binary(_data, _len); }
_geo::TYPE binary::type() { return eBinary; }
#pragma endregion
#pragma region plane
plane::plane() {}
plane::plane(const point &pt, const vector &vt): _origin(pt), _normal(vt) { }
plane::plane(const AcGePoint3d &ori, const AcGeVector3d &vt): _origin(ori), _normal(vt) {}
plane::plane(const AcGePlane &plan) { set(plan); }
plane::plane(const std::wstring &s) { _geo::set(s); }
plane::plane(const WValue &v) { _geo::set(v); }
void plane::set(const AcGePoint3d &ori, const AcGeVector3d &vt) { _origin = ori, _normal = vt; }
void plane::set(const AcGePlane &plan)
{
AcGePoint3d ptOrg(AcGePoint3d::kOrigin);
AcGeVector3d vt;
plan.get(ptOrg, vt, vt);
_origin = ptOrg;
_normal = plan.normal();
}
AcGePlane plane::asGePlane() { return AcGePlane(_origin.asPnt3d(), _normal.asVec3d()); }
WValue &plane::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("origin"), _origin.ToJson());
addMember(v, _T("normal"), _normal.ToJson());
return v;
}
bool plane::ByJson(const WValue &v)
{
if (v.HasMember(_T("origin")) && v.HasMember(_T("normal")))
{
if (!_origin.ByJson(v[_T("origin")])) return false;
if (!_normal.ByJson(v[_T("normal")])) return false;
return true;
}
return false;
}
_geo *plane::clone() { return new plane(_origin, _normal); }
_geo::TYPE plane::type() { return _geo::ePlane; }
plane &plane::operator = (const plane &plan) { _origin = plan._origin; _normal = plan._normal; return *this; }
plane &plane::operator = (const AcGePlane &plan) { *this = plane(plan); return *this; }
plane &plane::operator=(const std::wstring &s) { _geo::set(s); return *this; }
plane &plane::operator=(const WValue &v) { _geo::set(v); return *this; }
unsigned long plane::memLen()
{
return 2 * _origin.memLen() + sizeof(int);
}
byte* plane::toBinary()
{
int _type((int)type());
byte *p = makeMem();
CMemTools mem(p);
mem.write<int>(&_type);
mem.write_point(&_origin);
mem.write_point(&_normal);
return p;
}
void plane::byBinary(byte *p)
{
CMemTools mem(p);
int type;
mem.read<int>(&type);
_origin = mem.read_point();
_normal = mem.read_point();
}
#pragma endregion
#pragma region line
line::line() {}
line::line(const point &s, const point &e): _start(s), _end(e) {}
line::line(const AcGePoint3d &s, const AcGePoint3d &e): _start(s), _end(e) {}
line::line(const AcDbLine &l): _start(l.startPoint()), _end(l.endPoint()) {}
line::line(const AcDbObjectId &id) { set(id); }
line::line(const std::wstring &s) { _geo::set(s); }
line::line(const WValue &v) { _geo::set(v); }
void line::set(const AcGePoint3d &s, const AcGePoint3d &e) { _start = s; _end = e; }
void line::set(const AcDbLine &l) { _start = l.startPoint(); _end = l.endPoint(); }
void line::set(const AcDbObjectId &id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbLine, p)
if (p) set(*p);
OPENOBJ_END()
}
void line::set(const AcDbCurve *pCurve) { _CRV_SET_(AcDbLine, pCurve); }
AcDbLine *line::asDbLine() { return new AcDbLine(_start.asPnt3d(), _end.asPnt3d()); }
AcDbCurve *line::asDbCurve() { return asDbLine(); }
WValue &line::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("start"), _start.ToJson());
addMember(v, _T("end"), _end.ToJson());
return v;
}
bool line::ByJson(const WValue &v)
{
if (v.HasMember(_T("start")) && v.HasMember(_T("end")))
{
if (!_start.ByJson(v[_T("start")])) return false;
if (!_end.ByJson(v[_T("end")])) return false;
return true;
}
return false;
}
_geo *line::clone() { return new line(_start, _end); }
_geo::TYPE line::type() { return _geo::eLine; }
line &line::operator = (const line &l) { _start = l._start; _end = l._end; return *this; }
line &line::operator = (const AcDbLine &l) { _start = l.startPoint(); _end = l.endPoint(); return *this; }
line &line::operator=(const AcDbObjectId &id) { set(id); return *this; }
line &line::operator=(const std::wstring &s) { _geo::set(s); return *this; }
line &line::operator=(const WValue &v) { _geo::set(v); return *this; }
unsigned long line::memLen()
{
return 2 * _start.memLen() + sizeof(int);
}
byte* line::toBinary()
{
int _type((int)type());
byte *p = makeMem();
CMemTools mem(p);
mem.write<int>(&_type);
mem.write_point(&_start);
mem.write_point(&_end);
return p;
}
void line::byBinary(byte *p)
{
int type;
CMemTools mem(p);
mem.read<int>(&type);
_start = mem.read_point();
_end = mem.read_point();
}
#pragma endregion
#pragma region arc
arc::arc() {}
arc::arc(const point &s, const point &m, const point &e): _start(s), _middle(m), _end(e) { }
arc::arc(const AcDbArc &a) { set(a); }
arc::arc(const AcDbObjectId &id) { set(id); }
arc::arc(const std::wstring &s) { _geo::set(s); }
arc::arc(const WValue &v) { _geo::set(v); }
void arc::set(const AcDbArc &a)
{
AcGePoint3d pts(AcGePoint3d::kOrigin)
, pte(AcGePoint3d::kOrigin)
, ptm(AcGePoint3d::kOrigin);
double dL(.0);
a.getStartPoint(pts);
a.getEndPoint(pte);
a.getDistAtPoint(pte, dL);
a.getPointAtDist(dL * .5, ptm);
_start = pts;
_middle = ptm;
_end = pte;
}
void arc::set(const AcDbObjectId &id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbArc, p)
if (p) set(*p);
OPENOBJ_END()
}
void arc::set(const AcDbCurve *pCurve) { _CRV_SET_(AcDbArc, pCurve); }
AcDbArc *arc::asDbArc()
{
AcGeCircArc3d geArc(_start.asPnt3d(), _middle.asPnt3d(), _end.asPnt3d());
return CoreTools::geArc2DbArc(geArc);
}
AcDbCurve *arc::asDbCurve() { return asDbArc(); }
WValue &arc::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("start"), _start.ToJson());
addMember(v, _T("middle"), _middle.ToJson());
addMember(v, _T("end"), _end.ToJson());
return v;
}
bool arc::ByJson(const WValue &v)
{
if (v.HasMember(_T("start")) && v.HasMember(_T("end")) && v.HasMember(_T("middle")))
{
if (!_start.ByJson(v[_T("start")])) return false;
if (!_middle.ByJson(v[_T("middle")])) return false;
if (!_end.ByJson(v[_T("end")])) return false;
return true;
}
return false;
}
_geo *arc::clone() { return new arc(_start, _middle, _end); }
_geo::TYPE arc::type() { return _geo::eArc; }
arc &arc::operator = (const AcDbArc &a) { *this = arc(a); return *this; }
arc &arc::operator = (const arc &a) { _start = a._start; _middle = a._middle; _end = a._end; return *this; }
arc &arc::operator=(const AcDbObjectId &id) { set(id); return *this; }
arc &arc::operator=(const std::wstring &s) { _geo::set(s); return *this; }
arc &arc::operator=(const WValue &v) { _geo::set(v); return *this; }
unsigned long arc::memLen()
{
return 3 * _start.memLen() + sizeof(int);
}
byte *arc::toBinary()
{
int _type((int)type());
byte *p = makeMem();
CMemTools mem(p);
mem.write<int>(&_type);
mem.write_point(&_start);
mem.write_point(&_middle);
mem.write_point(&_end);
return p;
}
void arc::byBinary(byte *p)
{
int type;
CMemTools mem(p);
mem.read<int>(&type);
_start = mem.read_point();
_middle = mem.read_point();
_end = mem.read_point();
}
#pragma endregion
#pragma region circle
circle::circle(): _radius(.0) {}
circle::circle(const point &c, const vector &n, const double &r): _center(c), _normal(n), _radius(r) { }
circle::circle(const AcDbCircle &cir): _center(cir.center()), _normal(cir.normal()), _radius(cir.radius()) { }
circle::circle(const AcDbObjectId &id) { set(id); }
circle::circle(const std::wstring &s) { _geo::set(s); }
circle::circle(const WValue &v) { _geo::set(v); }
void circle::set(const AcDbCircle &cir) { _center = cir.center(); _normal = cir.normal(); _radius = cir.radius(); }
void circle::set(const AcDbObjectId &id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbCircle, p)
if (p) set(*p);
OPENOBJ_END()
}
void circle::set(const AcDbCurve *pCurve) { _CRV_SET_(AcDbCircle, pCurve); }
AcDbCircle *circle::asDbCircle() { return new AcDbCircle(_center.asPnt3d(), _normal.asVec3d(), _radius); }
AcDbCurve *circle::asDbCurve() { return asDbCircle(); }
WValue &circle::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("center"), _center.ToJson());
addMember(v, _T("normal"), _normal.ToJson());
addMember(v, _T("radius"), WValue(_radius).Move());
return v;
}
bool circle::ByJson(const WValue &v)
{
if (v.HasMember(_T("center")) && v.HasMember(_T("normal")) && v.HasMember(_T("radius")))
{
if (!_center.ByJson(v[_T("center")])) return false;
if (!_normal.ByJson(v[_T("normal")])) return false;
_radius = v[_T("radius")].GetDouble();
return true;
}
return false;
}
_geo *circle::clone()
{
return new circle(_center, _normal, _radius);
}
_geo::TYPE circle::type() { return _geo::eCircle; }
circle &circle::operator = (const circle &cir) { _center = cir._center; _normal = cir._normal; _radius = cir._radius; return *this; }
circle &circle::operator = (const AcDbCircle &cir) { _center = cir.center(); _normal = cir.normal(); _radius = cir.radius(); return *this; }
circle &circle::operator=(const AcDbObjectId &id) { set(id); return *this; }
circle &circle::operator=(const std::wstring &s) { _geo::set(s); return *this; }
circle &circle::operator=(const WValue &v) { _geo::set(v); return *this; }
unsigned long circle::memLen()
{
return 2 * _center.memLen() + sizeof(double) + sizeof(int);
}
byte *circle::toBinary()
{
int _type((int)type());
byte *p = makeMem();
CMemTools mem(p);
mem.write<int>(&_type);
mem.write_point(&_center);
mem.write_point(&_normal);
mem.write<double>(&_radius);
return p;
}
void circle::byBinary(byte *p)
{
int type;
CMemTools mem(p);
mem.read<int>(&type);
_center = mem.read_point();
_normal = mem.read_point();
mem.read<double>(&_radius);
}
#pragma endregion
#pragma region ellipse
ellipse::ellipse(): _xRadius(.0), _yRadius(.0), _startParam(.0), _endParam(.0) {}
ellipse::ellipse(const point &c
, const vector &x
, const vector &y
, const double &xr
, const double &yr
, const double &sp
, const double &ep)
: _center(c)
, _xAxis(x)
, _yAxis(y)
, _xRadius(xr)
, _yRadius(yr)
, _startParam(sp)
, _endParam(ep) { }
ellipse::ellipse(const AcDbEllipse &e) { set(e); }
ellipse::ellipse(const AcDbObjectId &id) { set(id); }
ellipse::ellipse(const ellipse &e) { set(e); }
ellipse::ellipse(const std::wstring &s) { _geo::set(s); }
ellipse::ellipse(const WValue &v) { _geo::set(v); }
void ellipse::set(const ellipse &e)
{
_center = e._center;
_xAxis = e._xAxis;
_yAxis = e._yAxis;
_xRadius = e._xRadius;
_yRadius = e._yRadius;
_startParam = e._startParam;
_endParam = e._endParam;
}
void ellipse::set(const AcDbEllipse &e)
{
_center = e.center();
_xAxis = e.majorAxis();
_yAxis = e.minorAxis();
_xRadius = e.majorAxis().length();
_yRadius = e.minorAxis().length();
_startParam = e.paramAtAngle(e.startAngle());
_endParam = e.paramAtAngle(e.endAngle());
}
void ellipse::set(const AcDbObjectId &id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEllipse, p)
if (p) set(*p);
OPENOBJ_END()
}
void ellipse::set(const AcDbCurve *pCurve) { _CRV_SET_(AcDbEllipse, pCurve); }
AcDbEllipse *ellipse::asDbEllipse()
{
AcGeVector3d vtNormal = _xAxis.asVec3d().crossProduct(_yAxis.asVec3d());
AcDbEllipse *pEll = new AcDbEllipse(_center.asPnt3d()
, vtNormal
, _xAxis.asVec3d()
, _yRadius / _xRadius);
double dSA = pEll->angleAtParam(_startParam);
double dEA = pEll->angleAtParam(_endParam);
pEll->setStartAngle(dSA);
pEll->setEndAngle(dEA);
return pEll;
}
AcDbCurve *ellipse::asDbCurve() { return asDbEllipse(); }
WValue &ellipse::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("center"), _center.ToJson());
addMember(v, _T("xAxis"), _xAxis.ToJson());
addMember(v, _T("yAxis"), _yAxis.ToJson());
addMember(v, _T("xRadius"), _xRadius);
addMember(v, _T("yRadius"), _yRadius);
addMember(v, _T("startParam"), _startParam);
addMember(v, _T("endParam"), _endParam);
return v;
}
bool ellipse::ByJson(const WValue &v)
{
if (v.HasMember(_T("center"))
&& v.HasMember(_T("xAxis"))
&& v.HasMember(_T("yAxis"))
&& v.HasMember(_T("xRadius"))
&& v.HasMember(_T("yRadius"))
&& v.HasMember(_T("startParam"))
&& v.HasMember(_T("endParam")))
{
if (!_center.ByJson(v[_T("center")])) return false;
if (!_xAxis.ByJson(v[_T("xAxis")])) return false;
if (!_yAxis.ByJson(v[_T("yAxis")])) return false;
_xRadius = v[_T("xRadius")].GetDouble();
_yRadius = v[_T("yRadius")].GetDouble();
_startParam = v[_T("startParam")].GetDouble();
_endParam = v[_T("endParam")].GetDouble();
return true;
}
return false;
}
_geo *ellipse::clone() { return new ellipse(*this); }
_geo::TYPE ellipse::type() { return _geo::eEllipse; }
ellipse &ellipse::operator = (const ellipse &e) { set(e); return *this; }
ellipse &ellipse::operator = (const AcDbEllipse &e) { set(e); return *this; }
ellipse &ellipse::operator=(const AcDbObjectId &id) { set(id); return *this; }
ellipse &ellipse::operator=(const std::wstring &s) { _geo::set(s); return *this; }
ellipse &ellipse::operator=(const WValue &v) { _geo::set(v); return *this; }
unsigned long ellipse::memLen()
{
return 3 * _center.memLen() + 4 * sizeof(double) + sizeof(int);
}
byte *ellipse::toBinary()
{
int _type((int)type());
byte *p = makeMem();
CMemTools mem(p);
mem.write<int>(&_type);
mem.write_point(&_center);
mem.write_point(&_xAxis);
mem.write_point(&_yAxis);
mem.write<double>(&_xRadius);
mem.write<double>(&_yRadius);
mem.write<double>(&_startParam);
mem.write<double>(&_endParam);
return p;
}
void ellipse::byBinary(byte *p)
{
int type;
CMemTools mem(p);
mem.read<int>(&type);
_center = mem.read_point();
_xAxis = mem.read_point();
_yAxis = mem.read_point();
mem.read<double>(&_xRadius);
mem.read<double>(&_yRadius);
mem.read<double>(&_startParam);
mem.read<double>(&_endParam);
}
#pragma endregion
#pragma region spline
_geo::TYPE spline::type() { return _geo::eSpline; }
spline::spline() { }
spline::spline(const AcDbSpline &pl) { set(pl); }
spline::spline(const spline &pl) { set(pl); }
void spline::set(const AcDbSpline &sp)
{
#if ARX > 18
_spType = sp.type();
#else
_spType = sp.hasFitData() ? 0 : 1;
#endif
_fitPts.clear();
_controlPts.clear();
AcGePoint3dArray fits_pts, control_pts;
AcGePoint3d pt;
AcGeVector3d vt1, vt2;
#if ARX < 19
sp.getFitData(fits_pts
, _degree_fit
, _fitTolerance
, _tangentsExist
, vt1
, vt2
);
#else
AcGe::KnotParameterization knotp;
sp.getFitData(fits_pts
, _tangentsExist
, vt1
, vt2
, knotp
, _degree_fit
, _fitTolerance
);
_knotParam = (int)knotp;
#endif
for (int i(0); i < fits_pts.length(); ++i)
_fitPts.push_back(fits_pts[i]);
_startTangent = vt1;
_endTangent = vt2;
sp.getNurbsData(_degree_nurb
, _rational
, _closed
, _periodic
, control_pts
, _knots
, _weights
, _controlPtTol
, _knotTol);
for (int i(0); i < control_pts.length(); ++i)
_controlPts.push_back(control_pts[i]);
}
void spline::set(const spline &pl)
{
_spType = pl._spType;
_fitPts.clear();
_controlPts.clear();
_fitPts.assign(pl._fitPts.begin(), pl._fitPts.end());
_controlPts.assign(pl._controlPts.begin(), pl._controlPts.end());
_tangentsExist = pl._tangentsExist;
_startTangent = pl._startTangent;
_endTangent = pl._endTangent;
_knotParam = pl._knotParam;
_degree_fit = pl._degree_fit;
_fitTolerance = pl._fitTolerance;
_degree_nurb = pl._degree_nurb;
_rational = pl._degree_nurb;
_closed = pl._degree_nurb;
_periodic = pl._degree_nurb;
_knots.removeAll();
_knots.append(pl._knots);
_weights.removeAll();
_weights.append(pl._weights);
_knotTol = pl._knotTol;
_controlPtTol = pl._controlPtTol;
}
void spline::set(const AcDbObjectId &id)
{
AcDbObjectPointer<AcDbSpline> ptr(id, AcDb::kForRead);
if (ptr.openStatus() != Acad::eOk) return;
set(*ptr.object());
}
void spline::set(const AcDbCurve *pCurve) { _CRV_SET_(AcDbSpline,pCurve); }
AcDbCurve *spline::asDbCurve()
{
AcGePoint3dArray arpts;
AcDbSpline *p(new AcDbSpline());
#if ARX > 18
p->setType((SplineType)_spType);
#else
#endif
if (!_fitPts.empty() && _spType == 0)
{
for (size_t i(0); i < _fitPts.size(); ++i)
arpts.append(_fitPts[i].asPnt3d());
//#if ARX < 19
p->setFitData(arpts
, _degree_fit
, _fitTolerance
, _startTangent.asVec3d()
, _endTangent.asVec3d()
);
//#else
// AcGe::KnotParameterization knotp = (AcGe::KnotParameterization)_knotParam;
// if (knotp == AcGe::kCustomParameterization)
// knotp = AcGe::kUniform;
// p->setFitData(arpts
// , _startTangent.asVec3d()
// , _endTangent.asVec3d()
// , knotp
// , _degree_fit
// , _fitTolerance
// );
//#endif
}
if (!_controlPts.empty() && _spType == 1)
{
for (size_t i(0); i < _controlPts.size(); ++i)
arpts.append(_controlPts[i].asPnt3d());
p->setNurbsData(_degree_nurb
, _rational
, _closed
, _periodic
, arpts
, _knots
, _weights
, _controlPtTol
, _knotTol);
}
return p;
}
WValue& spline::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("splineType"), _spType);
WValue ar;
ar.SetArray();
for (size_t i(0); i < _fitPts.size(); ++i)
pushBack(ar, _fitPts[i].ToJson());
addMember(v, _T("f_points"), ar);
addMember(v, _T("f_degree"), _degree_fit);
addMember(v, _T("tangentsExist"), _tangentsExist);
addMember(v, _T("startTangent"), vector(_startTangent).ToJson());
addMember(v, _T("endTangent"), vector(_endTangent).ToJson());
addMember(v, _T("knotParam"), _knotParam);
addMember(v, _T("fitTolerance"), _fitTolerance);
ar.SetArray();
for (size_t i(0); i < _controlPts.size(); ++i)
pushBack(ar, _controlPts[i].ToJson());
addMember(v, _T("c_points"), ar);
addMember(v, _T("c_degree"), _degree_nurb);
addMember(v, _T("rational"), _rational);
addMember(v, _T("closed"), _closed);
addMember(v, _T("periodic"), _periodic);
ar.SetArray();
for (int i(0); i < _knots.length(); ++i)
pushBack(ar, _knots[i]);
addMember(v, _T("knots"), ar);
ar.SetArray();
for (int i(0); i < _weights.length(); ++i)
pushBack(ar, _weights[i]);
addMember(v, _T("weights"), ar);
addMember(v, _T("controlPtTol"), _controlPtTol);
addMember(v, _T("knotTol"), _knotTol);
return v;
}
bool spline::ByJson(const WValue &v) { return false; }
_geo *spline::clone() { return new spline(*this); }
spline &spline::operator = (const spline &pl) { set(pl); return *this; }
spline& spline::operator = (const AcDbSpline &pl) { set(pl); return *this;}
spline& spline::operator = (const AcDbObjectId &id) { set(id); return *this;}
unsigned long spline::memLen()
{
point pt;
unsigned long len = sizeof(int) + sizeof(int);
len += sizeof(size_t);
len += (unsigned long)_fitPts.size() * pt.memLen(); // _fitPts
len += sizeof(Adesk::Boolean); // _tangentsExist
len += pt.memLen(); // _startTangent
len += pt.memLen(); // _endTangent
len += sizeof(int); // _knotParam
len += sizeof(int); // _degree_fit
len += sizeof(double); // _fitTolerance
len += sizeof(size_t);
len += (unsigned long)_controlPts.size() * pt.memLen(); // _controlPts
len += sizeof(int); // _degree_nurb
len += sizeof(Adesk::Boolean); // _rational
len += sizeof(Adesk::Boolean); // _closed
len += sizeof(Adesk::Boolean); // _periodic
len += sizeof(int);
len += _knots.length() * sizeof(double); // _knots
len += sizeof(int);
len += _weights.length() * sizeof(double); // _weights
len += sizeof(double); // _controlPtTol
len += sizeof(double); // _knotTol
return len;
}
byte *spline::toBinary()
{
int _type((int)type());
point pt;
size_t num(0);
int num1(0);
byte *p = makeMem();
CMemTools mem(p);
mem.write<int>(&_type);
mem.write<int>(&_spType);
num = _fitPts.size();
mem.write<size_t>(&num);
for (int i(0); i < num; ++i)
mem.write_point(&_fitPts[i]);
mem.write<Adesk::Boolean>(&_tangentsExist);
mem.write_point(&_startTangent);
mem.write_point(&_endTangent);
mem.write<int>(&_knotParam);
mem.write<int>(&_degree_fit);
mem.write<double>(&_fitTolerance);
num = _controlPts.size();
mem.write<size_t>(&num);
for (int i(0); i < num; ++i)
mem.write_point(&_controlPts[i]);
mem.write<int>(&_degree_nurb);
mem.write<Adesk::Boolean>(&_rational);
mem.write<Adesk::Boolean>(&_closed);
mem.write<Adesk::Boolean>(&_periodic);
num1 = _knots.length();
mem.write<int>(&num1);
mem.write<double>(_knots.asArrayPtr(), num1);
num1 = _weights.length();
mem.write<int>(&num1);
mem.write<double>(_weights.asArrayPtr(), num1);
mem.write<double>(&_controlPtTol);
mem.write<double>(&_knotTol);
return p;
}
void spline::byBinary(byte *p)
{
size_t num(0);
int num1(0);
int type;
CMemTools mem(p);
mem.read<int>(&type);
mem.read<int>(&_spType);
mem.read<size_t>(&num);
for (size_t i(0); i < num; ++i)
_fitPts.push_back(mem.read_point());
mem.read<Adesk::Boolean>(&_tangentsExist);
_startTangent = mem.read_point();
_endTangent = mem.read_point();
mem.read<int>(&_knotParam);
mem.read<int>(&_degree_fit);
mem.read<double>(&_fitTolerance);
mem.read<size_t>(&num);
for (size_t i(0); i < num; ++i)
_controlPts.push_back(mem.read_point());
mem.read<int>(&_degree_nurb);
mem.read<Adesk::Boolean>(&_rational);
mem.read<Adesk::Boolean>(&_closed);
mem.read<Adesk::Boolean>(&_periodic);
mem.read<int>(&num1);
_knots.setLogicalLength(num1);
mem.read<double>(_knots.asArrayPtr(), num1);
mem.read<int>(&num1);
_weights.setLogicalLength(num1);
mem.read<double>(_weights.asArrayPtr(), num1);
mem.read<double>(&_controlPtTol);
mem.read<double>(&_knotTol);
}
#pragma endregion
#pragma region path
path::path(): _profile(0) { }
path::~path() { clear(); }
path::path(const AcDbEntity &ent) { set(ent); }
path::path(const AcDbObjectId &id) { set(id); }
path::path(const std::wstring &s) { _geo::set(s); }
path::path(const WValue &v) { _geo::set(v); }
path &path::operator=(const profile &pf) { set(pf); return *this; }
path &path::operator=(const path &reg) { set(reg); return *this; }
path &path::operator=(const AcDbEntity &ent) { set(ent); return *this; }
path &path::operator=(const AcDbObjectId &id) { set(id); return *this; }
path &path::operator=(const std::wstring &s) { _geo::set(s); return *this; }
path &path::operator=(const WValue &v) { _geo::set(v); return *this; }
void path::set(const path &pt) { set(pt._profile); }
void path::set(const profile &pf)
{
clear();
for (size_t i = 0; i < pf.size(); ++i)
_profile.push_back(pf[i]->clone());
}
void path::set(const AcDbEntity &ent)
{
clear();
AcGePlane plan;
region::profiles pfs;
tools::fromEntity(pfs, plan, ent, false);
if (!pfs.empty())
{
set(*pfs[0]);
// 只用第一个,其它的释放
for (size_t i = 1; i < pfs.size(); ++i)
pfs[i]->clear();
}
_plane = plan;
}
void path::set(const AcDbCurve *pCurve)
{
const AcDbEntity *p((const AcDbEntity *)pCurve);
set(*p);
}
void path::set(const AcDbObjectId &id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt)
if (pEnt) set(*pEnt);
OPENOBJ_END()
}
void path::clear() { deleteContainerOfStd(_profile); }
bool path::isEmpty() { return _profile.empty(); }
AcDbCurve *path::asDbCurve()
{
AcDbCurve *pCrv = tools::asDbPolyline(_profile);
if (pCrv)
return pCrv;
return NULL;
}
AcDbRegion *path::asDbRegion()
{
AcDbRegion *pReg = tools::asDbRegion(_profile);
if (pReg)
return pReg;
return NULL;
}
WValue &path::ToJson()
{
WValue &v(_v), ar;
v.SetObject();
addType(v);
ar.SetArray();
for (size_t i = 0; i < _profile.size(); ++i)
{
pushBack(ar, _profile[i]->ToJson());
}
addMember(v, _T("profile"), ar);
addMember(v, _T("plane"), _plane.ToJson());
return v;
}
bool path::ByJson(const WValue &v)
{
clear();
MCIt vPath = v.FindMember(_T("profile"));
if (vPath != v.MemberEnd())
{
WCValue &v = vPath->value;
for (WCValue::ConstValueIterator it = v.Begin(); it != v.End(); ++it)
_profile.push_back(createGeo(*it));
return true;
}
return false;
}
_geo *path::clone() { return new path(*this); }
_geo::TYPE path::type() { return ePath; }
unsigned long path::memLen()
{
unsigned long len(sizeof(size_t));
len += sizeof(int);
for (size_t i(0); i < _profile.size(); ++i)
len += _profile[i]->memLen();
len += _plane.memLen();
return len;
}
byte *path::toBinary()
{
int _type((int)type());
byte *p(makeMem());
CMemTools mem(p);
mem.write<int>(&_type);
size_t num(_profile.size());
mem.write<size_t>(&num);
for (size_t i(0); i < _profile.size(); ++i)
mem.write(_profile[i]->toBinary(), _profile[i]->memLen(), true);
mem.write(_plane.toBinary(), _plane.memLen(), true);
return p;
}
void path::byBinary(byte *p)
{
int type;
CMemTools mem(p);
mem.read<int>(&type);
size_t num(0);
mem.read<size_t>(&num);
for (size_t i(0); i < num; ++i)
{
_geo *pGeo = tools::makeGeoPtr(mem.curPos());
if (pGeo)
{
mem.forward(pGeo->memLen());
_profile.push_back(pGeo);
}
}
_plane.byBinary(mem.curPos());
}
#pragma endregion
#pragma region region
region::region(): _profiles(0) { }
region::~region() { clear(); }
region::region(const AcDbEntity &ent, bool b2D): _b2D(b2D) { set(ent); }
region::region(const AcDbObjectId &id, bool b2D): _b2D(b2D) { set(id); }
region::region(const std::wstring &s, bool b2D): _b2D(b2D) { _geo::set(s); }
region::region(const WValue &v, bool b2D): _b2D(b2D) { _geo::set(v); }
region &region::operator=(const region &reg) { set(reg); return *this; }
region &region::operator=(const AcDbEntity &ent) { set(ent); return *this; }
region &region::operator=(const AcDbObjectId &id) { set(id); return *this; }
region &region::operator=(const std::wstring &s) { _geo::set(s); return *this; }
region &region::operator=(const WValue &v) { _geo::set(v); return *this; }
void region::set(const region &reg)
{
clear();
for (size_t i = 0; i < reg._profiles.size(); ++i)
_profiles.push_back((path *)reg._profiles[i]->clone());
_plane = reg._plane;
}
void region::set(const AcDbEntity &ent)
{
clear();
AcGePlane plan;
tools::fromEntity(_profiles, plan, ent, _b2D);
_plane = plan;
}
void region::set(const AcDbObjectId &id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, p)
if (p) set(*p);
OPENOBJ_END()
}
AcDbCurve *region::asDbCurve()
{
AcDbCurve *pCrv(NULL);
std::vector<AcDbCurve *> crvs;
asDbCurve(crvs);
if (!crvs.empty())
pCrv = (AcDbCurve *)crvs[0]->clone();
deleteContainerOfStd(crvs);
return pCrv;
}
void region::asDbCurve(std::vector<AcDbCurve *> &crvs)
{
for (size_t i = 0; i < _profiles.size(); ++i)
{
AcDbCurve *pCrv = _profiles[i]->asDbCurve();
if (pCrv)
crvs.push_back(pCrv);
}
}
void region::asDbRegion(std::vector<AcDbRegion *> &regs)
{
for (size_t i = 0; i < _profiles.size(); ++i)
{
AcDbRegion *pReg = _profiles[i]->asDbRegion();
if (pReg)
regs.push_back(pReg);
}
}
AcDbRegion *region::asDbRegion()
{
AcDbRegion *pReg(NULL);
std::vector<AcDbRegion *> regs;
asDbRegion(regs);
if (!regs.empty())
pReg = (AcDbRegion *)regs[0]->clone();
deleteContainerOfStd(regs);
return pReg;
}
void region::clear() { deleteContainerOfStd(_profiles); }
bool region::isEmpty() { return _profiles.empty(); }
WValue &region::ToJson()
{
WValue &v(_v), ar3D, ar2D;
v.SetObject();
addType(v);
ar3D.SetArray();
ar2D.SetArray();
for (size_t i = 0; i < _profiles.size(); ++i)
{
path *pf(_profiles[i]);
pushBack(ar3D, pf->ToJson());
}
addMember(v, _T("profiles"), ar3D);
addMember(v, _T("plane"), _plane.ToJson());
return v;
}
bool region::ByJson(const WValue &v)
{
MCIt itPfs = v.FindMember(_T("profiles"));
MCIt itPlan = v.FindMember(_T("plane"));
if (itPfs != v.MemberEnd() && itPlan != v.MemberEnd())
{
const WCValue &pfs = itPfs->value;
for (WValue::ConstValueIterator itPf = pfs.Begin(); itPf != pfs.End(); ++itPf)
{
path *pt = new path();
if (pt->ByJson(*itPf))
_profiles.push_back(pt);
}
_plane.ByJson(itPlan->value);
return true;
}
return false;
}
_geo *region::clone() { return new region(*this); }
_geo::TYPE region::type() { return eRegion; }
#pragma endregion
#pragma region extruded
extruded::extruded() {}
extruded::extruded(const region &r, const path &p) { set(r, p); }
extruded::extruded(const AcDbEntity &reg, const AcDbCurve &curve) { _region.set(reg); _path.set(curve); }
extruded::extruded(const AcDbObjectId &reg, const AcDbObjectId &curve) { set(reg, curve); }
extruded::extruded(const std::wstring &s) { _geo::set(s); }
extruded::extruded(const WValue &v) { _geo::set(v); }
extruded::~extruded() {}
void extruded::set(const AcDbEntity &reg, const AcDbCurve &curve) { *this = extruded(reg, curve); }
void extruded::set(const region &r, const path &p) { _region.set(r); _path.set(p); }
void extruded::set(const AcDbObjectId &reg, const AcDbObjectId &curve)
{
_region.set(reg);
_path.set(curve);
}
AcDbCurve *extruded::DbRegion1() { return _region.asDbCurve(); }
AcDbRegion *extruded::DbRegion2() { return _region.asDbRegion(); }
AcDbCurve *extruded::DbPath() { return _path.asDbCurve(); }
WValue &extruded::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
addMember(v, _T("region"), _region.ToJson());
addMember(v, _T("path"), _path.ToJson());
return v;
}
bool extruded::ByJson(const WValue &v)
{
if (v.HasMember(_T("region")) && v.HasMember(_T("path")))
{
WCValue &region = v[_T("region")];
WCValue &path = v[_T("path")];
if (!region.IsArray() || !path.IsArray()) return false;
if (!_region.ByJson(region)) return false;
if (!_path.ByJson(path)) return false;
return true;
}
return false;
}
_geo *extruded::clone() { return new extruded(_region, _path); }
_geo::TYPE extruded::type() { return _geo::eExtruded; }
extruded &extruded::operator = (const extruded &ed) { set(ed._region, ed._path); return *this; }
extruded &extruded::operator=(const std::wstring &s) { _geo::set(s); return *this; }
extruded &extruded::operator=(const WValue &v) { _geo::set(v); return *this; }
#pragma endregion
#pragma region revolved
revolved::revolved(): extruded() {}
revolved::revolved(const AcDbEntity &reg, const AcDbCurve &curve): extruded(reg, curve) { }
revolved::revolved(const AcDbObjectId &reg, const AcDbObjectId &curve) { extruded::set(reg, curve); }
revolved::revolved(const std::wstring &s) { _geo::set(s); }
revolved::revolved(const WValue &v) { _geo::set(v); }
_geo::TYPE revolved::type() { return _geo::eRevolved; }
revolved &revolved::operator = (const revolved &ed) { extruded::set(ed._region, ed._path); return *this; }
revolved &revolved::operator=(const std::wstring &s) { _geo::set(s); return *this; }
revolved &revolved::operator=(const WValue &v) { _geo::set(v); return *this; }
#pragma endregion
#pragma region sweep
sweep::sweep(): extruded() {}
sweep::sweep(const AcDbEntity &reg, const AcDbCurve &curve): extruded(reg, curve) { }
sweep::sweep(const AcDbObjectId &reg, const AcDbObjectId &curve) { extruded::set(reg, curve); }
sweep::sweep(const std::wstring &s) { _geo::set(s); }
sweep::sweep(const WValue &v) { _geo::set(v); }
_geo::TYPE sweep::type() { return _geo::eSweep; }
sweep &sweep::operator = (const sweep &ed) { extruded::set(ed._region, ed._path); return *this; }
sweep &sweep::operator=(const std::wstring &s) { _geo::set(s); return *this; }
sweep &sweep::operator=(const WValue &v) { _geo::set(v); return *this; }
#pragma endregion
#pragma region loft
loft::loft():_regions(0) {}
loft::loft(std::vector<region *> regs) { set(regs); }
loft::loft(const AcDbVoidPtrArray &regs) { set(regs); }
loft::loft(const AcDbObjectIdArray &ids) { set(ids); }
loft::loft(const std::wstring &s) { _geo::set(s); }
loft::loft(const WValue &v) { _geo::set(v); }
loft::~loft() { deleteContainerOfStd(_regions); }
void loft::getRegions(AcDbVoidPtrArray &ar, const bool &byPoly)
{
for (size_t i = 0; i < _regions.size(); ++i)
ar.append(!byPoly ? (AcDbEntity *)_regions[i]->asDbRegion() : (AcDbEntity *)_regions[i]->asDbCurve());
}
void loft::set(const AcDbVoidPtrArray &regs)
{
deleteContainerOfStd(_regions);
for (int i = 0; i < regs.length(); ++i)
{
region *p = new region(*(AcDbEntity *)regs[i]);
if (!p->isEmpty())
_regions.push_back(p);
else
DELETE_PTR(p);
}
}
void loft::set(const AcDbObjectIdArray &ids)
{
deleteContainerOfStd(_regions);
for (int i = 0; i < ids.length(); ++i)
{
region *p = new region(ids[i]);
if (!p->isEmpty())
_regions.push_back(p);
else
DELETE_PTR(p);
}
}
void loft::set(const std::vector<region *> &regs)
{
deleteContainerOfStd(_regions);
for (size_t i = 0; i < regs.size(); ++i)
_regions.push_back((region *)regs[i]->clone());
}
loft &loft::operator=(const loft &l) { set(l._regions); return *this; }
loft &loft::operator=(const std::wstring &s) { _geo::set(s); return *this; }
loft &loft::operator=(const WValue &v) { _geo::set(v); return *this; }
WValue &loft::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
WValue regs;
regs.SetArray();
for (size_t i = 0; i < _regions.size(); ++i)
{
pushBack(regs, _regions[i]->ToJson());
}
addMember(v, _T("regions"), regs);
return v;
}
bool loft::ByJson(const WValue &v)
{
if (!v.HasMember(_T("regions"))) return false;
WCValue &regions = v[_T("regions")];
if (!regions.IsArray()) return false;
deleteContainerOfStd(_regions);
for (WValue::ConstValueIterator it = regions.Begin(); it != regions.End(); ++it)
{
region *p = new region();
if (p->ByJson(*it))
_regions.push_back(p);
else
DELETE_PTR(p);
}
return true;
}
_geo *loft::clone() { return new loft(_regions); }
_geo::TYPE loft::type() { return _geo::eLoft; }
#pragma endregion
#pragma region tessellation
WValue& tessellation::ToJson()
{
WValue &v(_v);
v.SetObject();
addType(v);
WValue ar;
ar.SetArray();
for (int i(0); i < _pts.length(); ++i)
pushBack(ar, point(_pts[i]).ToJson());
addMember(v, _T("_pts_"), ar);
addMember(v, _T("_r"), _r);
addMember(v, _T("_g"), _g);
addMember(v, _T("_b"), _b);
return v;
}
_geo* tessellation::clone()
{
return new tessellation(_pts, RGB(_r, _g, _b));
}
void tessellation::set(const AcGePoint3dArray &pts, const DWORD dwClr)
{
_pts.removeAll();
_pts.append(pts);
_r = GetRValue(dwClr);
_g = GetGValue(dwClr);
_b = GetBValue(dwClr);
}
tessellation &tessellation::operator = (const tessellation &t)
{
set(t._pts, RGB(t._r, t._g, t._b));
return *this;
}
#pragma endregion
}
#include "KTCadUtility.h"
#include "aecdbwall.h"
void _export_test_()
{
/*
byte b[10] = { 0,1,2,3,4,5,6,7,8,9 };
std::wstring s = GEO2JSON::binary(b, 10).toString();
GEO2JSON::binary xx(s);
GEO2JSON::point pt(1., 2., 3.);
WValue v;
addMember(v, _T("pt"), pt.ToJson());
addMember(v, _T("string"), _T("test"));
addMember(v, _T("bool"), false);
addMember(v, _T("int"), 11);
addMember(v, _T("unsigned"), 11);
addMember(v, _T("double"), 1.1);
addMember(v, _T("float"), 1.1f);
addMember(v, _T("__int64"), __int64(11));
addMember(v, _T("unsigned __int64"), unsigned __int64(22));
WValue ar;
ar.SetArray();
pushBack(ar, 1);
pushBack(ar, 2);
pushBack(ar, 3);
pushBack(ar, 4);
addMember(v, _T("array"), ar);
std::wstring ws = write2Json(v);
addMember(v, _T("pt"), GEO2JSON::point(5., 6., 7.).ToJson());
addMember(v, _T("string"), _T("abcd"));
ar.SetNull();
ar.SetArray();
pushBack(ar, 6);
pushBack(ar, 7);
pushBack(ar, 8);
pushBack(ar, 9);
addMember(v, _T("array"), ar);
ws = write2Json(v);
return;
*/
/*AecDbObjXDataMap data;
AcGePoint3d pt;
AcGeVector3d vt;
AcGeMatrix3d mat;
mat.setCoordSystem(AcGePoint3d(100, 100, 100), AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis);
AcGeMatrix3d mat_t(mat);
mat_t.setTranslation(AcGeVector3d(.5, .5, .5));
SHJson::json2File(_T("d:\\桌面\\matrix_t.json"), GEO2JSON::matrix(mat_t).ToJson());
AcGeMatrix3d mat_s(mat);
mat_s.setToScaling(.5);
SHJson::json2File(_T("d:\\桌面\\matrix_s.json"), GEO2JSON::matrix(mat_s).ToJson());
AcGeMatrix3d mat_r(mat);
mat_r.setToRotation(.5 * PI, AcGeVector3d::kZAxis);
SHJson::json2File(_T("d:\\桌面\\matrix_r.json"), GEO2JSON::matrix(mat_r).ToJson());
SHJson::json2File(_T("d:\\桌面\\matrix.json"), GEO2JSON::matrix(mat).ToJson());
TCHAR *psz = _T("abcdefg");
std::wstring bs = GEO2JSON::binary((byte*)psz, sizeof(TCHAR) * (_tcslen(psz) + 1)).toString();
SHJson::json2File(_T("d:\\桌面\\binary.json"), GEO2JSON::binary((byte*)psz, sizeof(TCHAR) * (_tcslen(psz) + 1)).ToJson());
GEO2JSON::binary b(bs);
TCHAR *pb = (TCHAR *)b._data;
return;
AcDbObjectId id;
char p[10] = { 0 };
data.SetAt(_T("int"), 1);
data.SetAt(_T("double"), 1.0);
data.SetAt(_T("point"), pt);
data.SetAt(_T("vector"), vt);
data.SetAt(_T("matrix"), mat);
data.SetAt(_T("binary"), p, 10);
data.SetAt(_T("objectid"), id);
data.SetAt(_T("string"), _T("string"));
WValue &v = data.ToJson();
std::wstring s = write2Json(v);
acutPrintf(_T("%s"), s.c_str());
return;*/
/*
ads_name ents, ent;
AcDbObjectId idEnt1, idEnt2;
resbuf *pRb = acutBuildList(RTDXF0, _T("Line,Arc,Circle"), 0);
int nRes = CKTCadUtility::SelectEntities(_T("\n请选择一个polyline或region."), ents, pRb);
acutRelRb(pRb);
if (nRes != RTNORM) return;
AcDbObjectId id;
Adesk::Int32 lLen(0L);
acedSSLength(ents, &lLen);
AcDbVoidPtrArray ar;
for (long i = 0; i < lLen; ++i)
{
if (acedSSName(ents, i, ent) != RTNORM) continue;
if (acdbGetObjectId(id, ent) != Acad::eOk) continue;
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt)
if (pEnt)
{
ar.append(pEnt->clone());
}
OPENOBJ_END()
}
acedSSFree(ents);
std::vector<AcDbPolyline*> polys;
CoreTools::MakePolyline(ar, polys);
for (int i = 0; i < polys.size(); ++i)
{
AcDbPolyline *pPoly = polys[i];
if (pPoly)
CoreTools::AddToModelSpace(pPoly);
}
deleteContainerOfArx(ar);
return;
*/
ads_name ent;
resbuf *pRb = acutBuildList(RTDXF0, _T("Region"), 0);
int nRes = CKTCadUtility::SelectEntity(_T("\n请选择一个polyline或region."), ent, pRb);
acutRelRb(pRb);
if (nRes != RTNORM) return;
AcDbObjectId id;
if (acdbGetObjectId(id, ent) != Acad::eOk) return;
CString str;
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbRegion, pReg)
CoreTools::RegionToString(pReg, str);
OPENOBJ_END()
CStdioFile file;
if (file.Open(_T("d:\\xxx.sat"), CFile::modeCreate | CFile::modeWrite))
{
file.WriteString(str);
file.Close();
}
}