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

3899 lines
76 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : 内部全局函数实现文件
// = Version : ver2.0
// = Author :
// = CreateDate : 2002-09-09
// = Description: 全局函数的声明
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "XPrivateGlobalFunc.h"
#include "XCurveObjectEx.h"
#include "SymbolTable.h"
#include "AecDbPolyCurveEnt.h"
#include "XPushVar.h"
#include "XPushMemVar.h"
#include "CHole.h"
#include "IdPointPair.h"
#include "XSortSideOnVertex.h"
#include "XSearchRegionFromCurve.h"
#include "XRemoveDupByLayer.h"
#include "DList.h"
#include "XCurveObject.h"
#include "SearchException.h"
#include "DupWallException.h"
#include "PickSet.h"
#include "XLineDist.h"
#include "XExplodeStream.h"
#include "WPushVar.h"
#include "XBlockTableRecPtr.h"
#include "imgdef.h"
#include "imgent.h"
#include "XTrianglePface.h"
#include "AString.h"
#include "UString.h"
#include "XConfigBase.h"
#include "XGlobalCurveFunc.h"
#include "XCurveInline.h"
static TCHAR Are_appname[] = _T("_XG_HVAC");
// flag: TURE--add head; FALSE--add tail
static void add_2_rblist(struct resbuf **tagdata, struct resbuf *n, int flag)
{
struct resbuf *tmptr;
if(flag)
{
tmptr = AT_link_list(n, *tagdata);
}
else
{
tmptr = AT_link_list(*tagdata, n);
}
*tagdata = tmptr;
}
BOOL XPrivate::SkipSubErase(const TCHAR *szCmd)
{
const TCHAR *szSkip[] =
{
_T("UNDO"),
_T("U"),
_T("REDO"),
_T("BLOCK"),
_T("-BLOCK"),
_T("BMAKE"),
_T("WBLOCK"),
_T("REFCLOSE"),
};
int num = ELEMENTS(szSkip);
for (int i = 0; i < num; i++)
{
if (_tcsicmp(szCmd, szSkip[i]) == 0)
{
return TRUE;
}
}
return FALSE;
}
int XPrivate::CompareObjectId(const AcDbObjectId *id1, const void *id2)
{
if (*id1 == *(const AcDbObjectId *)id2)
{
return 0;
}
return 1;
}
int XPrivate::CompareObjectId(const AcDbSoftPointerId *id1, const void *id2)
{
if (*id1 == *(const AcDbSoftPointerId *)id2)
{
return 0;
}
return 1;
}
PGroups XPrivate::VBuildList(int *parguments)
{
PGroups list = NULL;
PGroups cur = NULL;
char *PArguments = (char *)parguments;
int type;
int code = *(int *)PArguments;
#ifdef _WIN64
PArguments += sizeof(void*);
#else
PArguments += sizeof(int);
#endif
while (code)
{
if (code == RTDXF0)
{
code = 0;
}
if (code > -5 && code < 1072 )
{
if (!cur)
{
list = cur = (PGroups)ads_newrb(code);
}
else
{
cur->next = (PGroups)ads_newrb(code);
cur = cur->next;
}
if (!cur)
{
Release(list);
ApplicationError(_T("\nError in fuction BuildList.No enough memory.\n"));
}
cur->next = NULL;
cur->type = code;
type = TypeOfCode(code);
if (type == RTENAME || type == RTPICKS)
{
memcpy(cur->adsName,*(ads_name**)PArguments,sizeof(ads_name));
//(*(ADSName *)cur->adsName) = **(ADSName **)PArguments;
PArguments += sizeof(void *);
}
else if (type == RT3DPOINT || type == RTPOINT)
{
(*(XPoint *)cur->point) = **(XPoint **)PArguments;
PArguments += sizeof(void *);
}
else if (type == RTSTR)
{
cur->string = _tcsdup(*(TCHAR **)PArguments);
PArguments += sizeof(void *);
}
else if (type == RTSHORT)
{
cur->shortInt = *(HALF_PTR*)PArguments;
#ifdef _WIN64
PArguments += sizeof(void*);
#else
PArguments += sizeof(int);
#endif
}
else if (type == RTREAL || type == RTANG || type == RTORINT)
{
cur->real = *(ads_real *)PArguments;
#ifdef _WIN64
PArguments += sizeof(void*);
#else
PArguments += sizeof(ads_real);
#endif
}
else if (type == RTLONG)
{
cur->longInt = *(long *)PArguments;
#ifdef _WIN64
PArguments += sizeof(void*);
#else
PArguments += sizeof(long);
#endif
}
else
{
ads_abort(_T("Bad Type"));
}
code = *(int *)PArguments;
#ifdef _WIN64
PArguments += sizeof(void*);
#else
PArguments += sizeof(int);
#endif
}
else
{
Release(list);
ApplicationError(_T("\nError in fuction BuildList.Undocumented DXFcode. code=%d\n"),code);
return NULL;
}
}
return list;
}
ads_real XPrivate::GetXDirection(const XCurveSegment &cv1, const XCurveSegment &cv2, const XPoint &ptLoc)
{
ads_real nRes = 0.0;
if (cv1.Is(CURVE_ARC))
{
nRes = cv1.Direction(ptLoc);
}
else if (cv2.Is(CURVE_ARC))
{
nRes = cv2.Direction(ptLoc);
}
else
{
ads_real nDrt1 = cv1.Direction(ptLoc);
ads_real nDrtRev1 = CT_std_angle(nDrt1 + PI);
XSector sec1(nDrt1, nDrtRev1);
ads_real nRes1 = *sec1.NearAngle(0.0);
ads_real nDrt2 = cv2.Direction(ptLoc);
ads_real nDrtRev2 = CT_std_angle(nDrt2 + PI);
XSector sec2(nDrt2, nDrtRev2);
ads_real nRes2 = *sec2.NearAngle(0.0);
XSector sec(nRes1, nRes2);
nRes = *sec.NearAngle(0.0);
}
return nRes;
}
//不判断顶点
int XPrivate::HitTestOnEdge(const AcDbFace *pFace, XPoint pt, bool bDiscardHideEdge)
{
pt.z = 0;
for (int i = 0; i < 4; i++)
{
Adesk::Boolean bVisible = Adesk::kTrue;
pFace->isEdgeVisibleAt(i, bVisible);
if (bDiscardHideEdge && !bVisible)
{
continue;
}
int iNext = DePeriod(4, i + 1);
XLine ln;
AcGePoint3d pt1, pt2;
pFace->getVertexAt(i, pt1);
pFace->getVertexAt(iNext, pt2);
ln.SetStartPoint(pt1);
ln.SetEndPoint(pt2);
ln.SetElevation(0.0);
if ((pt & ln) == PR_INSIDE)
{
return i;
}
}
return -1;
}
AcGeMatrix3d XPrivate::BlockTransform(const AcDbBlockReference *pInsert)
{
AcGePoint3d ptBase, ptInsert = pInsert->position();
AcGeScale3d s = pInsert->scaleFactors();
double rot = pInsert->rotation();
AcDbObjectId idBlock = pInsert->blockTableRecord();
AcDbBlockTableRecord *pBlock = NULL;
// 打开的时候碰到有打不开的情况(如对象被删除了的情况),因此要支持删除的也能打开,并且对指针判断 ---wyg20090710
// acdbOpenObject(pBlock, idBlock, AcDb::kForRead);
// ASSERT(pBlock);
acdbOpenObject(pBlock, idBlock, AcDb::kForRead, true);
if (NULL != pBlock)
{
ptBase = pBlock->origin();
pBlock->close();
}
AcGeMatrix3d result = pInsert->blockTransform();
// 先移动base到原点, Scale, Rotation, 再平移到insPt
AcGeMatrix3d mvMat1;
mvMat1.setToTranslation(AcGeVector3d(-ptBase.x, -ptBase.y, -ptBase.z));
result.postMultBy(mvMat1);
return result;
}
void XPrivate::_RemoveDupCurves(DList<XCurveSegment> &lstCurves)
{
//初始化消除重线的集合
int len = lstCurves.Length();
DList<XCurveObjectEx> lstNewCurves;
for (int i = 0; i < len; i++)
{
XCurveSegment &seg = *lstCurves[i];
if (seg.GetLength() < _DIST_SNAP) //太短了
{
continue;
}
lstNewCurves.Append(new XCurveObjectEx(seg));
}
len = lstNewCurves.Length();
if (g_bEchoSearch)
{
XString sMsg(256);
sMsg << _T("对") << len << _T("条线进行消除重线");
acedSetStatusBarProgressMeter(sMsg, 0, len);
}
int nStep = len / 100;
if (nStep < 1)
{
nStep = 1;
}
for (int i = 0; i < len; i++)
{
if (g_bEchoSearch && !(i % nStep))
{
acedSetStatusBarProgressMeterPos(i);
}
XCurveObjectEx &line1 = *lstNewCurves[i];
if (line1.IsDeleted())
{
continue;
}
BOOL bIsLine1 = line1.Is(CURVE_LINE);
for (int j = 0; j < len; j++)
{
XCurveObjectEx &line2 = *lstNewCurves[j];
if (j == i)
{
continue;
}
if (line2.IsDeleted() || bIsLine1 != line2.Is(CURVE_LINE))
{
continue; // 线2已经被删除或者两线类型不匹配
}
BOOL bPossibleDup = FALSE;
XArc ar1, ar2;
if (bIsLine1) //对于LINE类型
{
XVector3D vt1 = line1.GetStartPoint() - line1.GetEndPoint(), //向量1
vt2 = line2.GetStartPoint() - line2.GetEndPoint(); //向量2
ads_real len1 = vt1.Length(),
len2 = vt2.Length();
if (len1 > 1.0E-6)
{
vt1.Scale(1.0 / len1);
}
if (len2 > 1.0E-6)
{
vt2.Scale(1.0 / len2);
}
double nSweepAng = acos(vt1 & vt2); //单位向量的点积确定夹角
//同一方向, 旧的算法没有考虑夹角精度
bPossibleDup = (nSweepAng < _angSnap || fabs(PI - nSweepAng) < _angSnap);
}
else //对于Arc/Circle类型
{
if (line1.Is(CURVE_ARC))
{
ar1 = line1.GetArc();
}
else
{
(XCircle &)ar1 = line1.GetCircle();
ar1.SetStarAngle(0.0);
ar1.SetEndAngle(PI * 2.0);
}
if (line2.Is(CURVE_ARC))
{
ar2 = line2.GetArc();
}
else
{
(XCircle &)ar2 = line2.GetCircle();
ar2.SetStarAngle(0.0);
ar2.SetEndAngle(PI * 2.0);
}
bPossibleDup = (ar1.GetCenterPt().Distance(ar2.GetCenterPt()) < _DIST_SNAP && fabs(ar1.GetRadius() - ar2.GetRadius()) < _DIST_SNAP);
if (bPossibleDup)
{
if (line1.Is(CURVE_CIRCLE))
{
line2.m_bDel = TRUE;
continue;
}
if (line2.Is(CURVE_CIRCLE))
{
line1 = line2;
line2.m_bDel = TRUE;
continue;
}
}
}
if (bPossibleDup)
{
int flg = bIsLine1 ? (line2.GetStartPoint() & line1) : ar1.AngleFlag(ar2.GetStarAngle());
int flg1 = bIsLine1 ? (line2.GetEndPoint() & line1) : ar1.AngleFlag(ar2.GetEndAngle());
if (flg == PR_ONPT1 || flg == PR_ONPT2 || flg == PR_INSIDE)
{
// 线2起点在线1内(包括端点)
line2.m_bDel = TRUE; //线2要合并到线1内
if (!bIsLine1 || flg1 == PR_EXTEND)
{
// 线2的终点在线1的延长线上, 判断在起始延长还是终止延长
if (bIsLine1)
{
double *pNearPoint = line1.NearPoint(line2.GetEndPoint());
BOOL bIncludeLine1Start = (pNearPoint == &(line1.StartPoint().x));
if (bIncludeLine1Start) //线1的起点在线2内
{
line1.StartPoint() = line2.GetEndPoint(); //因此改变线1的起点
}
else
{
line1.SetEndPoint(line2.GetEndPoint()); //否则线1的终点在线2内,因此改变线1的终点
}
}
else
{
if (flg1 == PR_INSIDE) //需要判断是否构成封闭的圆
{
if (ar2.AngleFlag(ar1.GetStarAngle()) == PR_INSIDE) //ar1变成圆
{
(XCurveSegment &)line1 = XCircle(ar1.GetCenterPt(), ar1.GetRadius());
}
}
else if (flg1 != PR_OUTSIDE) //Add this 2 lines on 2003/12/15
{
(XCurveSegment &)line1 = XCircle(ar1.GetCenterPt(), ar1.GetRadius());
}
else
{
ar1.SetEndAngle(ar2.GetEndAngle());
(XCurveSegment &)line1 = ar1;
}
}
}
else
{
// 否则线2整个位于线1内部, 仅仅删除就可以了
ASSERT(bIsLine1);
}
}
else if (flg1 == PR_ONPT1 || flg1 == PR_ONPT2 || flg1 == PR_INSIDE)
{
// 线2终点线1内(包括端点)
line2.m_bDel = TRUE;
if (!bIsLine1 || flg == PR_EXTEND)
{
// 线2的起点在线1的延长线上, 判断在起始延长还是终止延长
if (bIsLine1)
{
double *pNearPoint = line1.NearPoint(line2.GetStartPoint());
if (pNearPoint == &(line1.StartPoint().x))
{
line1.SetStartPoint(line2.GetStartPoint());
}
else
{
line1.SetEndPoint(line2.GetEndPoint());
}
}
else
{
ar1.SetStarAngle(ar2.GetStarAngle());
(XCurveSegment &)line1 = ar1;
}
}
else
{
// 否则线2整个位于线1内部, 仅仅删除就可以了
ASSERT(bIsLine1);
}
}
else if (bIsLine1 && (flg == PR_EXTEND && flg1 == PR_EXTEND)) //线2的两端都在线一的外边
{
int flg2 = bIsLine1 ? (line1.GetStartPoint() & line2) : ar2.AngleFlag(ar1.GetStarAngle());
if (flg2 == PR_INSIDE)
{
line1.SetStartPoint(line2.GetStartPoint());
line1.SetEndPoint(line2.GetEndPoint());
line2.m_bDel = TRUE;
}
}
}
}
}
lstCurves.Reset();
for (int i = 0; i < len; i++)
{
XCurveObjectEx &ln = *lstNewCurves[i];
if (!ln.IsDeleted())
{
lstCurves.Append(new XCurveSegment(ln));
}
}
if (g_bEchoSearch)
{
acedRestoreStatusBar();
}
}
int XPrivate::GetApplicationPath(TCHAR *vPath,HINSTANCE hInstance)
{
TCHAR fileName[128] = _T("");
GetModuleFileName(hInstance, fileName, 127);
TCHAR drive[_MAX_DRIVE] = _T(""), dir[_MAX_DIR] = _T(""), fname[_MAX_FNAME] = _T(""),
ext[_MAX_EXT] = _T("");
_tsplitpath(fileName, drive, dir, fname, ext);
_tcscpy(vPath, drive);
_tcscat(vPath, dir);
return 1;
}
int XPrivate::AT_get_cirarcp(ads_name arc_ent, ads_point cent, ads_real *rad, ads_real *sang, ads_real *eang)
{
struct resbuf *res2, *rb1;
res2 = ads_entget(arc_ent);
rb1 = AT_get_resbuf(res2,0);
if (_tcscmp(rb1->resval.rstring,_T("ARC")) != 0
&& _tcscmp(rb1->resval.rstring,_T("CIRCLE")) != 0)
{
ads_relrb(res2);
return RTERROR;
}
rb1 = AT_get_resbuf(res2,10);
cent[X] = rb1->resval.rpoint[X];
cent[Y] = rb1->resval.rpoint[Y];
cent[Z] = rb1->resval.rpoint[Z];
rb1 = AT_get_resbuf(res2,40);
*rad = rb1->resval.rreal;
rb1 = AT_get_resbuf(res2,0);
if ( _tcscmp(rb1->resval.rstring,_T("ARC")) == 0)
{
rb1 = AT_get_resbuf(res2,50);
*sang = rb1->resval.rreal;
rb1 = AT_get_resbuf(res2,51);
*eang = rb1->resval.rreal;
ads_relrb(res2);
return 1;
}
if ( _tcscmp(rb1->resval.rstring,_T("CIRCLE")) == 0)
{
ads_relrb(res2);
*sang = 0.0;
*eang = 2.0 * PI;
return 1;
}
return RTERROR;
}
int XPrivate::operator == (XStringList &strs1, XStringList &strs2)
{
if (strs1.Length() != strs2.Length())
{
return 0;
}
int len = strs1.Length();
for (int i = 0; i < len; i++)
{
if (_tcscmp(strs1[i], strs2[i]) == 0)
{
;
}
else
{
return 0;
}
}
return 1;
}
void XPrivate::ThickPoly2Face(XMasterProperties prop, const XPoly2D &poly, XPoint vtNormal, double nThick,
AcDbVoidPtrArray &entSet, AcGeMatrix3d *pMatTran)
{
ASSERT(nThick > _DIST_SNAP);
if (nThick > _DIST_SNAP && poly.Length())
{
XPoly polygon;
poly.AsOpenPoly1(polygon, _AS_SYS_UNIT(g_nCirDeviation));
int nSeg = polygon.Length() - 1;
for (int n = 0; n < nSeg; n++)
{
XPoint verts[4];
verts[0] = *polygon[n];
verts[1] = *polygon[n+1];
verts[2] = verts[1];
verts[2].z += nThick;
verts[3] = verts[0];
verts[3].z += nThick;
AcDbFace *pFace = new AcDbFace;
for (int idx = 0; idx < 4; idx++)
{
XPoint ptVert = Ecs2Wcs(verts[idx], vtNormal);
if (pMatTran)
{
((AcGePoint3d &)ptVert).transformBy(*pMatTran);
}
pFace->setVertexAt(idx, ptVert);
}
prop.SetTo(pFace);
entSet.append(pFace);
}
// Modify on 2004/4/6, 增加顶面和底面
if (poly.IsClosed() && g_bSlabThickPolyline)
{
XPoly2D polyBot(poly), polyTop(poly);
polyBot.Reverse();
polyTop.SetElevation(poly.Head()->z + nThick);
XExplodeStream dc(entSet);
DList<XPoly2D> emptyHole;
dc.DrawShell(polyBot, emptyHole);
dc.DrawShell(polyTop, emptyHole);
}
}
}
// 画拉伸圆
void XPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XCircle &cir, ads_real nHeight)
{
AcDbPolyline line;
line.setElevation(cir.GetCenterPt().z);
line.setThickness(nHeight);
XPoint ptStart, ptEnd;
ads_polar(cir.GetCenterPt(), 0.0, cir.GetRadius(), ptStart);
ads_polar(cir.GetCenterPt(), PI, cir.GetRadius(), ptEnd);
line.addVertexAt(0, ptStart, tan(PI / 4.0));
line.addVertexAt(1, ptEnd, tan(PI / 4.0));
line.setClosed(Adesk::kTrue);
if (pWd)
{
line.worldDraw(pWd);
}
else
{
line.viewportDraw(pVd);
}
}
// 显示3d弧段
// 参数: pWd, pVd -- 必须有一个非NULL
// ar -- 待显示的弧段
// nHeight -- 厚度
// bShowStart -- 是否绘制起始边界线
// bShowEnd -- 是否绘制终止边界线
void XPrivate::DrawArcSeg(XExplodeDraw &dc, const XArc &ar, ads_real nHeight, int bShowStart, int bShowEnd)
{
// Modify on 2002/4/12 by , 避免大圆弧的出现
if (ar.Bulge() > 2 * PI - _angSnap || ar.GetLength() < _DIST_SNAP)
{
return;
}
if (_tcsicmp(dc.Desc(), XExplodeStream::Descriptor()) == 0)
{
dc.DrawArc(ar, nHeight);
return; //希望有渐变线
}
int nCirDiv = GetCirDivNum(ar.GetRadius(), _AS_SYS_UNIT(g_nCirDeviation));
ads_real intAng = fabs(ar.Bulge());
int n = AS_INT(intAng / PI / 2.0 * nCirDiv); //一个圆分解为50份
if (n < 1)
{
n = 1;
}
ads_real ang = intAng / n;
int nVertexNum = 2 * n + 2;
XPoint *ptArray = new XPoint[nVertexNum];
for (int i = 0; i < n + 1; i++)
{
ads_real drt = ar.GetStarAngle() + i * ang;
ads_polar(ar.GetCenterPt(), drt, ar.GetRadius(), ptArray[i]);
ptArray[i + n + 1] = ptArray[i];
ptArray[i + n + 1].z += nHeight;
}
AcGiEdgeData edge;
Adesk::UInt8 *visibleData = new Adesk::UInt8[3 * n + 1];
for (int j = 0; j < 2 * n; j++)
{
visibleData[j] = kAcGiVisible;
}
visibleData[2 * n] = bShowStart ? kAcGiVisible:kAcGiInvisible;
visibleData[3 * n] = bShowEnd ? kAcGiVisible:kAcGiInvisible;
for (int j = 2 * n + 1; j < 3 * n; j++)
{
visibleData[j] = kAcGiInvisible;
}
edge.setVisibility(visibleData);
dc.DrawMesh(2, n + 1, (AcGePoint3d *)ptArray, &edge);
delete [] ptArray;
delete [] visibleData;
}
// 显示3d线段
// 参数: pWd, pVd -- 必须有一个非NULL
// ln -- 待显示的线段
// nHeight -- 厚度
// bShowStart -- 是否绘制起始边界线
// bShowEnd -- 是否绘制终止边界线
void XPrivate::DrawLineSeg(XExplodeDraw &dc, const XLine &ln,
ads_real nHeight, int bShowStart, int bShowEnd)
{
int nVertexNum = 4;
XPoint *ptArray = new XPoint[nVertexNum];
ptArray[0] = ln.GetStartPoint();
ptArray[1] = ln.GetEndPoint();
ptArray[2] = ln.GetStartPoint();
ptArray[2].z += nHeight;
ptArray[3] = ln.GetEndPoint();
ptArray[3].z += nHeight;
AcGiEdgeData edge;
Adesk::UInt8 *visibleData = new Adesk::UInt8[4];
for (int j = 0; j < 2; j++)
{
visibleData[j] = kAcGiVisible;
}
visibleData[2] = bShowStart ? kAcGiVisible : kAcGiInvisible;
visibleData[3] = bShowEnd ? kAcGiVisible : kAcGiInvisible;
edge.setVisibility(visibleData);
dc.DrawMesh(2, 2, (AcGePoint3d *)ptArray, &edge);
delete [] ptArray;
delete [] visibleData;
}
//绘制二维直线
void XPrivate::DrawLineSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XLine &ln)
{
AcGePoint3d line[2] = {ln.GetStartPoint(), ln.GetEndPoint()};
if (pWd)
{
pWd->geometry().polyline(2, line);
}
else
{
pVd->geometry().polyline(2, line);
}
}
//绘制二维弧线
void XPrivate::DrawArcSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XArc &ar)
{
XPoint ptStart, ptEnd, ptMid;
ar.GetStartPoint(ptStart);
ar.GetEndPoint(ptEnd);
ar.MidPoint(ptMid);
if (pWd)
{
pWd->geometry().circularArc(ptStart, ptMid, ptEnd);
}
else
{
pVd->geometry().circularArc(ptStart, ptMid, ptEnd);
}
}
// 绘制二维圆
void XPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XCircle &cir)
{
if (pWd)
{
pWd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0,0.0,1.0));
}
else
{
pVd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0,0.0,1.0));
}
}
void XPrivate::AsPolyline(const AcDbLine &line, AcDbPolyline &pline)
{
pline.reset(Adesk::kFalse, 0);
pline.setPropertiesFrom(&line);
XVector3D vtNormal;
(AcGeVector3d &)vtNormal = line.normal();
XPoint ptStart = Wcs2Ecs(line.startPoint(), vtNormal),
ptEnd = Wcs2Ecs(line.endPoint(), vtNormal);
pline.addVertexAt(0, ptStart);
pline.addVertexAt(1, ptEnd);
pline.setNormal(line.normal());
pline.setElevation(ptStart.z);
double nThick = line.thickness();
pline.setThickness(nThick);
}
void XPrivate::AsPolyline(const AcDbArc &line, AcDbPolyline &pline)
{
pline.reset(Adesk::kFalse, 0);
XPoint vtNormal;
(AcGeVector3d &)vtNormal = line.normal();
XPoint ptCen = Wcs2Ecs(line.center(), vtNormal);
XArc ar(ptCen, line.radius(), line.startAngle(), line.endAngle());
pline.setPropertiesFrom(&line);
XPoint ptStart, ptEnd;
ar.GetStartPoint(ptStart);
ar.GetEndPoint(ptEnd);
pline.addVertexAt(0, ptStart, tan(ar.Bulge() / 4.0));
pline.addVertexAt(1, ptEnd);
pline.setNormal(line.normal());
double nThick = line.thickness();
pline.setElevation(ptCen.z);
pline.setThickness(nThick);
}
void XPrivate::AsPolyline(const AcDbCircle &line, AcDbPolyline &pline)
{
XPoint vtNormal;
(AcGeVector3d &)vtNormal = line.normal();
XPoint ptCen = Wcs2Ecs(line.center(), vtNormal);
XCircle cir(ptCen, line.radius());
XCurveSegment seg;
seg = cir;
XPoly2D poly;
seg.AsPoly2D(poly);
PolyConvert(poly, pline);
pline.setPropertiesFrom(&line);
pline.setNormal(line.normal());
pline.setElevation(ptCen.z);
double nThick = line.thickness();
pline.setThickness(nThick);
}
int XPrivate::CompNodeByEqual(const XSortWallOnPt *p1, const void *p2)
{
if (p1 == p2)
{
return 0;
}
return 1;
}
int XPrivate::AT_in_arc(ads_point pt, ads_point cenpt, ads_real rad, ads_real ang1, ads_real ang2)
{
ads_real ang;
int tag;
ads_point ptStart, ptEnd;
if ( fabs(pt[2]-cenpt[2]) > _DIST_SNAP || fabs(ads_distance(cenpt,pt) - rad) > _DIST_SNAP )
{
return 0;
}
ang = ads_angle(cenpt,pt);
ads_polar(cenpt, ang1, rad, ptStart);
ads_polar(cenpt, ang2, rad, ptEnd);
if (ads_distance(ptStart, pt) < _DIST_SNAP)
{
return 1;
}
if (ads_distance(ptEnd, pt) < _DIST_SNAP)
{
return 2;
}
if (ang1 < ang2 )
{
if (ang > ang1 && ang < ang2)
{
tag = 3;
}
else
{
tag = 0;
}
}
else
{
if (ang > ang1 || ang < ang2)
{
tag = 3;
}
else
{
tag = 0;
}
}
return tag;
}
// 点到线的投影
// src_pt -- 源点
// cl_pt1, cl_pt2 -- 投影线
// dest_pt -- 投影点
// 返回值:
// RTNOMR -- 正常
// RTERROR -- 错误
// Modify by Z on 2002/1/5, return RTNORM always
int XPrivate::AT_pt_ProjectLine(ads_point src_pt, ads_point cl_pt1, ads_point cl_pt2, ads_point dest_pt)
{
//modify by zjq 100613 取消AcGe算法,速度慢
//AcGeLine3d lineT(asPnt3d(cl_pt1),asPnt3d(cl_pt2));
//AcGePointOnCurve3d ptOnCr;
//lineT.getClosestPointTo(asPnt3d(src_pt),ptOnCr);
//asPnt3d(dest_pt) = ptOnCr.point3d();
//return RTNORM;
struct plan_para plan;
XVector3D vt;
CT_Vector(cl_pt1, cl_pt2, vt);
dest_pt[0]=src_pt[0];
dest_pt[1]=src_pt[1];
dest_pt[2]=src_pt[2];
if(CT_plan_equation(src_pt, vt, &plan))
{
CT_inter_line_plan1(cl_pt1, cl_pt2, &plan, dest_pt);
}
return RTNORM;
}
// 计算点到线的距离
// pt1, pt2 -- 指定线上的两点
// pt0 -- 指定点
// 返回值: 点到线的距离
ads_real XPrivate::AT_Dist_PtLine2(ads_point pt0, ads_point pt1,ads_point pt2)
{
//modify by zjq 100613 取消AcGe算法,速度慢
//AcGeLine3d lineT(asPnt3d(pt1),asPnt3d(pt2));
//AcGePointOnCurve3d ptOnCr;
//lineT.getClosestPointTo(asPnt3d(pt0),ptOnCr);
//return ptOnCr.point3d().distanceTo(asPnt3d(pt0));
ads_point pt4;
AT_pt_ProjectLine(pt0, pt1, pt2, pt4);
double dist = ads_distance(pt0, pt4);
return dist;
}
// 点与线的位置关系
// pt1, pt2 -- 线的两个端点
// pt -- 指定点
// 返回值:
// 0 -- 线外; 1 -- 在端点line_pt1上;
// 2 -- 在端点line_pt2上; 3 -- 线上.
// 4 -- 延长线上;
int XPrivate::AT_in_line(ads_point pt, ads_point line_pt1,ads_point line_pt2)
{
ads_real snap0 = _DIST_SNAP;
ads_point vt1, vt2;
if (XPrivate::AT_Dist_PtLine2(pt, line_pt1, line_pt2) > snap0)
{
return 0;
}
CT_Vector(pt, line_pt1, vt1);
CT_Vector(pt, line_pt2, vt2);
if (fabs(vt1[0]) <= snap0 && fabs(vt1[1]) <= snap0 && fabs(vt1[2]) <= snap0)
{
return 1;
}
if (fabs(vt2[0]) <= snap0 && fabs(vt2[1]) <= snap0 && fabs(vt2[2]) <= snap0)
{
return 2;
}
if (CT_RealEqual(CT_VectorAngle(vt1, vt2), 0, _angSnap) )
{
return 4;
}
if (CT_RealEqual(CT_VectorAngle(vt1, vt2), PI, _angSnap) )
{
return 3;
}
return 0;
}
double XPrivate::GetPolygonDist(const XPolygonEx &poly1, const XPolygonEx &poly2)
{
int nIndex1 = 0;
int num1 = poly1.Length();
int nIndex2 = 0; //poly2与pt最近的顶点
double nMinDist = 0.0;
int num2 = poly2.Length();
for (int j = 0; j < num1; j++)
{
XPoint pt = poly1[j];
for (int i = 0; i < num2; i++)
{
double nDist = pt.Distance(poly2[i]);
if (i == 0 && j == 0)
{
nMinDist = nDist;
}
else if (nDist < nMinDist)
{
nMinDist = nDist;
nIndex2 = i;
nIndex1 = j;
}
}
}
return nMinDist;
}
BOOL XPrivate::IsEqual(const AcGePoint3d pt11,const AcGePoint3d pt12,const AcGePoint3d pt21,const AcGePoint3d pt22,double tol)
{
if ((XPrivate::IsEqual(pt11,pt21,tol) && XPrivate::IsEqual(pt12,pt22,tol))
|| (XPrivate::IsEqual(pt11,pt22,tol) && XPrivate::IsEqual(pt12,pt21,tol)))
{
return 1;
}
else
{
return 0;
}
}
BOOL XPrivate::IsOverlap(AcGePoint3d& pt11,AcGePoint3d& pt12,AcGePoint3d& pt21,AcGePoint3d& pt22)
{
AcGeLine3d line(pt11,pt12);
AcGeTol tol1;
tol1.setEqualPoint(TOL);
if (line.isOn(pt21,tol1) && line.isOn(pt22,tol1))
{
return 1;
}
else
{
return 0;
}
}
int XPrivate::PtAtWhichSide(const AcGePoint3d& pt0,const AcGePoint3d& pt1,const AcGePoint3d& pt2,double tol)
{
AcGePoint3d pt00, pt11, pt22;
double L01, L02, L12, Lmax;
L01 = pt0.distanceTo(pt1);
L02 = pt0.distanceTo(pt2);
L12 = pt1.distanceTo(pt2);
if (L01 <= TOL || L02 <= TOL || L12 < TOL)
{
return 0;
}
if (L01 >= L02)
{
if (L02 >= L12)
{
pt00 = pt0;
pt11 = pt1;
pt22 = pt2;
}
else if (L01 >= L12)
{
pt00 = pt1;
pt11 = pt0;
pt22 = pt2;
}
else
{
pt00 = pt1;
pt11 = pt2;
pt22 = pt0;
}
}
else
{
if (L01 >= L12)
{
pt00 = pt0;
pt11 = pt2;
pt22 = pt1;
}
else if (L02 >= L12)
{
pt00 = pt2;
pt11 = pt0;
pt22 = pt1;
}
else
{
pt00 = pt2;
pt11 = pt1;
pt22 = pt0;
}
}
double Ang1, Ang2, DltAng, DltAng_TOL;
Lmax = max(L01, L02);
Lmax = max(Lmax, L12);
DltAng_TOL = tol / Lmax;
Ang1 = AngleToX(pt00, pt11);
Ang2 = AngleToX(pt00, pt22);
while (Ang1 >= 2.0 * PI)
{
Ang1 -= 2.0 * PI;
}
while (Ang1 < 0)
{
Ang1 += 2.0 * PI;
}
while (Ang2 >= 2.0 * PI)
{
Ang2 -= 2.0 * PI;
}
while (Ang2 < 0)
{
Ang2 += 2.0 * PI;
}
DltAng = fabs(Ang2 - Ang1);
if (fabs(DltAng) <= DltAng_TOL || fabs(DltAng - 2.0 * PI) <= DltAng_TOL || fabs(DltAng - PI) <= DltAng_TOL)
{
return 0;
}
double s = 0;
s = pt0.x * (pt1.y - pt2.y) + pt1.x * (pt2.y - pt0.y) + pt2.x * (pt0.y - pt1.y);
if (s > 0)
{
return 1;
}
else
{
return 2;
}
}
//三角化
BOOL XPrivate::Triangulate(const DList<XPoly2D> &lstHole,DList<XTriangle> &lstRes)
{
CHole hole;
if (hole.ConstructEdgeList(lstHole))
{
return (hole.GetTriangles(lstRes));
}
return FALSE;
}
BOOL XPrivate::Triangulate(const DList<XPolygonEx> &lstHole,DList<XTriangle> &lstRes)
{
CHole hole;
if (hole.ConstructEdgeList(lstHole))
{
return (hole.GetTriangles(lstRes));
}
return FALSE;
}
BOOL XPrivate::Triangulate(const XPoly2D &out,const DList<XPoly2D> &lstHole,DList<XTriangle> &lstRes)
{
CHole hole;
if (hole.ConstructEdgeList(out,lstHole))
{
return hole.GetTriangles(lstRes);
}
return FALSE;
}
BOOL XPrivate::Triangulate(const XPolygonEx &out, const DList<XPoly2D> &lstHole, DList<XTriangle> &lstRes)
{
CHole hole;
if (hole.ConstructEdgeList(out,lstHole))
{
return hole.GetTriangles(lstRes);
}
return FALSE;
}
BOOL XPrivate::Triangulate(const XPolygonEx &out, const DList<XPolygonEx> &lstHole, DList<XTriangle> &lstRes)
{
CHole hole;
if (hole.ConstructEdgeList(out,lstHole))
{
return hole.GetTriangles(lstRes);
}
return FALSE;
}
// 区域的减法
// lstPoly2 is inside poly1, but share edges
// lstPoly2都是独立的域,不含孔洞模型
int XPrivate::_Subtract(const XPoly2D &poly1, const DList<XPoly2D> &lstPoly2, DList<XPoly2D> &lstResult)
{
// 首先, poly1对poly2进行裁剪, 取内部
DList<XCurveSegment> lstSeg2, lstSeg2In, lstSeg2Out, lstSeg2Edge ;
for (int n = 0; n < lstPoly2.Length(); n++)
{
const XPoly2D &poly2 = lstPoly2[n];
ExplodePoly2D(poly2, lstSeg2);
}
PolyClip(lstSeg2, (XPoly2D &)poly1, lstSeg2In, lstSeg2Out, lstSeg2Edge);
// 然后, poly2对poly1进行裁剪, 取外部
DList<XCurveSegment> lstSeg1, lstSeg1In, lstSeg1Out, lstSeg1Edge ;
ExplodePoly2D(poly1, lstSeg1);
for (int n = 0; n < lstPoly2.Length(); n++)
{
const XPoly2D &poly2 = lstPoly2[n];
lstSeg1Out.Reset();
PolyClip(lstSeg1, (XPoly2D &)poly2, lstSeg1In, lstSeg1Out, lstSeg1Edge);
lstSeg1.Reset();
for (int k = 0; k < lstSeg1Out.Length(); k++)
{
lstSeg1.Append(new XCurveSegment(*lstSeg1Out[k]));
}
}
//lstSeg2In合并到lstSeg1Out
for (int i = 0; i < lstSeg2In.Length(); i++)
{
lstSeg1Out.Append(new XCurveSegment(*lstSeg2In[i]));
}
DList<XPoly2D> lstTemp(FALSE);
int nRet = SearchRegions(lstSeg1Out, lstTemp);
for (int i = 0; i < lstTemp.Length(); i++)
{
XPoly2D *pTemp = lstTemp[i];
if (pTemp->IsSelfIntersect())
{
delete pTemp;
}
else
{
lstResult.Append(pTemp);
}
}
return nRet;
}
// 8.0补丁暂未使用
// 参考ptRef,判断在外轮廓中,应该减去pt1、pt2中的哪个点
XPoint XPrivate::GetAutoDelPt(XPoint ptRef, XPoint pt1, XPoint pt2)
{
XPoint vecXDir, vecYDir;
xg_getvar(_T("UCSXDIR"), vecXDir);
xg_getvar(_T("UCSYDIR"), vecYDir);
// 当前视图下的Z轴
AcGeVector3d vecZDir = vecXDir.AsAcGeVector3d().crossProduct(vecYDir.AsAcGeVector3d());
AcGePoint3d point1 = pt1.AsAcGePoint3d(),
point2 = pt2.AsAcGePoint3d(),
pointRef = ptRef.AsAcGePoint3d();
AcGeVector3d vec1 = point1 - pointRef,
vec2 = point2 - pointRef;
double dAngle = vec1.angleTo(vec2, vecZDir); // 角度范围为[0, 2PI]
// pt1、pt2距离小于1,角度通常趋近于0或2PI,此判断无需精确度
if (dAngle > PI * 1.5)
{
return pt2;
}
return pt1;
}
BOOL XPrivate::IsPointAtSameSide(const AcGePlane& plane, const AcGePoint3d& pt1, const AcGePoint3d& pt2)
{
if (plane.isOn(pt1) || plane.isOn(pt2))
{
return 1;
}
AcGePoint3d ptPrj1 = pt1.project(plane, plane.normal());
AcGePoint3d ptPrj2 = pt2.project(plane, plane.normal());
if ((pt1 - ptPrj1).isCodirectionalTo(pt2 - ptPrj2))
{
return 2;
}
return 0;
}
#if (ARX>15)
bool XPrivate::RemoveRT_MANIFEST(const TCHAR* fullPath,int resId)
{
HANDLE hUpdateRes = BeginUpdateResource(fullPath,FALSE);
if (hUpdateRes == NULL)
{
return false;
}
if (!UpdateResource(hUpdateRes,RT_MANIFEST,MAKEINTRESOURCE(resId),
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),NULL,NULL))
{
return false;
}
if (!EndUpdateResource(hUpdateRes, FALSE))
{
return false;
}
return true;
}
#endif
XString XPrivate::OsMode2Str(int nMode)
{
XString sMode;
if (nMode & 0x4000)
{
return sMode;
}
if (nMode & 1)
{
sMode << _T("END,");
}
if (nMode & 2)
{
sMode << _T("MID,");
}
if (nMode & 4)
{
sMode << _T("CEN,");
}
if (nMode & 8)
{
sMode << _T("NOD,");
}
if (nMode & 16)
{
sMode << _T("QUA,");
}
if (nMode & 32)
{
sMode << _T("INT,");
}
if (nMode & 64)
{
sMode << _T("INS,");
}
if (nMode & 128)
{
sMode << _T("PER,");
}
if (nMode & 256)
{
sMode << _T("TAN,");
}
if (nMode & 512)
{
sMode << _T("NEA,");
}
int nLen = sMode.Length();
if (nLen)
{
sMode[nLen - 1] = 0;
}
return sMode;
}
BOOL XPrivate::SearchPathFromCurve(const DList<XCurveSegment> &curves, XPoly2D &polyPath)
{
XSearchRegionFromCurve aSearch;
BOOL bInit = TRUE;
try
{
aSearch.InitStart(curves);
}
catch(...)
{
bInit = FALSE;
}
if (!bInit)
{
return FALSE;
}
DList<XSortSideOnVertex> &nodes = XSearchRegionFromCurve::g_lstAllSortSides;
XSortSideOnVertex *pHead = NULL;
XSortSideOnVertex *pTail = NULL;
for (int i = 0; i < nodes.Length(); i++)
{
XSortSideOnVertex &node = *nodes[i];
if (node.Length() > 2 || !node)
{
return FALSE;
}
if (node.Length() == 1)
{
if (!pHead)
{
pHead = &node;
}
else if (!pTail)
{
pTail = &node;
}
else
{
return FALSE;
}
}
}
if (!pHead || !pTail)
{
return FALSE;
}
polyPath.Reset();
polyPath.SetFlag(0);
XSortSideOnVertex *pNode = pHead;
XRegionSide *pLast = NULL;
while (pNode != pTail)
{
XRegionSide *pSide1 = pNode->Head()->m_pSide;
XRegionSide *pSide2 = pNode->Tail()->m_pSide;
XRegionSide *pSide = NULL;
if (!pLast)
{
ASSERT(pSide1 == pSide2);
pSide = pSide1;
}
else if (pSide1 == pLast)
{
pSide = pSide2;
}
else if (pSide2 == pLast)
{
pSide = pSide1;
}
else
{
ASSERT(0);
return FALSE;
}
if (pSide->GetStartNode() == pNode) //正向搜索
{
polyPath.AppendNode(pSide->StartPoint(), pSide->GetBulge());
pNode = pSide->GetEndNode();
}
else //逆向搜索
{
polyPath.AppendNode(pSide->EndPoint(), -pSide->GetBulge());
pNode = pSide->GetStartNode();
}
pLast = pSide;
}
polyPath.AppendNode(pTail->m_ptLoc);
return TRUE;
}
void XPrivate::FixGsView()
{
PersistGsView(NULL);
}
extern Acad::ErrorStatus fromAcDbTextStyle(AcGiTextStyle& style, const AcDbObjectId& AcDbStyleId);
XPoint XPrivate::GetTextExtend(AcDbObjectId idTextStyle, const TCHAR *pszText, double nHeight, BOOL penups)
{
AcGiTextStyle txtStyle;
VERIFY(fromAcDbTextStyle(txtStyle, idTextStyle) == Acad::eOk);
int nRetFlag = txtStyle.loadStyleRec();
txtStyle.setTextSize(nHeight);
AcGePoint2d ptExt = txtStyle.extents(pszText, penups, -1, Adesk::kFalse);
XPoint ptBox;
(AcGePoint2d &)ptBox = ptExt;
return ptBox;
}
void XPrivate::RemoveDupNoXData()
{
XPushMemVar<BOOL> vTemp(g_bEchoSearch, TRUE);
DList<XRemoveDupByLayer> lstRemoveDup;
PickSet ss(SS_FREE);
if (ss.Get(NULL, NULL, NULL, RBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM)
{
long lCount = ss.Length();
for (long i = 0L;i<lCount; i++)
{
Entity ent = ss[i];
XString sLayer(256);
ent.GetData(8, (TCHAR *)sLayer);
XRemoveDupByLayer *pData = lstRemoveDup.FindNode((TCHAR *)sLayer, XRemoveDupByLayer::CompareForFindByLayer);
if (pData)
{
pData->m_lstCurves.Append(new XCurveSegment(ent));
}
else
{
pData = new XRemoveDupByLayer(sLayer);
pData->m_lstCurves.Append(new XCurveSegment(ent));
lstRemoveDup.Append(pData);
}
}
ss.Erase();
for (int n = 0; n<lstRemoveDup.Length(); n++)
{
XRemoveDupByLayer *pData = lstRemoveDup[n];
XGeLib::adsout << _T("\n对图层") << pData->m_sLayer << _T("消除重线: ");
int nOldNum = pData->m_lstCurves.Length();
RemoveDupCurves(pData->m_lstCurves);
XGeLib::adsout << _T("由") << int(nOldNum) << _T("变为") << pData->m_lstCurves.Length();
for (int k = 0; k<pData->m_lstCurves.Length(); k++)
{
pData->m_lstCurves[k]->Make(pData->m_sLayer);
}
}
}
}
void XPrivate::RemoveExactDupLines(DList<XCurveSegment> &lstCurves)
{
//初始化消除重线的集合
int len = lstCurves.Length();
DList<XCurveObject> lstNewCurves;
for (int i = 0; i < len; i++)
{
XCurveSegment &seg = *lstCurves[i];
if (seg.GetLength() < _DIST_SNAP)
{
continue;
}
lstNewCurves.Append(new XCurveObject(seg));
}
len = lstNewCurves.Length();
if (g_bEchoSearch)
{
XString sMsg(256);
sMsg << _T("对") << len << _T("条线进行消除完全重线");
acedSetStatusBarProgressMeter(sMsg, 0, len);
}
int nStep = len / 100;
if (nStep < 1)
{
nStep = 1;
}
for (int i = 0; i < len; i++)
{
if (g_bEchoSearch && !(i % nStep))
{
acedSetStatusBarProgressMeterPos(i);
}
XCurveObject line1 = *lstNewCurves[i];
if (line1.m_bDeleted)
{
continue;
}
ASSERT(line1.Is(CURVE_LINE));
for (int j = 0; j < len; j++)
{
XCurveObject &line2 = *lstNewCurves[j];
if (j == i)
{
continue;
}
if (line2.m_bDeleted)
{
// 线2已经被删除
continue;
}
ASSERT(line2.Is(CURVE_LINE));
if ( (line1.GetStartPoint().Distance2d(line2.StartPoint()) < _DIST_SNAP
&& line1.GetEndPoint().Distance2d(line2.EndPoint()) < _DIST_SNAP)
|| (line1.GetStartPoint().Distance(line2.EndPoint()) < _DIST_SNAP
&& line1.GetEndPoint().Distance2d(line2.StartPoint()) < _DIST_SNAP)
)
{
line2.m_bDeleted = TRUE; //线2要合并到线1内
}
}
}
lstCurves.Reset();
for (int i = 0; i < len; i++)
{
XCurveObject &ln = *lstNewCurves[i];
if (!ln.m_bDeleted)
{
lstCurves.Append(new XCurveSegment(ln));
}
}
if (g_bEchoSearch)
{
acedRestoreStatusBar();
}
}
char* XPrivate::xh2cpy(char *to, char *from, int len)
{
if (!to || !from)
{
exit(0);
}
char *p;
int len1 = strlen(from);
int i = 0;
p = to;
memcpy(to, from, len1);
to[len] = 0;
to += len1;
for (i = len1; i < len; i++)
{
*to++ = ' ';
}
return p;
}
char* XPrivate::xh3cpy(char *to, char *fr, int len)
{
if (!to || !fr)
{
exit(0);
}
char *from;
for (from = fr; *from == ' '; from++)
{
;
}
return XPrivate::xh2cpy(to, from, len);
}
void XPrivate::xh1cpy(char *to, const char *src)
{
if (!to || !src)
{
exit(0);
}
if (!src)
{
*to = 0;
return;
}
char sDup[1000];
strcpy(sDup, src);
char *p = sDup;
while(*p == ' ' || *p == '\t')
{
p++;
}
char *q = &sDup[strlen(sDup)];
while (q != p)
{
q--;
if (*q == ' ' || *q == '\t')
{
*q = 0;
}
else
{
break;
}
}
strcpy(to, p);
}
TCHAR *XPrivate::strnew_delspace(const TCHAR *src)
{
if (!src)
{
exit(0);
}
char tmp[256] = "";
XPrivate::xh1cpy(tmp, _AS(src));
return tstrnew(TString(tmp));
}
int XPrivate::GetPickFirst(PickSet &gSet, PickSet &pSet)
{
resbuf *gset = NULL, *pset = NULL;
int nRet = ads_ssgetfirst(&gset, &pset);
if (gset)
{
if (gset->restype == RTPICKS)
{
PickSet ss0(0);
ss0 = gset->resval.rlname;
gSet += ss0;
ss0.Free();
}
ads_relrb(gset);
}
if (pset)
{
if (pset->restype == RTPICKS)
{
PickSet ss0(0);
ss0 = pset->resval.rlname;
pSet += ss0;
ss0.Free();
}
ads_relrb(pset);
}
return nRet;
}
double XPrivate::GetViewportPScale(int cvport)
{
AcDbBlockTable *pTable = NULL;
acdbCurDwg()->getSymbolTable(pTable, AcDb::kForRead);
if (pTable == NULL)
{
return 0;
}
AcDbBlockTableIterator *pBlockTableIter = NULL;
pTable->newIterator(pBlockTableIter);
pTable->close();
if (pBlockTableIter == NULL)
{
return 0;
}
for (pBlockTableIter->start(); !pBlockTableIter->done(); pBlockTableIter->step())
{
AcDbBlockTableRecord *pRecord = NULL;
pBlockTableIter->getRecord(pRecord, AcDb::kForRead);
if (pRecord == NULL)
{
continue;
}
AcDbBlockTableRecordIterator *pIter = NULL;
pRecord->newIterator(pIter);
pRecord->close();
if (pIter == NULL)
{
continue;
}
for (pIter->start(); !pIter->done(); pIter->step())
{
AcDbEntity*pEnt = NULL;
pIter->getEntity(pEnt,AcDb::kForRead);
if (pEnt != NULL)
{
AcDbViewport*pVP = AcDbViewport::cast(pEnt);
if (pVP != NULL && pVP->number() == cvport)
{
double s = pVP->centerPoint().z;
pEnt->close();
delete pIter;
delete pBlockTableIter;
return s;
}
pEnt->close();
}
}
delete pIter;
}
delete pBlockTableIter;
return 0;
}
int XPrivate::ConnectPolygonsNew(DList<XPolygonEx> &lstPolygons, XPolygonEx &polyEx1)
{
if (!lstPolygons)
{
return RTERROR;
}
polyEx1 = *lstPolygons.Head();
lstPolygons.Remove(0);
LAB_RESTART:
if (!lstPolygons)
{
return RTNORM;
}
XPolyDist minDist;
BOOL bInit = FALSE;
int nIndex = 0;
for (int i = 0; i < lstPolygons.Length(); i++)
{
XPolyDist polyDist;
int nRet = MinDistance(polyEx1, *lstPolygons[i], polyDist);
if (nRet == RTNORM)
{
if (!bInit)
{
minDist = polyDist;
nIndex = i;
bInit = TRUE;
}
else if (minDist.nDist > polyDist.nDist)
{
minDist = polyDist;
int nIndex = i;
}
}
else
{
ASSERT(0);
}
}
if (bInit)
{
XPolygonEx polyEx2;
ConnectPolygon(polyEx1, *lstPolygons[nIndex], minDist, polyEx2);
polyEx1 = polyEx2;
lstPolygons.Remove(nIndex);
goto LAB_RESTART;
}
return RTERROR;
}
int XPrivate::ConnectPolygons(DList<XPolygonEx> &lstPolygons, XPolygonEx &polyEx1)
{
if (!lstPolygons)
{
return RTERROR;
}
polyEx1 = *lstPolygons.Head();
lstPolygons.Remove(0);
LAB_RESTART:
for (int i = 0; i < lstPolygons.Length(); i++)
{
XLine lnConnector;
double nDist = GetConnector(polyEx1, *lstPolygons[i], lnConnector);
if (IsGoodConnector(lnConnector, lstPolygons, i))
{
XPolygonEx polyEx2;
ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2);
polyEx1 = polyEx2;
lstPolygons.Remove(i);
goto LAB_RESTART;
}
}
if (lstPolygons.Length())
{
#ifndef NDEBUG
XGeLib::adsout << _T("\nCan not find good connector!");
#endif
for (int i = 0; i < lstPolygons.Length(); i++)
{
XPolygonEx polyEx2;
ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2);
polyEx1 = polyEx2;
}
}
return RTNORM;
}
void XPrivate::RemoveDup()
{
DList<XRemoveDupEntByLayer> lstRemoveDup;
PickSet ss(SS_FREE);
if (ss.Get(NULL, NULL, NULL, RBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM)
{
long lCount = ss.Length();
for (long i = 0L; i < lCount; i++)
{
Entity ent = ss[i];
XString sLayer(256);
ent.GetData(8, (TCHAR *)sLayer);
XRemoveDupEntByLayer *pData = lstRemoveDup.FindNode((TCHAR *)sLayer, XRemoveDupEntByLayer::CompareForFindByLayer);
if (pData)
{
pData->m_ss += ent;
}
else
{
pData = new XRemoveDupEntByLayer(sLayer);
pData->m_ss += ent;
lstRemoveDup.Append(pData);
}
}
for (int n = 0; n<lstRemoveDup.Length(); n++)
{
XRemoveDupEntByLayer *pData = lstRemoveDup[n];
XGeLib::adsout << _T("\n对图层") << pData->m_sLayer << _T("消除重线: ");
long nOldNum = pData->m_ss.Length();
HandleCurveDup(pData->m_ss);
XGeLib::adsout << _T("由") << int(nOldNum) << _T("变为") << (int)pData->m_ss.Length();
}
}
}
// 判断桥接是否合适,即不和任何边有交点(位于边内)
BOOL XPrivate::IsGoodConnector(const XLine &lnConnector, const XPolygonEx &rPolygon)
{
for (int j = 0; j < rPolygon.Length(); j++)
{
XPoint ptInt;
XLine lnSide(rPolygon.GetVertex(j), rPolygon.GetVertex(j + 1));
if (ads_inters(lnConnector.GetStartPoint(), lnConnector.GetEndPoint(),
lnSide.GetStartPoint(), lnSide.GetEndPoint(), 1, ptInt) == RTNORM)
{
int nHit1 = lnSide.HitTest2d(ptInt);
if (nHit1 == 5) //点在线内
{
return FALSE;
}
}
}
return FALSE;
}
// 取得连接桥
int XPrivate::GetConnector(const XPolygonEx &poly1, const XPolygonEx &poly2, XLine &lnConnector)
{
if (!poly1.Length() || !poly2.Length())
{
ASSERT(0);
return RTERROR;
}
int nIndex1 = 0;
int num1 = poly1.Length();
int nIndex2 = 0; //poly2与pt最近的顶点
double nMinDist = 0.0;
int num2 = poly2.Length();
for (int j = 0; j < num1; j++)
{
XPoint pt = poly1[j];
for (int i = 0; i < num2; i++)
{
double nDist = pt.Distance(poly2[i]);
if (i == 0 && j == 0)
{
nMinDist = nDist;
}
else if (nDist < nMinDist)
{
nMinDist = nDist;
nIndex2 = i;
nIndex1 = j;
}
}
}
lnConnector.SetStartPoint(*poly1[nIndex1]);
lnConnector.SetEndPoint(*poly1[nIndex2]);
return RTNORM;
}
// 判断桥接是否合适
BOOL XPrivate::IsGoodConnector(const XLine &lnConnector, const DList<XPolygonEx> &lstPolygons, int idxExclude)
{
for (int i = 0; i < lstPolygons.Length(); i++)
{
if (i == idxExclude)
{
continue;
}
const XPolygonEx &rPolygon = lstPolygons[i];
if (!XPrivate::IsGoodConnector(lnConnector, rPolygon))
{
return FALSE;
}
}
return TRUE;
}
ads_real XPrivate::MinDistance(const XLine &ln1, const XLine &ln2, XPoint &ptInt1, XPoint &ptInt2)
{
assert(ln1.m_nFlag == LS_FINITE && ln2.m_nFlag == LS_FINITE);
XPoint ptInt;
if (ln1.Intersection(&ln2, ptInt))
{
ptInt1 = ptInt2 = ptInt;
return 0.0;
}
XPoint pt1, pt2; // ln1在ln2上的两垂足
ln1.GetStartPoint().Project(&ln2, pt1);
ln1.GetEndPoint().Project(&ln2, pt2);
int nPrFlag1 = pt1 & ln2;
int nPrFlag2 = pt2 & ln2;
XPoint qt1, qt2;
ln2.GetStartPoint().Project(&ln1, qt1);
ln2.GetEndPoint().Project(&ln1, qt2);
int nQrFlag1 = qt1 & ln1;
int nQrFlag2 = qt2 & ln1;
DList<XLineDist> lstResult;
ads_real pDist1 = (nPrFlag1 != PR_OUTSIDE && nPrFlag1 != PR_EXTEND)
? ads_distance(ln1.GetStartPoint(), pt1) : 0.0;
lstResult.Append(new XLineDist(pDist1, ln1.GetStartPoint(), pt1));
ads_real pDist2 = (nPrFlag2 != PR_OUTSIDE && nPrFlag2 != PR_EXTEND)
? ads_distance(ln1.GetEndPoint(), pt2) : 0.0;
lstResult.Append(new XLineDist(pDist2, ln1.GetEndPoint(), pt2));
ads_real qDist1 = (nQrFlag1 != PR_OUTSIDE && nQrFlag1 != PR_EXTEND)
? ads_distance(ln2.GetStartPoint(), qt1) : 0.0;
lstResult.Append(new XLineDist(qDist1, qt1, ln2.GetStartPoint()));
ads_real qDist2 = (nQrFlag2 != PR_OUTSIDE && nQrFlag2 != PR_EXTEND)
? ads_distance(ln2.GetEndPoint(), qt2) : 0.0;
lstResult.Append(new XLineDist(qDist2, qt2, ln2.GetEndPoint()));
lstResult.Append(new XLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetStartPoint()),
ln1.GetStartPoint(), ln2.GetStartPoint()));
lstResult.Append(new XLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetEndPoint()),
ln1.GetStartPoint(), ln2.GetEndPoint()));
lstResult.Append(new XLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetStartPoint()),
ln1.GetEndPoint(), ln2.GetStartPoint()));
lstResult.Append(new XLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetEndPoint()),
ln1.GetEndPoint(), ln2.GetEndPoint()));
lstResult.QuickSort(XLineDist::Compare);
XLineDist *pp1 = lstResult[0];
ptInt1 = pp1->ptLocation1;
ptInt2 = pp1->ptLocation2;
return pp1->nDist;
}
int XPrivate::MinDistance(XLine &ln1, XPolygonEx &poly2, XPolyDist &result)
{
assert(ln1.m_nFlag == LS_FINITE);
DList<XPolyDist> lstResult;
for (int i = 0; i < poly2.Length(); i++)
{
XLine ln2(LS_FINITE);
poly2.NthLine(i, ln2);
XPoint pt1, pt2;
ads_real nDist = XPrivate::MinDistance(ln1, ln2, pt1, pt2);
if (nDist < _DIST_SNAP)
{
result.ptLocation1 = pt1;
result.ptLocation2 = pt2;
result.nDist = nDist;
result.nIndex2 = i;
return RTERROR;
}
else
{
lstResult.Append(new XPolyDist(nDist, 0, i, pt1, pt2));
}
}
lstResult.QuickSort(XPolyDist::Compare);
result = *lstResult[0];
return RTNORM;
}
int XPrivate::MinDistance(XPolygonEx &poly1, XPolygonEx &poly2, XPolyDist &result)
{
DList<XPolyDist> lstResult;
for (int i = 0; i < poly1.Length(); i++)
{
XLine ln1(LS_FINITE);
poly1.NthLine(i, ln1);
XPolyDist *pRes = new XPolyDist();
if (XPrivate::MinDistance(ln1, poly2, *pRes) != RTNORM)
{
result = *pRes;
result.nIndex1 = i;
delete pRes;
return RTERROR;
}
else
{
pRes->nIndex1 = i;
lstResult.Append(pRes);
}
}
lstResult.QuickSort(XPolyDist::Compare);
result = *lstResult[0];
return RTNORM;
}
double XPrivate::GetAnglePrecFromRadius(double radius)
{
double newAngPrec = 2 * asin(0.5 * g_distZero / radius);
if (newAngPrec > 0.1)
{
newAngPrec = 0.1;
}
else if (newAngPrec < 1E-18)
{
newAngPrec = 1E-18;
}
return newAngPrec;
}
double XPrivate::GetParaPrecFromLength(double length)
{
double newPrec = g_distZero / length;
if (newPrec > 0.1)
{
newPrec = 0.1;
}
else if (newPrec < 1E-18)
{
newPrec = 1E-18;
}
return newPrec;
}
bool XPrivate::IsParaInSeg(double pa,double prec)
{
WPushVar<double> vTemp(g_fZero,prec);
return UPEQUAL_ZERO(pa) && DOWNEQUAL_ZERO(pa - 1);
}
// 通用的函数, 要移到其他模块
Acad::ErrorStatus XPrivate::ReadCurve(AcDbDwgFiler *pFiler, XCurveSegment &seg)
{
pFiler->readItem(&(AcGePoint3d &)seg.GetStartPoint());
pFiler->readItem(&(AcGePoint3d &)seg.GetEndPoint());
double dBulge = 0;
pFiler->readItem(&dBulge);
seg.SetBulge(dBulge);
return pFiler->filerStatus();
}
Acad::ErrorStatus XPrivate::ReadCurveList(AcDbDwgFiler *pFiler, DList<XCurveSegment> &lstSegs)
{
Adesk::UInt16 nCount = 0;
pFiler->readItem(&nCount);
for (Adesk::UInt16 i = 0U; i<nCount; i++)
{
XCurveSegment *seg = new XCurveSegment;
XPrivate::ReadCurve(pFiler, *seg);
lstSegs.Append(seg);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus XPrivate::WriteCurve(AcDbDwgFiler *pFiler, const XCurveSegment &seg)
{
pFiler->writeItem((const AcGePoint3d &)seg.GetStartPoint());
pFiler->writeItem((const AcGePoint3d &)seg.GetEndPoint());
pFiler->writeItem(seg.GetBulge());
return pFiler->filerStatus();
}
Acad::ErrorStatus XPrivate::WriteCurveList(AcDbDwgFiler *pFiler, const DList<XCurveSegment> &lstSegs)
{
Adesk::UInt16 nCount = (Adesk::UInt16)lstSegs.Length();;
pFiler->writeItem(nCount);
for (Adesk::UInt16 i = 0U; i < nCount; i++)
{
XPrivate::WriteCurve(pFiler, lstSegs[(int)i]);
}
return pFiler->filerStatus();
}
// 用两个区域对一曲线进行裁剪, 剩下最长的曲线作为代表
XCurveSegment XPrivate::GetMaxCurveAfterClip(const XCurveSegment &cvSource, const XPoly2D &sPoly, const XPoly2D &ePoly)
{
XCurveSegment cvOffset = cvSource;
cvOffset.SetLineFlag(LS_FINITE);
DList<XCurveSegment> lstSource, lstIn, lstOut, lstEdge;
lstSource.Append(new XCurveSegment(cvOffset));
for (int nFrom = 0; nFrom < 2; nFrom++)
{
//起点裁剪和终点裁剪
const XPoly2D &poly = nFrom ? ePoly : sPoly;
if (!!poly)
{
lstOut.Reset();
PolyClip(lstSource, poly, lstIn, lstOut, lstEdge);
lstSource.Reset();
for (int i = 0; i < lstOut.Length(); i++)
{
lstSource.Append(new XCurveSegment(*lstOut[i]));
}
}
}
// 取裁剪后最长的边线作为代表(经验解)
if (!lstSource)
{
cvOffset = cvSource;
cvOffset.SetEndPoint(cvOffset.GetStartPoint());
}
else
{
XCurveSegment *pMax = lstSource[0];
for (int i = 1; i < lstSource.Length(); i++)
{
if (lstSource[i]->GetLength() > pMax->GetLength())
{
pMax = lstSource[i];
}
}
cvOffset = *pMax;
}
cvOffset.SetLineFlag(cvSource.GetLineFlag());
return cvOffset;
}
// 用两个区域对一曲线进行裁剪, 剩下的包含给定的点作为返回
XCurveSegment XPrivate::GetCurveContainPointAfterClip(XPoint ptPick,
const XCurveSegment &cvSource, const XPoly2D &sPoly, const XPoly2D &ePoly)
{
XCurveSegment cvOffset = cvSource;
cvOffset.SetLineFlag(LS_FINITE);
DList<XCurveSegment> lstSource, lstIn, lstOut, lstEdge;
lstSource.Append(new XCurveSegment(cvOffset));
for (int nFrom = 0; nFrom < 2; nFrom++)
{
//起点裁剪和终点裁剪
const XPoly2D &poly = nFrom ? ePoly : sPoly;
if (!!poly)
{
lstOut.Reset();
PolyClip(lstSource, poly, lstIn, lstOut, lstEdge);
lstSource.Reset();
for (int i = 0; i < lstOut.Length(); i++)
{
lstSource.Append(new XCurveSegment(*lstOut[i]));
}
}
}
if (!lstSource)
{
cvOffset = cvSource;
cvOffset.SetEndPoint(cvOffset.GetStartPoint());
}
else
{
BOOL bFind = FALSE;
for (int i = 0; i < lstSource.Length(); i++)
{
XCurveSegment &seg = *lstSource[i];
XPoint ptPrj;
if (seg.ProjectToMe(ptPick, ptPrj) == RTNORM && (ptPrj & seg) == PR_INSIDE)
{
cvOffset = seg;
bFind = TRUE;
break;
}
}
if (!bFind)
{
XCurveSegment *pMax = lstSource[0];
for ( int i = 1; i < lstSource.Length(); i++)
{
if (lstSource[i]->GetLength() > pMax->GetLength())
{
pMax = lstSource[i];
}
}
cvOffset = *pMax;
}
}
cvOffset.SetLineFlag(cvSource.GetLineFlag());
return cvOffset;
}
int XPrivate::MakeArcWallSeg(XExplodeDraw &dc, const XArc &arc,
ads_real height, ads_real iDist, ads_real oDist, int bShowStart, int bShowEnd)
{
if (height <= 0)
{
height = 0;
}
if (iDist >= arc.GetRadius() || oDist >= arc.GetRadius())
{
return RTERROR;
}
XArc iArc = arc.Offset(-iDist);
XArc oArc = arc.Offset(oDist);
XPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
XPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
return RTNORM;
}
void XPrivate::MakeArcWallSeg(XExplodeDraw &dc, const XArc &iArc, const XArc &oArc, ads_real height, int bShowStart, int bShowEnd)
{
XPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
XPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
}
// 对xBeg开始,以步长nStep共nDivNum步,高度为nHeight,进行镶嵌,
// 结果存入lstSectFaces。bHasTop, bHasBot, bHasLeft, bHasRight,外围边的可见性
void XPrivate::Tessellate(DList<X3DFace> &lstSectFaces, double xBeg, double nStep, int nDivNum, double nHeight,
BOOL bHasTop, BOOL bHasBot, BOOL bHasLeft, BOOL bHasRight)
{
double nPrev = xBeg;
for (int n = 1; n <= nDivNum; n++)
{
double nNext = xBeg + n * nStep;
X3DFace *pFace = new X3DFace;
int nFlag = pFace->GetFlag();
// 底-右-顶-左
if (!bHasBot)
{
nFlag |= 0x01;
}
if (bHasRight && n == nDivNum)
{
;
}
else
{
nFlag |= 0x02;
}
if (!bHasTop)
{
nFlag |= 0x04;
}
if (bHasLeft && n == 1)
{
;
}
else
{
nFlag |= 0x08;
}
pFace->SetFlag(nFlag);
pFace->SetVertex(0, XPoint(nPrev, 0.0));
pFace->SetVertex(1, XPoint(nNext, 0.0));
pFace->SetVertex(2, XPoint(nNext, nHeight));
pFace->SetVertex(3, XPoint(nPrev, nHeight));
lstSectFaces.Append(pFace);
nPrev = nNext;
}
}
// 把平面(含洞口)的模型,化解为三角形
// z坐标全部为0
int XPrivate::AsTriangleFaces(const XPolygonEx &polyOut, const DList<XPoly2D> &lstHoles,
DList<X3DFace> &lstFaces)
{
XTrianglePface lstTris;
if (XPrivate::Triangulate(polyOut, lstHoles, lstTris))
{
int nFlag = 0;
for (int n = 0; n < lstTris.Length(); n++)
{
XTriangle *triangle = lstTris[n];
ASSERT(triangle);
X3DFace *pFace = new X3DFace;
nFlag = triangle->m_nFlag;
pFace->SetVertex(0, triangle->vertex1);
pFace->SetVertex(1, triangle->vertex2);
pFace->SetVertex(2, triangle->vertex3);
pFace->SetVertex(3, triangle->vertex1);
nFlag |= FLAG_TRIANGLE;
pFace->SetFlag(nFlag);
lstFaces.Append(pFace);
}
return RTNORM;
}
return RTERROR;
}
// 把平面(含洞口)的模型,化解为三角形
// z坐标全部为0
int XPrivate::AsTriangleFaces(const XPoly2D &polyOut, const DList<XPoly2D> &lstHoles, DList<X3DFace> &lstFaces)
{
XPoly poly1;
((XPoly2D &)polyOut).MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation));
ASSERT(poly1.Length() > 2);
XPolygonEx polyEx1(poly1);
if (polyEx1.PathArea() > 0.0)
{
polyEx1.Reverse();
}
return XPrivate::AsTriangleFaces(polyEx1, lstHoles, lstFaces);
}
BOOL XPrivate::CreateReference(AcGePoint3d org,CString& BlockTableRecordName,double rotAng,CString layerName)
{
AcDbBlockReference* pNewBlkRef;
AcDbObjectId newEntId;
AcDbObjectId newBlockId;
AcDbBlockTable* pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
Acad::ErrorStatus es = pBlockTable->getAt(BlockTableRecordName,newBlockId);
if (es != Acad::eOk)
{
pBlockTable->close();
return 0;
}
pBlockTable->close();
AcDbObjectId layerId = NULL;
if (layerName != _T(""))
{
if (!IsLayerExistInDb(layerName))
{
NewLayer(layerName);
}
SetLayerFrozen(layerName,false);
SetLayerOff(layerName,false);
layerId = GetLayerRecordId(layerName);
}
pNewBlkRef = new AcDbBlockReference;
AcGeVector3d normal = AcGeVector3d(0.0,0.0,1.0);
AcGePoint3d basePt = org;
UCS2WCS(basePt);
AcGeMatrix3d mat;
acdbUcsMatrix(mat);
AcGeMatrix3d mat1;
mat1(0,0) = cos(rotAng);
mat1(0,1) = -sin(rotAng);
mat1(1,0) = sin(rotAng);
mat1(1,1) = cos(rotAng);
mat = mat * mat1;
pNewBlkRef->setBlockTableRecord(newBlockId);
pNewBlkRef->setNormal(normal);
pNewBlkRef->setBlockTransform(mat);
pNewBlkRef->setPosition(basePt);
if (layerId != NULL)
{
pNewBlkRef->setLayer(layerId);
}
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord* pBlockTableRec;
es = pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRec,AcDb::kForWrite);
if (es != Acad::eOk)
{
pBlockTable->close();
delete pNewBlkRef;
return 0;
}
pBlockTable->close();
es = pBlockTableRec->appendAcDbEntity(newEntId,pNewBlkRef);
if (es != Acad::eOk)
{
pBlockTableRec->close();
return 0;
}
pBlockTableRec->close();
pNewBlkRef->close();
return 1;
}
CString XPrivate::GetEnityLayer(AcDbObjectId objId)
{
CString layer = _T("");
if (objId == NULL)
{
return _T("");
}
AcDbEntity* pEnt = NULL;
acdbOpenObject(pEnt,objId,AcDb::kForRead);
if (pEnt == NULL)
{
return _T("");
}
TCHAR* str = pEnt->layer();
layer = str;
delete str;
pEnt->close();
return layer;
}
BOOL XPrivate::BlockName(CString& blockName)
{
static unsigned long Block_Num = 0;
CString temp;
Block_Num++;
temp.Format(_T("%ld"),Block_Num);
blockName = blockName + temp;
return 1;
}
BOOL XPrivate::CreateBlock(CEntityList& entLst,CString& blockName,AcDbObjectId& blockId,AcGePoint3d org)
{
if (!XPrivate::BlockName(blockName))
{
return 0;
}
AcDbBlockTable *pBlockTable = NULL;
Acad::ErrorStatus ret = acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForWrite);
if (ret != Acad::eOk)
{
return 0;
}
AcDbBlockTableRecord *pBlockTableRecord = new AcDbBlockTableRecord;
pBlockTableRecord->setOrigin(org);
pBlockTableRecord->setName(blockName);
pBlockTable->add(blockId,pBlockTableRecord);
pBlockTable->close();
POSITION pos = entLst.GetHeadPosition();
while (pos != NULL)
{
CEntity* pEnt = entLst.GetNext(pos);
pBlockTableRecord->appendAcDbEntity(pEnt->m_pAcDbEnt);
pEnt->m_pAcDbEnt->close();
}
pBlockTableRecord->close();
return 1;
}
AcDbObjectId XPrivate::GetLayerRecordId(CString layerName)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return NULL;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForRead) != Acad::eOk)
{
return NULL;
}
AcDbObjectId recordId = NULL;
if (pLayerTable->getAt(layerName, recordId) != Acad::eOk)
{
pLayerTable->close();
return NULL;
}
pLayerTable->close();
return recordId;
}
void XPrivate::ReleaseC3DFaceList(C3DFaceList& c3dfaceLst)
{
POSITION pos = c3dfaceLst.GetHeadPosition();
while (pos != NULL)
{
C3DFace* pC3DFace = c3dfaceLst.GetNext(pos);
delete pC3DFace;
}
c3dfaceLst.RemoveAll();
}
void XPrivate::ReleaseCEntityList(CEntityList& centityLst)
{
POSITION pos = centityLst.GetHeadPosition();
while (pos != NULL)
{
CEntity* pEnt = centityLst.GetNext(pos);
delete pEnt;
}
centityLst.RemoveAll();
}
void XPrivate::SetLayerOfEntities(CEntityList& entLst,CString layerName, int colorNum)
{
SetLayer(layerName, colorNum);
POSITION pos = entLst.GetHeadPosition();
while (pos != NULL)
{
CEntity* pEnt = entLst.GetNext(pos);
pEnt->m_pAcDbEnt->setLayer(layerName);
pEnt->m_pAcDbEnt->setColorIndex(256);
}
}
BOOL XPrivate::IsLayerExistInDb(CString layerName)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return 0;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForRead) != Acad::eOk)
{
return 0;
}
BOOL ret = pLayerTable->has(layerName);
pLayerTable->close();
return ret;
}
BOOL XPrivate::SetLayer(CString layerName, int colorNum)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
layerName = _T("0");
}
if (XPrivate::IsLayerExistInDb(layerName))
{
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk)
{
return 0;
}
AcDbLayerTableRecord* pLayerTableRecord;
if (pLayerTable->getAt(layerName, pLayerTableRecord,AcDb::kForWrite) == Acad::eOk)
{
pLayerTable->close();
if (pLayerTableRecord->isFrozen())
{
pLayerTableRecord->setIsFrozen(false);
}
if (pLayerTableRecord->isOff())
{
pLayerTableRecord->setIsOff(false);
}
if (colorNum > 0 && colorNum < 256)
{
AcCmColor color;
color.setColorIndex(colorNum);
pLayerTableRecord->setColor(color);
}
pLayerTableRecord->close();
return 1;
}
else
{
pLayerTable->close();
return 0;
}
}
return NewLayer(layerName, colorNum);
}
BOOL XPrivate::NewLayer(CString& layerName, int colorNum, BOOL bFreeze)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
layerName = _T("0");
return 0;
}
AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord;
if (!pLayerTableRecord)
{
return 0;
}
pLayerTableRecord->setName(layerName);
if (colorNum > 0 && colorNum < 256)
{
AcCmColor color;
color.setColorIndex(colorNum);
pLayerTableRecord->setColor(color);
}
if (bFreeze)
{
pLayerTableRecord->setIsFrozen(1);
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForWrite) != Acad::eOk)
{
delete pLayerTableRecord;
return 0;
}
AcDbObjectId recordId;
if (pLayerTable->add(recordId,pLayerTableRecord) != Acad::eOk)
{
pLayerTable->close();
delete pLayerTableRecord;
return 0;
}
pLayerTable->close();
pLayerTableRecord->close();
return 1;
}
void XPrivate::C3DFaceList2EntityList(C3DFaceList& c3dFaceLst,CEntityList& entLst)
{
POSITION pos = c3dFaceLst.GetTailPosition();
while (pos != NULL)
{
C3DFace* pNode = c3dFaceLst.GetPrev(pos);
CEntity* pCEnt = new CEntity(pNode->m_p3DFace);
entLst.AddTail(pCEnt);
}
}
BOOL XPrivate::SetLayerFrozen(CString layerName, bool bFreeze)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return 0;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk)
{
return 0;
}
AcDbLayerTableRecord* pLayerTableRecord;
if (pLayerTable->getAt(layerName, pLayerTableRecord, AcDb::kForWrite) != Acad::eOk)
{
pLayerTable->close();
return 0;
}
pLayerTable->close();
if (bFreeze)
{
if (!pLayerTableRecord->isFrozen())
{
pLayerTableRecord->setIsFrozen(true);
}
}
else
{
if (pLayerTableRecord->isFrozen())
{
pLayerTableRecord->setIsFrozen(false);
}
}
pLayerTableRecord->close();
return 1;
}
BOOL XPrivate::SetLayerOff(CString layerName, bool bOff)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return 0;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk)
{
return 0;
}
AcDbLayerTableRecord* pLayerTableRecord;
if (pLayerTable->getAt(layerName, pLayerTableRecord, AcDb::kForWrite) != Acad::eOk)
{
pLayerTable->close();
return 0;
}
pLayerTable->close();
if (bOff)
{
if (!pLayerTableRecord->isOff())
{
pLayerTableRecord->setIsOff(true);
}
}
else
{
if (pLayerTableRecord->isOff())
{
pLayerTableRecord->setIsOff(false);
}
}
pLayerTableRecord->close();
return 1;
}
void XPrivate::WCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
XPrivate::ARX2AdsPt(pt,ads_pt1);
ads_name pEntName;
acdbGetAdsName(pEntName,objId);
struct resbuf from,to;
from.restype = RTSHORT;
from.resval.rint = 0;
to.restype = RTENAME;
ads_name_set(pEntName,to.resval.rlname); //ECS
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
XPrivate::Ads2ARXPt(ads_ret,pt);
}
void XPrivate::UCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
XPrivate::ARX2AdsPt(pt,ads_pt1);
ads_name pEntName;
acdbGetAdsName(pEntName,objId);
struct resbuf from,to;
from.restype = RTSHORT;
from.resval.rint = 1;
to.restype = RTENAME;
ads_name_set(pEntName,to.resval.rlname); //ECS
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
XPrivate::Ads2ARXPt(ads_ret,pt);
}
void XPrivate::UCS2WCS(AcGePoint3d& pt,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
XPrivate::ARX2AdsPt(pt,ads_pt1);
struct resbuf from,to;
from.restype = RTSHORT;
from.resval.rint = 1; //UCS
to.restype = RTSHORT;
to.resval.rint = 0;
int ret = RTNORM;
ret = acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
XPrivate::Ads2ARXPt(ads_ret,pt);
}
void XPrivate::WCS2UCS(AcGePoint3d& pt,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
XPrivate::ARX2AdsPt(pt,ads_pt1);
struct resbuf from,to;
from.restype = RTSHORT;
from.resval.rint = 0; //WCS
to.restype = RTSHORT;
to.resval.rint = 1; //UCS
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
XPrivate::Ads2ARXPt(ads_ret,pt);
}
void XPrivate::ECS2UCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
XPrivate::ARX2AdsPt(pt,ads_pt1);
ads_name pEntName;
acdbGetAdsName(pEntName,objId);
struct resbuf from,to;
from.restype = RTENAME;
ads_name_set(pEntName,from.resval.rlname); //ECS
to.restype = RTSHORT;
to.resval.rint = 1;
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
XPrivate::Ads2ARXPt(ads_ret,pt);
}
void XPrivate::ECS2WCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
XPrivate::ARX2AdsPt(pt,ads_pt1);
ads_name pEntName;
acdbGetAdsName(pEntName,objId);
struct resbuf from,to;
from.restype = RTENAME;
ads_name_set(pEntName,from.resval.rlname); //ECS
to.restype = RTSHORT;
to.resval.rint = 0;
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
XPrivate::Ads2ARXPt(ads_ret,pt);
}
BOOL XPrivate::IsOverlap(AcGeLine3d& line1,AcGeLineSeg3d& lineSeg2,const AcGeTol& tol)
{
if (line1.isOn(lineSeg2.startPoint(),tol)
&& line1.isOn(lineSeg2.endPoint(),tol))
{
return 1;
}
else
{
return 0;
}
}
BOOL XPrivate::IsEqualSign(double x1,double x2)
{
if (x1 > fTOL && x2 > fTOL)
{
return 1;
}
if (x1 < fTOL && x2 < fTOL)
{
return 1;
}
return 0;
}
int XPrivate::xdata_extract_str(struct resbuf **rb, int *num)
{
if ((*rb) && ((*rb)->restype == 1070))
{
*num = (*rb)->resval.rint;
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int XPrivate::xdata_extract_str(struct resbuf **rb, ads_real *num)
{
if ((*rb) && ((*rb)->restype == 1040))
{
*num = (*rb)->resval.rreal;
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int XPrivate::xdata_extract_strPt(struct resbuf **rb, ads_point pt)
{
if ((*rb) && ((*rb)->restype == 1010))
{
Cpoint(pt, (*rb)->resval.rpoint);
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int XPrivate::xdata_extract_str(struct resbuf **rb, TCHAR *str)
{
if ((*rb) && ((*rb)->restype == 1000))
{
_tcscpy(str, (*rb)->resval.rstring);
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int XPrivate::xdata_extract_handle(struct resbuf **rb, TCHAR *str)
{
if ((*rb) && ((*rb)->restype == 1005))
{
_tcscpy(str, (*rb)->resval.rstring);
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int XPrivate::xdata_handle_assoc_single(ads_name ent, int tag, ads_name assoc_ent)
{
struct resbuf *entdata, *xdata, *tmprb, *rb;
get_app_xdata(ent, NULL, &entdata, &xdata);
if ((entdata == NULL) || (xdata == NULL))
{
ads_relrb(entdata);
return(0);
}
if ((rb = get_xdata_tag_item(xdata, tag, &tmprb)) == NULL)
{
ads_relrb(entdata);
return(0);
}
else
{
if (ads_handent(rb->rbnext->resval.rstring, assoc_ent) != RTNORM)
{
ads_printf(_T("\nSPY: Stale handle!"));
ads_relrb(entdata);
return(0);
}
else
{
ads_relrb(entdata);
return(1);
}
}
}
void XPrivate::set_xdata_tag_item(struct resbuf **xdata, int tag, struct resbuf *tag_xdata,
const TCHAR *appname)
{
struct resbuf *tmpxd, *old_xdata, *rb, *lagptr, *pretag_ptr;
int nested_list;
if (*xdata == NULL)
{
if ((appname == NULL) || (appname[0] == _T('\0')))
{
*xdata = ads_buildlist(-3, 1001, Are_appname, 0);
}
else
{
*xdata = ads_buildlist(-3, 1001, appname, 0);
}
}
if ((tmpxd = get_xdata_tag_item(*xdata, tag, &pretag_ptr)) == NULL)
{
if (!tag_xdata)
{
return;
}
rb = ads_newrb(1070);
rb->resval.rint = tag;
add_2_rblist(xdata, rb, FALSE);
append_rblists(xdata, tag_xdata);
return;
}
lagptr = tmpxd;
nested_list = 0;
if (tmpxd->rbnext)
{
tmpxd = tmpxd->rbnext;
}
while (tmpxd->rbnext)
{
if (tmpxd->restype == 1002)
{
if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("{"))))
{
nested_list++;
}
else if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("}"))))
{
nested_list--;
}
}
if (nested_list == 0)
{
break;
}
tmpxd = tmpxd->rbnext;
}
old_xdata = lagptr->rbnext;
if (!tag_xdata)
{
pretag_ptr->rbnext = tmpxd->rbnext;
tmpxd->rbnext = NULL;
}
else
{
lagptr->rbnext = tag_xdata;
rb = tag_xdata;
while (rb->rbnext)
{
rb = rb->rbnext;
}
rb->rbnext = tmpxd->rbnext;
tmpxd->rbnext = NULL;
}
ads_relrb(old_xdata);
}
struct resbuf *XPrivate::get_xdata_tag_item(struct resbuf * xdata, int tag, struct resbuf **lagptr)
{
struct resbuf *xptr, *tmp_lagptr;
int nested_list = 0;
tmp_lagptr = NULL;
tmp_lagptr = xptr = xdata;
while (xptr)
{
if (xptr->restype == 1002)
{
if (!_tcscmp(xptr->resval.rstring, PRIV_STR(_T("{"))))
{
nested_list++;
}
else if (!_tcscmp(xptr->resval.rstring, PRIV_STR(_T("}"))))
{
nested_list--;
}
}
else if (xptr->restype == 1070)
{
if (nested_list == 0)
{
if (xptr->resval.rint == tag)
{
if (lagptr)
{
*lagptr = tmp_lagptr;
}
return(xptr);
}
else
{
if (xptr->rbnext)
{
xptr = xptr->rbnext;
if (tmp_lagptr->rbnext != xptr)
{
tmp_lagptr = tmp_lagptr->rbnext;
}
if (xptr->restype == 1002)
{
continue;
}
if (!xptr->rbnext)
{
return(NULL);
}
}
else
{
return(NULL);
}
}
}
}
xptr = xptr->rbnext;
if (tmp_lagptr->rbnext != xptr)
{
tmp_lagptr = tmp_lagptr->rbnext;
}
}
return(NULL);
}
struct resbuf * XPrivate::detach_xdata_tag_item( struct resbuf *xdata, int tag)
{
struct resbuf *tmpxd, *tagptr, *pretag_ptr, *lagptr, *old_xdata;
int nested_list;
if ((tagptr = XPrivate::get_xdata_tag_item(xdata, tag, &pretag_ptr)) == NULL)
{
return(NULL);
}
tmpxd = tagptr;
if (tagptr->rbnext && (tagptr->rbnext->restype != 1002))
{
tmpxd = tmpxd->rbnext;
pretag_ptr->rbnext = tmpxd->rbnext;
tmpxd->rbnext = NULL;
tagptr->rbnext = NULL;
ads_relrb(tagptr);
return(tmpxd);
}
if (tagptr->rbnext && (tagptr->rbnext->restype == 1002))
{
tmpxd = tagptr->rbnext;
if ((tmpxd->rbnext && (tmpxd->rbnext->restype == 1002))
&& (!_tcscmp(tmpxd->rbnext->resval.rstring, _T("}"))))
{
pretag_ptr->rbnext = tmpxd->rbnext->rbnext;
tmpxd->rbnext->rbnext = NULL;
ads_relrb(tagptr);
return(NULL);
}
}
nested_list = 0;
if (!tagptr->rbnext)
{
return(NULL);
}
tmpxd = tagptr->rbnext;
while (tmpxd)
{
if (tmpxd->restype == 1002)
{
if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("{"))))
{
nested_list++;
}
else if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("}"))))
{
nested_list--;
}
}
if (nested_list == 0)
{
break;
}
lagptr = tmpxd;
tmpxd = tmpxd->rbnext;
}
pretag_ptr->rbnext = tmpxd->rbnext;
lagptr->rbnext = NULL;
tmpxd->rbnext = NULL;
ads_relrb(tmpxd);
old_xdata = tagptr->rbnext->rbnext;
tagptr->rbnext->rbnext = NULL;
ads_relrb(tagptr);
return(old_xdata);
}
int XPrivate::delete_xdata_tag_item(struct resbuf * xdata, int tag)
{
struct resbuf *tmp;
tmp = XPrivate::detach_xdata_tag_item(xdata, tag);
if (tmp)
{
ads_relrb(tmp);
return(1);
}
else
{
return(0);
}
}
void XPrivate::add_xdata_tag_braces(struct resbuf **tagdata)
{
struct resbuf *n;
n = ads_newrb(1002);
n->resval.rstring = _tcsdup(_T("{"));
add_2_rblist(tagdata, n, TRUE);
n = ads_newrb(1002);
n->resval.rstring = _tcsdup(_T("}"));
add_2_rblist(tagdata, n, FALSE);
}
int XPrivate::get_app_xdata(ads_name ent, const TCHAR *apps, struct resbuf **entdata, struct resbuf ** xdata)
{
struct resbuf *apps_rb;
apps_rb = ads_newrb(RTSTR);
if ((apps == NULL) || (apps[0] == _T('\0')))
{
apps_rb->resval.rstring = _tcsdup(Are_appname);
}
else
{
apps_rb->resval.rstring = _tcsdup(apps);
}
*entdata = ads_entgetx(ent, apps_rb);
if (*entdata == NULL)
{
ads_printf(_T("\nentgetx error!"));
*entdata = ads_entget(ent);
if (*entdata == NULL)
{
ads_printf(_T("\nentget error!"));
ads_relrb(apps_rb);
return(0);
}
}
ads_relrb(apps_rb);
*xdata = *entdata;
while ((*xdata) && ((*xdata)->restype != -3))
{
*xdata = (*xdata)->rbnext;
}
if (*xdata)
{
*xdata = (*xdata)->rbnext;
}
return(1);
}
int XPrivate::AT_setstr_resbuf(struct resbuf *ebuf, const TCHAR * str,int code)
{
struct resbuf *rb;
if ((rb = AT_get_resbuf(ebuf,code)) == NULL)
{
return RTNONE;
}
if (rb->restype != RTSTR)
{
return RTERROR;
}
if (_tcslen(rb->resval.rstring)<_tcslen(str))
{
if ((rb->resval.rstring = (TCHAR *)realloc(rb->resval.rstring,_tcslen(str) + 1)) == NULL)
{
return RTERROR;
}
}
_tcscpy(rb->resval.rstring,str);
return RTNORM;
}
//不封闭pline的裁剪延伸操作,seg与poly同向同心!
void XPrivate::ModifyXPoly2D(XPoly2D& poly,XCurveSegment seg)
{
if (poly.Length() < 2)
{
return;
}
XCurveSegment cv;
poly.Nth(0,cv);
*poly.Head() = seg.GetStartPoint();
if (cv.Is(CURVE_ARC))
{
XArc arc;
arc = cv.GetArc();
XVector3D vt = seg.GetStartPoint() - arc.GetCenterPt();
arc.SetStarAngle(vt.AsAcGeVector2d().angle());
poly.SetBulge(0, arc.Bulge());
}
poly.Nth(poly.TotalSegments() - 1,cv);
*poly.Tail() = seg.GetEndPoint();
if (cv.Is(CURVE_ARC))
{
XArc arc;
arc = cv.GetArc();
XVector3D vt = seg.GetEndPoint() - arc.GetCenterPt();
arc.SetEndAngle(vt.AsAcGeVector2d().angle());
poly.SetBulge(poly.Length() - 2, arc.Bulge());
}
}
void XPrivate::ModifyXPoly2DStart(XPoly2D& poly,XCurveSegment seg)
{
if (poly.Length() < 2)
{
return;
}
XCurveSegment cv;
poly.Nth(0,cv);
*poly.Head() = seg.GetStartPoint();
if (cv.Is(CURVE_ARC))
{
XArc arc;
arc = cv.GetArc();
XVector3D vt = seg.GetStartPoint() - arc.GetCenterPt();
arc.SetStarAngle(vt.AsAcGeVector2d().angle());
poly.SetBulge(0, arc.Bulge());
}
}
void XPrivate::ModifyXPoly2DEnd(XPoly2D& poly,XCurveSegment seg)
{
if (poly.Length() < 2)
{
return;
}
XCurveSegment cv;
poly.Nth(poly.TotalSegments() - 1,cv);
*poly.Tail() = seg.GetEndPoint();
if (cv.Is(CURVE_ARC))
{
XArc arc;
arc = cv.GetArc();
XVector3D vt = seg.GetEndPoint() - arc.GetCenterPt();
arc.SetEndAngle(vt.AsAcGeVector2d().angle());
poly.SetBulge(poly.Length() - 2, arc.Bulge());
}
}
void XPrivate::StringToList(const TCHAR *s, XStringList &res, TCHAR cSep)
{
const TCHAR *pBeg = s;
const TCHAR *pEnd = NULL;
do
{
pEnd = _tcschr(pBeg, cSep);
XString sTemp(1024);
StrCpy(sTemp, pBeg, pEnd);
res.Append(tstrnew(sTemp));
if (pEnd)
{
pBeg = pEnd + 1;
}
} while(pEnd != NULL);
}
int XPrivate::MergeCurve(XCurveSegment &curve, XCurveSegment &seg, int bMinusCurve, int bMinusSeg)
{
int bMerged = 0;
int bLine1 = curve.Is(CURVE_LINE),
bLine2 = seg.Is(CURVE_LINE);
//曲线类型相同, 走向相同
if (bLine1 == bLine2 && bMinusCurve == bMinusSeg)
{
if (bLine1)
{
if (CT_IsSameDrt(curve.XLine::Direction(), seg.XLine::Direction(), _angSnap))
{
curve.SetEndPoint(seg.GetEndPoint());
bMerged = 1;
}
}
else
{
XArc arc1 = curve.GetArc();
XArc arc2 = seg.GetArc();
if (fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt())
{
if (bMinusSeg)
{
arc1.SetStarAngle(arc2.GetStarAngle());
}
else
{
arc1.SetEndAngle(arc2.GetEndAngle());
}
if (fabs(arc1.Bulge()) < _angSnap || fabs(arc1.Bulge() - 2 * PI) < _angSnap)
{
;
}
else
{
curve = arc1;
bMerged = 1;
}
}
}
}
return bMerged;
}
void XPrivate::CircleToPoly(const XCircle &cir, XPoly &poly, int nDiv)
{
double nAng = PI * 2.0 / nDiv;
poly.Reset();
for (int i = 0; i < nDiv; i++)
{
XPoint ptVertex;
ads_polar(cir.GetCenterPt(), i * nAng, cir.GetRadius(), ptVertex);
poly.Append(new XPoint(ptVertex));
}
}
AcDbObject* XPrivate::GetDbConfigObjFromDict(AcDbDictionary *pXDict, AcDb::OpenMode mode)
{
Acad::ErrorStatus es=Acad::eOk;
AcDbObjectId idExist;
AcDbObject *pIObj = NULL;
es = pXDict->getAt(_T("AEC_DBCONFIG"), idExist);
if (es == Acad::eOk)
{
es=acdbOpenObject(pIObj, idExist, mode);
if (es == Acad::eOk)
return pIObj;
}
else
{
mode = AcDb::kForWrite;
}
if(mode==AcDb::kForWrite)
{
if(pXDict->upgradeOpen()==Acad::eOk)
{
AcRxClass* pDbConfigRx = AcRxClass::cast(acrxClassDictionary->at(_T("TDbConfig")));
if (pDbConfigRx != NULL)
{
pIObj = (AcDbObject*)pDbConfigRx->create();
//初始化线型
struct resbuf rb,rbNext;
rb.restype = RTSTR;
rb.resval.rstring = _tcsdup(_T("InitLineType"));
rb.rbnext = &rbNext;
rbNext.restype = RTSTR;
rbNext.resval.rstring = (TCHAR*)pXDict->database();
pIObj->setXData(&rb);
AcDbObjectId id;
es = pXDict->setAt(_T("AEC_DBCONFIG"), pIObj, id);
ASSERT(es == Acad::eOk);
}
pXDict->downgradeOpen();
}
}
return pIObj;
}
AcDbObject * XPrivate::GetDwgGlobalObj(AcDb::OpenMode opMode, AcDbDatabase *pDb)
{
AcDbObject* pInitSet = NULL;
AcDbDictionary* pNamedObj = NULL;
if(!pDb)
{
pDb=acdbCurDwg();
}
if(pDb && pDb->getNamedObjectsDictionary(pNamedObj, AcDb::kForRead) == Acad::eOk && pNamedObj)
{
pInitSet = XPrivate::GetDbConfigObjFromDict(pNamedObj, opMode);
pNamedObj->close();
}
return pInitSet;
}
//modify by zjq on 100310 从AEC_KERNAL工程移入
AcDbObjectId XPrivate::InitDynTextStyle()
{
AcDbObjectId idRet=GetTextStyleId(_T("_AEC_DYN"));
if(!idRet)
{
AcDbTextStyleTableRecord *pStyle=new AcDbTextStyleTableRecord;
pStyle->setName(_T("_AEC_DYN"));
#if ARX < 21
int iCharSet = 0, iPitchFamily = 0;
if (pStyle->setFont(_T("宋体"), Adesk::kFalse, Adesk::kFalse, iCharSet, iPitchFamily) == Acad::eOk)
#else
Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch;
Autodesk::AutoCAD::PAL::FontUtils::FontFamily family;
Charset charset;
if (pStyle->setFont(_T("宋体"), Adesk::kFalse, Adesk::kFalse, charset, pitch, family) == Acad::eOk)
#endif
idRet=AddTextStyle(pStyle, TRUE);
else
delete pStyle;
}
return idRet;
}
XConfigBase* g_pGlobalConfigBase = NULL;
XConfigBase* XPrivate::GetGlobalConfigBase()
{
if (g_pGlobalConfigBase == NULL)
{
AcDbObject* pObj = XPrivate::GetDwgGlobalObj(AcDb::kForRead,g_pCurrentDb);
if (pObj != NULL)
{
g_pGlobalConfigBase = (XConfigBase*)pObj->xData(_T("TDbConfig"));//AecConfig
pObj->close();
}
}
return g_pGlobalConfigBase;
}
BOOL DocGetCurMeterUnitDraw()
{
BOOL bMeterUnitDraw = FALSE;
XConfigBase* pBase = GetGlobalConfigBase();
if (pBase != NULL)
{
bMeterUnitDraw = pBase->DocGetMeterUnitDraw();
}
return bMeterUnitDraw;
}