2546 lines
61 KiB
C++
2546 lines
61 KiB
C++
#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 *> ®s)
|
||
{
|
||
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 ? ®Plane : 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 ? ®Plane : 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 ®) { 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 ®ion::operator=(const region ®) { set(reg); return *this; }
|
||
|
||
region ®ion::operator=(const AcDbEntity &ent) { set(ent); return *this; }
|
||
|
||
region ®ion::operator=(const AcDbObjectId &id) { set(id); return *this; }
|
||
|
||
region ®ion::operator=(const std::wstring &s) { _geo::set(s); return *this; }
|
||
|
||
region ®ion::operator=(const WValue &v) { _geo::set(v); return *this; }
|
||
|
||
void region::set(const region ®)
|
||
{
|
||
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 *> ®s)
|
||
{
|
||
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 ®ion::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 ®, const AcDbCurve &curve) { _region.set(reg); _path.set(curve); }
|
||
|
||
extruded::extruded(const AcDbObjectId ®, 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 ®, 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 ®, 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 ®ion = 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 ®, const AcDbCurve &curve): extruded(reg, curve) { }
|
||
|
||
revolved::revolved(const AcDbObjectId ®, 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 ®, const AcDbCurve &curve): extruded(reg, curve) { }
|
||
|
||
sweep::sweep(const AcDbObjectId ®, 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 ®s) { 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 ®s)
|
||
{
|
||
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 *> ®s)
|
||
{
|
||
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 ®ions = 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();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|