#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(v); case ePlane: return newGeo(v); case eLine: return newGeo(v); case eArc: return newGeo(v); case eCircle: return newGeo(v); case eEllipse: return newGeo(v); case eExtruded: return newGeo(v); case eRevolved: return newGeo(v); case eLoft: return newGeo(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 ®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 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(pCir, pt, *pPlane); return true; } CLASS_CONVER(AcDbEllipse, pEll, pCurve); if (pEll) { if (!pPlane) pt->_profile.push_back(new ellipse(*pEll)); else convertEntityByPlane(pEll, pt, *pPlane); return true; } CLASS_CONVER(AcDbLine, pLine, pCurve); if (pLine) { if (!pPlane) pt->_profile.push_back(new line(*pLine)); else convertEntityByPlane(pLine, pt, *pPlane); return true; } CLASS_CONVER(AcDbArc, pArc, pCurve); if (pArc) { if (!pPlane) pt->_profile.push_back(new arc(*pArc)); else convertEntityByPlane(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 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 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 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 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(&_type); mem.write_point(this); return p; } void point::byBinary(byte *p) { CMemTools mem(p); int type; mem.read(&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(&_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(&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(&_type); mem.write_point(&_origin); mem.write_point(&_normal); return p; } void plane::byBinary(byte *p) { CMemTools mem(p); int type; mem.read(&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(&_type); mem.write_point(&_start); mem.write_point(&_end); return p; } void line::byBinary(byte *p) { int type; CMemTools mem(p); mem.read(&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(&_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(&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(&_type); mem.write_point(&_center); mem.write_point(&_normal); mem.write(&_radius); return p; } void circle::byBinary(byte *p) { int type; CMemTools mem(p); mem.read(&type); _center = mem.read_point(); _normal = mem.read_point(); mem.read(&_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(&_type); mem.write_point(&_center); mem.write_point(&_xAxis); mem.write_point(&_yAxis); mem.write(&_xRadius); mem.write(&_yRadius); mem.write(&_startParam); mem.write(&_endParam); return p; } void ellipse::byBinary(byte *p) { int type; CMemTools mem(p); mem.read(&type); _center = mem.read_point(); _xAxis = mem.read_point(); _yAxis = mem.read_point(); mem.read(&_xRadius); mem.read(&_yRadius); mem.read(&_startParam); mem.read(&_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 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(&_type); mem.write(&_spType); num = _fitPts.size(); mem.write(&num); for (int i(0); i < num; ++i) mem.write_point(&_fitPts[i]); mem.write(&_tangentsExist); mem.write_point(&_startTangent); mem.write_point(&_endTangent); mem.write(&_knotParam); mem.write(&_degree_fit); mem.write(&_fitTolerance); num = _controlPts.size(); mem.write(&num); for (int i(0); i < num; ++i) mem.write_point(&_controlPts[i]); mem.write(&_degree_nurb); mem.write(&_rational); mem.write(&_closed); mem.write(&_periodic); num1 = _knots.length(); mem.write(&num1); mem.write(_knots.asArrayPtr(), num1); num1 = _weights.length(); mem.write(&num1); mem.write(_weights.asArrayPtr(), num1); mem.write(&_controlPtTol); mem.write(&_knotTol); return p; } void spline::byBinary(byte *p) { size_t num(0); int num1(0); int type; CMemTools mem(p); mem.read(&type); mem.read(&_spType); mem.read(&num); for (size_t i(0); i < num; ++i) _fitPts.push_back(mem.read_point()); mem.read(&_tangentsExist); _startTangent = mem.read_point(); _endTangent = mem.read_point(); mem.read(&_knotParam); mem.read(&_degree_fit); mem.read(&_fitTolerance); mem.read(&num); for (size_t i(0); i < num; ++i) _controlPts.push_back(mem.read_point()); mem.read(&_degree_nurb); mem.read(&_rational); mem.read(&_closed); mem.read(&_periodic); mem.read(&num1); _knots.setLogicalLength(num1); mem.read(_knots.asArrayPtr(), num1); mem.read(&num1); _weights.setLogicalLength(num1); mem.read(_weights.asArrayPtr(), num1); mem.read(&_controlPtTol); mem.read(&_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(&_type); size_t num(_profile.size()); mem.write(&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(&type); size_t num(0); mem.read(&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 crvs; asDbCurve(crvs); if (!crvs.empty()) pCrv = (AcDbCurve *)crvs[0]->clone(); deleteContainerOfStd(crvs); return pCrv; } void region::asDbCurve(std::vector &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 ®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 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 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 ®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 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(); } }