Files
envi-code/SourceCode/Code2026/tg_shs/shs_geLib/TchPrivateGlobalFunc.cpp
T
2026-09-28 15:28:50 +08:00

3902 lines
78 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : 内部全局函数实现文件
// = Version : ver2.0
// = Author : tg
// = CreateDate : 2002-09-09
// = Description: 全局函数的声明
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TchPrivateGlobalFunc.h"
#include "TGGeCurveSegSegEx.h"
#include "TSymbolTableRecord.h"
#include "TDbPolyCurveEnt.h"
#include "TPushAcadVar.h"
#include "TPushMemVar.h"
#include "THole.h"
#include "TIdPointPair.h"
#include "TSortSideOnVertex.h"
#include "TSearchRegionFromCurve.h"
#include "TRemoveDupByLayer.h"
#include "TDPtrList.h"
#include "TGGeCurveSegSeg.h"
#include "TSearchException.h"
#include "TDupWallException.h"
#include "TPickEntSet.h"
#include "TGGeLineDist.h"
#include "TGGiExplodeDraw.h"
#include "TWPushVar.h"
#include "TAcDbBlockTableRecPtr.h"
#include "imgdef.h"
#include "imgent.h"
#include "TGGeTrianglePface.h"
#include "TDbDwgLicense.h"
#include "TAString.h"
#include "TUString.h"
#include "TConfigBase.h"
#include "TchGlobalCurveFunc.h"
#include "TGGeCurveInline.h"
static TCHAR Are_appname[] = _T("_XG_HVAC");
// flag: TURE--add head; FALSE--add tail
static void Add2Rblist(struct resbuf **tagdata, struct resbuf *n, int flag)
{
struct resbuf *tmptr;
if(flag)
{
tmptr = LinkResbufList(n, *tagdata);
}
else
{
tmptr = LinkResbufList(*tagdata, n);
}
*tagdata = tmptr;
}
BOOL TchPrivate::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 TchPrivate::CompareObjectId(const AcDbObjectId *id1, const void *id2)
{
if (*id1 == *(const AcDbObjectId *)id2)
{
return 0;
}
return 1;
}
int TchPrivate::CompareObjectId(const AcDbSoftPointerId *id1, const void *id2)
{
if (*id1 == *(const AcDbSoftPointerId *)id2)
{
return 0;
}
return 1;
}
PGroups TchPrivate::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);
//modify by xlc on 101217 修改输出信息
//ApplicationError(_T("\nError in fuction BuildList.No enough memory.\n"));
ads_printf(_T("\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)
{
(*(TADSGePoint3d *)cur->point) = **(TADSGePoint3d **)PArguments;
PArguments += sizeof(void *);
}
else if (type == RTSTR)
{
cur->string = _tcsdup(*(TCHAR **)PArguments);
PArguments += sizeof(void *);
}
else if (type == RTSHORT)
{
cur->shortInt = *(int*)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);
//modify by xlc on 101217 修改输出信息
//ApplicationError(_T("\nError in fuction BuildList.Undocumented DXFcode. code=%d\n"),code);
ads_printf(_T("\n创建参数链表错误,不支持的DXF码%d\n"),code);
return NULL;
}
}
return list;
}
ads_real TchPrivate::GetXDirection(const TGGeCurveSegment &cv1, const TGGeCurveSegment &cv2, const TADSGePoint3d &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 = AngleRangeTo2PI(nDrt1 + PI);
TGGeSector sec1(nDrt1, nDrtRev1);
ads_real nRes1 = *sec1.NearAngle(0.0);
ads_real nDrt2 = cv2.Direction(ptLoc);
ads_real nDrtRev2 = AngleRangeTo2PI(nDrt2 + PI);
TGGeSector sec2(nDrt2, nDrtRev2);
ads_real nRes2 = *sec2.NearAngle(0.0);
TGGeSector sec(nRes1, nRes2);
nRes = *sec.NearAngle(0.0);
}
return nRes;
}
//不判断顶点
int TchPrivate::HitTestOnEdge(const AcDbFace *pFace, TADSGePoint3d 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);
TGGeLine ln;
AcGePoint3d pt(ln.GetStartPoint().AsAcGePoint3d());
pFace->getVertexAt(i, pt);
pt = ln.GetEndPoint().AsAcGePoint3d();
pFace->getVertexAt(iNext, pt);
ln.SetElevation(0.0);
if ((pt & ln) == PR_INSIDE)
{
return i;
}
}
return -1;
}
AcGeMatrix3d TchPrivate::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 TchPrivate::_RemoveDupCurves(TDPtrList<TGGeCurveSegment> &lstCurves)
{
//初始化消除重线的集合
int len = lstCurves.Length();
TDPtrList<TGGeCurveSegSegEx> lstNewCurves;
for (int i = 0; i < len; i++)
{
TGGeCurveSegment &seg = *lstCurves[i];
if (seg.GetLength() < _DIST_SNAP) //太短了
{
continue;
}
lstNewCurves.Append(new TGGeCurveSegSegEx(seg));
}
len = lstNewCurves.Length();
if (g_bEchoSearch)
{
TCString sMsg(256);
sMsg << _T("对") << len << _T("条线进行消除重线");
acedSetStatusBarProgressMeter(sMsg, 0, len);
}
int nStep = len / 100;
if (nStep < 1)
{
nStep = 1;
}
for (i = 0; i < len; i++)
{
if (g_bEchoSearch && !(i % nStep))
{
acedSetStatusBarProgressMeterPos(i);
}
TGGeCurveSegSegEx &line1 = *lstNewCurves[i];
if (line1.IsDeleted())
{
continue;
}
BOOL bIsLine1 = line1.Is(CURVE_LINE);
for (int j = 0; j < len; j++)
{
TGGeCurveSegSegEx &line2 = *lstNewCurves[j];
if (j == i)
{
continue;
}
if (line2.IsDeleted() || bIsLine1 != line2.Is(CURVE_LINE))
{
continue; // 线2已经被删除或者两线类型不匹配
}
BOOL bPossibleDup = FALSE;
TGGeArc ar1, ar2;
if (bIsLine1) //对于LINE类型
{
TVector3D 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
{
(TGGeCircle &)ar1 = line1.GetCircle();
ar1.SetStarAngle(0.0);
ar1.SetEndAngle(PI * 2.0);
}
if (line2.Is(CURVE_ARC))
{
ar2 = line2.GetArc();
}
else
{
(TGGeCircle &)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变成圆
{
(TGGeCurveSegment &)line1 = TGGeCircle(ar1.GetCenterPt(), ar1.GetRadius());
}
}
else if (flg1 != PR_OUTSIDE) //Add this 2 lines on 2003/12/15
{
(TGGeCurveSegment &)line1 = TGGeCircle(ar1.GetCenterPt(), ar1.GetRadius());
}
else
{
ar1.SetEndAngle(ar2.GetEndAngle());
(TGGeCurveSegment &)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());
(TGGeCurveSegment &)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 (i = 0; i < len; i++)
{
TGGeCurveSegSegEx &ln = *lstNewCurves[i];
if (!ln.IsDeleted())
{
lstCurves.Append(new TGGeCurveSegment(ln));
}
}
if (g_bEchoSearch)
{
acedRestoreStatusBar();
}
}
int TchPrivate::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 TchPrivate::GetArcData(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 = GetResbufAtCode(res2,0);
if (_tcscmp(rb1->resval.rstring,_T("ARC")) != 0
&& _tcscmp(rb1->resval.rstring,_T("CIRCLE")) != 0)
{
ads_relrb(res2);
return RTERROR;
}
rb1 = GetResbufAtCode(res2,10);
cent[X] = rb1->resval.rpoint[X];
cent[Y] = rb1->resval.rpoint[Y];
cent[Z] = rb1->resval.rpoint[Z];
rb1 = GetResbufAtCode(res2,40);
*rad = rb1->resval.rreal;
rb1 = GetResbufAtCode(res2,0);
if ( _tcscmp(rb1->resval.rstring,_T("ARC")) == 0)
{
rb1 = GetResbufAtCode(res2,50);
*sang = rb1->resval.rreal;
rb1 = GetResbufAtCode(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 TchPrivate::operator == (TCStringList &strs1, TCStringList &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 TchPrivate::ThickPoly2Face(TMasterProperties prop, const TGGePoly2D &poly, TADSGePoint3d vtNormal, double nThick,
AcDbVoidPtrArray &entSet, AcGeMatrix3d *pMatTran)
{
ASSERT(nThick > _DIST_SNAP);
if (nThick > _DIST_SNAP && poly.Length())
{
TGGePoly polygon;
poly.AsOpenPoly1(polygon, _AS_SYS_UNIT(g_nCirDeviation));
int nSeg = polygon.Length() - 1;
for (int n = 0; n < nSeg; n++)
{
TADSGePoint3d 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++)
{
TADSGePoint3d 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)
{
TGGePoly2D polyBot(poly), polyTop(poly);
polyBot.Reverse();
polyTop.SetElevation(poly.Head()->z + nThick);
TGGiExplodeDraw dc(entSet);
TDPtrList<TGGePoly2D> emptyHole;
dc.DrawShell(polyBot, emptyHole);
dc.DrawShell(polyTop, emptyHole);
}
}
}
// 画拉伸圆
void TchPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeCircle &cir, ads_real nHeight)
{
AcDbPolyline line;
line.setElevation(cir.GetCenterPt().z);
line.setThickness(nHeight);
TADSGePoint3d 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 TchPrivate::DrawArcSeg(TGGiExplodeDrawBase &dc, const TGGeArc &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(), TGGiExplodeDraw::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;
TADSGePoint3d *ptArray = new TADSGePoint3d[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 (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 TchPrivate::DrawLineSeg(TGGiExplodeDrawBase &dc, const TGGeLine &ln,
ads_real nHeight, int bShowStart, int bShowEnd)
{
int nVertexNum = 4;
TADSGePoint3d *ptArray = new TADSGePoint3d[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 TchPrivate::DrawLineSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeLine &ln)
{
AcGePoint3d line[2] = {ln.GetStartPoint(), ln.GetEndPoint()};
if (pWd)
{
pWd->geometry().polyline(2, line);
}
else
{
pVd->geometry().polyline(2, line);
}
}
//绘制二维弧线
void TchPrivate::DrawArcSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeArc &ar)
{
TADSGePoint3d 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 TchPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeCircle &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 TchPrivate::AsPolyline(const AcDbLine &line, AcDbPolyline &pline)
{
pline.reset(Adesk::kFalse, 0);
pline.setPropertiesFrom(&line);
TVector3D vtNormal;
(AcGeVector3d &)vtNormal = line.normal();
TADSGePoint3d 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 TchPrivate::AsPolyline(const AcDbArc &line, AcDbPolyline &pline)
{
pline.reset(Adesk::kFalse, 0);
TADSGePoint3d vtNormal;
(AcGeVector3d &)vtNormal = line.normal();
TADSGePoint3d ptCen = Wcs2Ecs(line.center(), vtNormal);
TGGeArc ar(ptCen, line.radius(), line.startAngle(), line.endAngle());
pline.setPropertiesFrom(&line);
TADSGePoint3d 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 TchPrivate::AsPolyline(const AcDbCircle &line, AcDbPolyline &pline)
{
TADSGePoint3d vtNormal;
(AcGeVector3d &)vtNormal = line.normal();
TADSGePoint3d ptCen = Wcs2Ecs(line.center(), vtNormal);
TGGeCircle cir(ptCen, line.radius());
TGGeCurveSegment seg;
seg = cir;
TGGePoly2D 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 TchPrivate::CompNodeByEqual(const TSortWallOnPt *p1, const void *p2)
{
if (p1 == p2)
{
return 0;
}
return 1;
}
int TchPrivate::GetPointInArcType(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 TchPrivate::PointProjectToLine(ads_point src_pt, ads_point cl_pt1, ads_point cl_pt2, ads_point dest_pt)
{
//modify by xlc 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 STPlanePara plan;
TVector3D vt;
Vector3dFrom2Pt(cl_pt1, cl_pt2, vt);
dest_pt[0]=src_pt[0];
dest_pt[1]=src_pt[1];
dest_pt[2]=src_pt[2];
if(GetPlaneEquation(src_pt, vt, &plan))
{
LineIntersectWithPlaneA(cl_pt1, cl_pt2, &plan, dest_pt);
}
return RTNORM;
}
// 计算点到线的距离
// pt1, pt2 -- 指定线上的两点
// pt0 -- 指定点
// 返回值: 点到线的距离
ads_real TchPrivate::PointDistanceToLine(ads_point pt0, ads_point pt1,ads_point pt2)
{
//modify by xlc 100613 取消AcGe算法,速度慢
//AcGeLine3d lineT(asPnt3d(pt1),asPnt3d(pt2));
//AcGePointOnCurve3d ptOnCr;
//lineT.getClosestPointTo(asPnt3d(pt0),ptOnCr);
//return ptOnCr.point3d().distanceTo(asPnt3d(pt0));
ads_point pt4;
PointProjectToLine(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 TchPrivate::GetPointOnLineType(ads_point pt, ads_point line_pt1,ads_point line_pt2)
{
ads_real snap0 = _DIST_SNAP;
ads_point vt1, vt2;
if (TchPrivate::PointDistanceToLine(pt, line_pt1, line_pt2) > snap0)
{
return 0;
}
Vector3dFrom2Pt(pt, line_pt1, vt1);
Vector3dFrom2Pt(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 (RealEqual(Vector3dAngleTo(vt1, vt2), 0, _angSnap) )
{
return 4;
}
if (RealEqual(Vector3dAngleTo(vt1, vt2), PI, _angSnap) )
{
return 3;
}
return 0;
}
double TchPrivate::GetPolygonDist(const TGGePolygonEx &poly1, const TGGePolygonEx &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++)
{
TADSGePoint3d 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 TchPrivate::IsEqual(const AcGePoint3d pt11,const AcGePoint3d pt12,const AcGePoint3d pt21,const AcGePoint3d pt22,double tol)
{
if ((TchPrivate::IsEqual(pt11,pt21,tol) && TchPrivate::IsEqual(pt12,pt22,tol))
|| (TchPrivate::IsEqual(pt11,pt22,tol) && TchPrivate::IsEqual(pt12,pt21,tol)))
{
return 1;
}
else
{
return 0;
}
}
BOOL TchPrivate::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 TchPrivate::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 TchPrivate::Triangulate(const TDPtrList<TGGePoly2D> &lstHole,TDPtrList<TGGeTriangle> &lstRes)
{
THole hole;
if (hole.ConstructEdgeList(lstHole))
{
return (hole.GetTriangles(lstRes));
}
return FALSE;
}
BOOL TchPrivate::Triangulate(const TDPtrList<TGGePolygonEx> &lstHole,TDPtrList<TGGeTriangle> &lstRes)
{
THole hole;
if (hole.ConstructEdgeList(lstHole))
{
return (hole.GetTriangles(lstRes));
}
return FALSE;
}
BOOL TchPrivate::Triangulate(const TGGePoly2D &out,const TDPtrList<TGGePoly2D> &lstHole,TDPtrList<TGGeTriangle> &lstRes)
{
THole hole;
if (hole.ConstructEdgeList(out,lstHole))
{
return hole.GetTriangles(lstRes);
}
return FALSE;
}
BOOL TchPrivate::Triangulate(const TGGePolygonEx &out, const TDPtrList<TGGePoly2D> &lstHole, TDPtrList<TGGeTriangle> &lstRes)
{
THole hole;
if (hole.ConstructEdgeList(out,lstHole))
{
return hole.GetTriangles(lstRes);
}
return FALSE;
}
BOOL TchPrivate::Triangulate(const TGGePolygonEx &out, const TDPtrList<TGGePolygonEx> &lstHole, TDPtrList<TGGeTriangle> &lstRes)
{
THole hole;
if (hole.ConstructEdgeList(out,lstHole))
{
return hole.GetTriangles(lstRes);
}
return FALSE;
}
// 区域的减法
// lstPoly2 is inside poly1, but share edges
// lstPoly2都是独立的域,不含孔洞模型
int TchPrivate::_Subtract(const TGGePoly2D &poly1, const TDPtrList<TGGePoly2D> &lstPoly2, TDPtrList<TGGePoly2D> &lstResult)
{
// 首先, poly1对poly2进行裁剪, 取内部
TDPtrList<TGGeCurveSegment> lstSeg2, lstSeg2In, lstSeg2Out, lstSeg2Edge ;
for (int n = 0; n < lstPoly2.Length(); n++)
{
const TGGePoly2D &poly2 = lstPoly2[n];
ExplodePoly2D(poly2, lstSeg2);
}
PolyClip(lstSeg2, (TGGePoly2D &)poly1, lstSeg2In, lstSeg2Out, lstSeg2Edge);
// 然后, poly2对poly1进行裁剪, 取外部
TDPtrList<TGGeCurveSegment> lstSeg1, lstSeg1In, lstSeg1Out, lstSeg1Edge ;
ExplodePoly2D(poly1, lstSeg1);
for (n = 0; n < lstPoly2.Length(); n++)
{
const TGGePoly2D &poly2 = lstPoly2[n];
lstSeg1Out.Reset();
PolyClip(lstSeg1, (TGGePoly2D &)poly2, lstSeg1In, lstSeg1Out, lstSeg1Edge);
lstSeg1.Reset();
for (int k = 0; k < lstSeg1Out.Length(); k++)
{
lstSeg1.Append(new TGGeCurveSegment(*lstSeg1Out[k]));
}
}
//lstSeg2In合并到lstSeg1Out
for (int i = 0; i < lstSeg2In.Length(); i++)
{
lstSeg1Out.Append(new TGGeCurveSegment(*lstSeg2In[i]));
}
TDPtrList<TGGePoly2D> lstTemp(FALSE);
int nRet = SearchRegions(lstSeg1Out, lstTemp);
for (i = 0; i < lstTemp.Length(); i++)
{
TGGePoly2D *pTemp = lstTemp[i];
if (pTemp->IsSelfIntersect())
{
delete pTemp;
}
else
{
lstResult.Append(pTemp);
}
}
return nRet;
}
// 8.0补丁暂未使用
// 参考ptRef,判断在外轮廓中,应该减去pt1、pt2中的哪个点
TADSGePoint3d TchPrivate::GetAutoDelPt(TADSGePoint3d ptRef, TADSGePoint3d pt1, TADSGePoint3d pt2)
{
TADSGePoint3d vecXDir, vecYDir;
TGGetVar(_T("UCSXDIR"), vecXDir);
TGGetVar(_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 TchPrivate::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 (ADS>15)
bool TchPrivate::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
TCString TchPrivate::OsMode2Str(int nMode)
{
TCString 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 TchPrivate::SearchPathFromCurve(const TDPtrList<TGGeCurveSegment> &curves, TGGePoly2D &polyPath)
{
TSearchRegionFromCurve aSearch;
BOOL bInit = TRUE;
try
{
aSearch.InitStart(curves);
}
catch(...)
{
bInit = FALSE;
}
if (!bInit)
{
return FALSE;
}
TDPtrList<TSortSideOnVertex> &nodes = TSearchRegionFromCurve::g_lstAllSortSides;
TSortSideOnVertex *pHead = NULL;
TSortSideOnVertex *pTail = NULL;
for (int i = 0; i < nodes.Length(); i++)
{
TSortSideOnVertex &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);
TSortSideOnVertex *pNode = pHead;
TGGeRegionSide *pLast = NULL;
while (pNode != pTail)
{
TGGeRegionSide *pSide1 = pNode->Head()->m_pSide;
TGGeRegionSide *pSide2 = pNode->Tail()->m_pSide;
TGGeRegionSide *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 TchPrivate::FixGsView()
{
PersistGsView(NULL);
}
extern Acad::ErrorStatus fromAcDbTextStyle(AcGiTextStyle& style, const AcDbObjectId& AcDbStyleId);
TADSGePoint3d TchPrivate::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);
TADSGePoint3d ptBox;
(AcGePoint2d &)ptBox = ptExt;
return ptBox;
}
void TchPrivate::RemoveDupNoXData()
{
TPushMemVar<BOOL> vTemp(g_bEchoSearch, TRUE);
TDPtrList<TRemoveDupByLayer> lstRemoveDup;
TPickEntSet ss(SS_FREE);
if (ss.Get(NULL, NULL, NULL, TRBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM)
{
long lCount = ss.Length();
for (long i = 0L;i<lCount; i++)
{
TEntitySet ent = ss[i];
TCString sLayer(256);
ent.GetData(8, (TCHAR *)sLayer);
TRemoveDupByLayer *pData = lstRemoveDup.FindNode((TCHAR *)sLayer, TRemoveDupByLayer::CompareForFindByLayer);
if (pData)
{
pData->m_lstCurves.Append(new TGGeCurveSegment(ent));
}
else
{
pData = new TRemoveDupByLayer(sLayer);
pData->m_lstCurves.Append(new TGGeCurveSegment(ent));
lstRemoveDup.Append(pData);
}
}
ss.Erase();
for (int n = 0; n<lstRemoveDup.Length(); n++)
{
TRemoveDupByLayer *pData = lstRemoveDup[n];
TchGeLib::adsout << _T("\n对图层") << pData->m_sLayer << _T("消除重线: ");
int nOldNum = pData->m_lstCurves.Length();
RemoveDupCurves(pData->m_lstCurves);
TchGeLib::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 TchPrivate::RemoveExactDupLines(TDPtrList<TGGeCurveSegment> &lstCurves)
{
//初始化消除重线的集合
int len = lstCurves.Length();
TDPtrList<TGGeCurveSegSeg> lstNewCurves;
for (int i = 0; i < len; i++)
{
TGGeCurveSegment &seg = *lstCurves[i];
if (seg.GetLength() < _DIST_SNAP)
{
continue;
}
lstNewCurves.Append(new TGGeCurveSegSeg(seg));
}
len = lstNewCurves.Length();
if (g_bEchoSearch)
{
TCString sMsg(256);
sMsg << _T("对") << len << _T("条线进行消除完全重线");
acedSetStatusBarProgressMeter(sMsg, 0, len);
}
int nStep = len / 100;
if (nStep < 1)
{
nStep = 1;
}
for (i = 0; i < len; i++)
{
if (g_bEchoSearch && !(i % nStep))
{
acedSetStatusBarProgressMeterPos(i);
}
TGGeCurveSegSeg line1 = *lstNewCurves[i];
if (line1.m_bDeleted)
{
continue;
}
ASSERT(line1.Is(CURVE_LINE));
for (int j = 0; j < len; j++)
{
TGGeCurveSegSeg &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 (i = 0; i < len; i++)
{
TGGeCurveSegSeg &ln = *lstNewCurves[i];
if (!ln.m_bDeleted)
{
lstCurves.Append(new TGGeCurveSegment(ln));
}
}
if (g_bEchoSearch)
{
acedRestoreStatusBar();
}
}
char* TchPrivate::TGh2cpy(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* TchPrivate::TGh3cpy(char *to, char *fr, int len)
{
if (!to || !fr)
{
exit(0);
}
char *from;
for (from = fr; *from == ' '; from++)
{
;
}
return TchPrivate::TGh2cpy(to, from, len);
}
void TchPrivate::TGh1cpy(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 *TchPrivate::StrDelSpace(const TCHAR *src)
{
if (!src)
{
exit(0);
}
char tmp[256] = "";
TchPrivate::TGh1cpy(tmp, _AS(src));
return tstrnew(TString(tmp));
}
int TchPrivate::GetPickFirst(TPickEntSet &gSet, TPickEntSet &pSet)
{
resbuf *gset = NULL, *pset = NULL;
int nRet = ads_ssgetfirst(&gset, &pset);
if (gset)
{
if (gset->restype == RTPICKS)
{
TPickEntSet ss0(0);
ss0 = gset->resval.rlname;
gSet += ss0;
ss0.Free();
}
ads_relrb(gset);
}
if (pset)
{
if (pset->restype == RTPICKS)
{
TPickEntSet ss0(0);
ss0 = pset->resval.rlname;
pSet += ss0;
ss0.Free();
}
ads_relrb(pset);
}
return nRet;
}
double TchPrivate::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 TchPrivate::ConnectPolygonsNew(TDPtrList<TGGePolygonEx> &lstPolygons, TGGePolygonEx &polyEx1)
{
if (!lstPolygons)
{
return RTERROR;
}
polyEx1 = *lstPolygons.Head();
lstPolygons.Remove(0);
LAB_RESTART:
if (!lstPolygons)
{
return RTNORM;
}
TGGePolyDist minDist;
BOOL bInit = FALSE;
int nIndex = 0;
for (int i = 0; i < lstPolygons.Length(); i++)
{
TGGePolyDist 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)
{
TGGePolygonEx polyEx2;
ConnectPolygon(polyEx1, *lstPolygons[nIndex], minDist, polyEx2);
polyEx1 = polyEx2;
lstPolygons.Remove(nIndex);
goto LAB_RESTART;
}
return RTERROR;
}
int TchPrivate::ConnectPolygons(TDPtrList<TGGePolygonEx> &lstPolygons, TGGePolygonEx &polyEx1)
{
if (!lstPolygons)
{
return RTERROR;
}
polyEx1 = *lstPolygons.Head();
lstPolygons.Remove(0);
LAB_RESTART:
for (int i = 0; i < lstPolygons.Length(); i++)
{
TGGeLine lnConnector;
double nDist = GetConnector(polyEx1, *lstPolygons[i], lnConnector);
if (IsGoodConnector(lnConnector, lstPolygons, i))
{
TGGePolygonEx polyEx2;
ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2);
polyEx1 = polyEx2;
lstPolygons.Remove(i);
goto LAB_RESTART;
}
}
if (lstPolygons.Length())
{
#ifndef NDEBUG
TchGeLib::adsout << _T("\nCan not find good connector!");
#endif
for (i = 0; i < lstPolygons.Length(); i++)
{
TGGePolygonEx polyEx2;
ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2);
polyEx1 = polyEx2;
}
}
return RTNORM;
}
void TchPrivate::RemoveDup()
{
TDPtrList<TRemoveDupEntByLayer> lstRemoveDup;
TPickEntSet ss(SS_FREE);
if (ss.Get(NULL, NULL, NULL, TRBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM)
{
long lCount = ss.Length();
for (long i = 0L; i < lCount; i++)
{
TEntitySet ent = ss[i];
TCString sLayer(256);
ent.GetData(8, (TCHAR *)sLayer);
TRemoveDupEntByLayer *pData = lstRemoveDup.FindNode((TCHAR *)sLayer, TRemoveDupEntByLayer::CompareForFindByLayer);
if (pData)
{
pData->m_ss += ent;
}
else
{
pData = new TRemoveDupEntByLayer(sLayer);
pData->m_ss += ent;
lstRemoveDup.Append(pData);
}
}
for (int n = 0; n<lstRemoveDup.Length(); n++)
{
TRemoveDupEntByLayer *pData = lstRemoveDup[n];
TchGeLib::adsout << _T("\n对图层") << pData->m_sLayer << _T("消除重线: ");
long nOldNum = pData->m_ss.Length();
HandleCurveDup(pData->m_ss);
TchGeLib::adsout << _T("由") << int(nOldNum) << _T("变为") << (int)pData->m_ss.Length();
}
}
}
// 判断桥接是否合适,即不和任何边有交点(位于边内)
BOOL TchPrivate::IsGoodConnector(const TGGeLine &lnConnector, const TGGePolygonEx &rPolygon)
{
for (int j = 0; j < rPolygon.Length(); j++)
{
TADSGePoint3d ptInt;
TGGeLine 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 TchPrivate::GetConnector(const TGGePolygonEx &poly1, const TGGePolygonEx &poly2, TGGeLine &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++)
{
TADSGePoint3d 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 TchPrivate::IsGoodConnector(const TGGeLine &lnConnector, const TDPtrList<TGGePolygonEx> &lstPolygons, int idxExclude)
{
for (int i = 0; i < lstPolygons.Length(); i++)
{
if (i == idxExclude)
{
continue;
}
const TGGePolygonEx &rPolygon = lstPolygons[i];
if (!TchPrivate::IsGoodConnector(lnConnector, rPolygon))
{
return FALSE;
}
}
return TRUE;
}
ads_real TchPrivate::MinDistance(const TGGeLine &ln1, const TGGeLine &ln2, TADSGePoint3d &ptInt1, TADSGePoint3d &ptInt2)
{
assert(ln1.m_nFlag == LS_FINITE && ln2.m_nFlag == LS_FINITE);
TADSGePoint3d ptInt;
if (ln1.Intersection(&ln2, ptInt))
{
ptInt1 = ptInt2 = ptInt;
return 0.0;
}
TADSGePoint3d pt1, pt2; // ln1在ln2上的两垂足
ln1.GetStartPoint().Project(&ln2, pt1);
ln1.GetEndPoint().Project(&ln2, pt2);
int nPrFlag1 = pt1 & ln2;
int nPrFlag2 = pt2 & ln2;
TADSGePoint3d qt1, qt2;
ln2.GetStartPoint().Project(&ln1, qt1);
ln2.GetEndPoint().Project(&ln1, qt2);
int nQrFlag1 = qt1 & ln1;
int nQrFlag2 = qt2 & ln1;
TDPtrList<TGGeLineDist> lstResult;
ads_real pDist1 = (nPrFlag1 != PR_OUTSIDE && nPrFlag1 != PR_EXTEND)
? ads_distance(ln1.GetStartPoint(), pt1) : 0.0;
lstResult.Append(new TGGeLineDist(pDist1, ln1.GetStartPoint(), pt1));
ads_real pDist2 = (nPrFlag2 != PR_OUTSIDE && nPrFlag2 != PR_EXTEND)
? ads_distance(ln1.GetEndPoint(), pt2) : 0.0;
lstResult.Append(new TGGeLineDist(pDist2, ln1.GetEndPoint(), pt2));
ads_real qDist1 = (nQrFlag1 != PR_OUTSIDE && nQrFlag1 != PR_EXTEND)
? ads_distance(ln2.GetStartPoint(), qt1) : 0.0;
lstResult.Append(new TGGeLineDist(qDist1, qt1, ln2.GetStartPoint()));
ads_real qDist2 = (nQrFlag2 != PR_OUTSIDE && nQrFlag2 != PR_EXTEND)
? ads_distance(ln2.GetEndPoint(), qt2) : 0.0;
lstResult.Append(new TGGeLineDist(qDist2, qt2, ln2.GetEndPoint()));
lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetStartPoint()),
ln1.GetStartPoint(), ln2.GetStartPoint()));
lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetEndPoint()),
ln1.GetStartPoint(), ln2.GetEndPoint()));
lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetStartPoint()),
ln1.GetEndPoint(), ln2.GetStartPoint()));
lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetEndPoint()),
ln1.GetEndPoint(), ln2.GetEndPoint()));
lstResult.QuickSort(TGGeLineDist::Compare);
TGGeLineDist *pp1 = lstResult[0];
ptInt1 = pp1->ptLocation1;
ptInt2 = pp1->ptLocation2;
return pp1->nDist;
}
int TchPrivate::MinDistance(TGGeLine &ln1, TGGePolygonEx &poly2, TGGePolyDist &result)
{
assert(ln1.m_nFlag == LS_FINITE);
TDPtrList<TGGePolyDist> lstResult;
for (int i = 0; i < poly2.Length(); i++)
{
TGGeLine ln2(LS_FINITE);
poly2.NthLine(i, ln2);
TADSGePoint3d pt1, pt2;
ads_real nDist = TchPrivate::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 TGGePolyDist(nDist, 0, i, pt1, pt2));
}
}
lstResult.QuickSort(TGGePolyDist::Compare);
result = *lstResult[0];
return RTNORM;
}
int TchPrivate::MinDistance(TGGePolygonEx &poly1, TGGePolygonEx &poly2, TGGePolyDist &result)
{
TDPtrList<TGGePolyDist> lstResult;
for (int i = 0; i < poly1.Length(); i++)
{
TGGeLine ln1(LS_FINITE);
poly1.NthLine(i, ln1);
TGGePolyDist *pRes = new TGGePolyDist();
if (TchPrivate::MinDistance(ln1, poly2, *pRes) != RTNORM)
{
result = *pRes;
result.nIndex1 = i;
delete pRes;
return RTERROR;
}
else
{
pRes->nIndex1 = i;
lstResult.Append(pRes);
}
}
lstResult.QuickSort(TGGePolyDist::Compare);
result = *lstResult[0];
return RTNORM;
}
double TchPrivate::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 TchPrivate::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 TchPrivate::IsParaInSeg(double pa,double prec)
{
TWPushVar<double> vTemp(g_fZero,prec);
return UPEQUAL_ZERO(pa) && DOWNEQUAL_ZERO(pa - 1);
}
// 通用的函数, 要移到其他模块
Acad::ErrorStatus TchPrivate::ReadCurve(AcDbDwgFiler *pFiler, TGGeCurveSegment &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 TchPrivate::ReadCurveList(AcDbDwgFiler *pFiler, TDPtrList<TGGeCurveSegment> &lstSegs)
{
Adesk::UInt16 nCount = 0;
pFiler->readItem(&nCount);
for (Adesk::UInt16 i = 0U; i<nCount; i++)
{
TGGeCurveSegment *seg = new TGGeCurveSegment;
TchPrivate::ReadCurve(pFiler, *seg);
lstSegs.Append(seg);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TchPrivate::WriteCurve(AcDbDwgFiler *pFiler, const TGGeCurveSegment &seg)
{
pFiler->writeItem((const AcGePoint3d &)seg.GetStartPoint());
pFiler->writeItem((const AcGePoint3d &)seg.GetEndPoint());
pFiler->writeItem(seg.GetBulge());
return pFiler->filerStatus();
}
Acad::ErrorStatus TchPrivate::WriteCurveList(AcDbDwgFiler *pFiler, const TDPtrList<TGGeCurveSegment> &lstSegs)
{
Adesk::UInt16 nCount = (Adesk::UInt16)lstSegs.Length();;
pFiler->writeItem(nCount);
for (Adesk::UInt16 i = 0U; i < nCount; i++)
{
TchPrivate::WriteCurve(pFiler, lstSegs[(int)i]);
}
return pFiler->filerStatus();
}
// 用两个区域对一曲线进行裁剪, 剩下最长的曲线作为代表
TGGeCurveSegment TchPrivate::GetMaxCurveAfterClip(const TGGeCurveSegment &cvSource, const TGGePoly2D &sPoly, const TGGePoly2D &ePoly)
{
TGGeCurveSegment cvOffset = cvSource;
cvOffset.SetLineFlag(LS_FINITE);
TDPtrList<TGGeCurveSegment> lstSource, lstIn, lstOut, lstEdge;
lstSource.Append(new TGGeCurveSegment(cvOffset));
for (int nFrom = 0; nFrom < 2; nFrom++)
{
//起点裁剪和终点裁剪
const TGGePoly2D &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 TGGeCurveSegment(*lstOut[i]));
}
}
}
// 取裁剪后最长的边线作为代表(经验解)
if (!lstSource)
{
cvOffset = cvSource;
cvOffset.SetEndPoint(cvOffset.GetStartPoint());
}
else
{
TGGeCurveSegment *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;
}
// 用两个区域对一曲线进行裁剪, 剩下的包含给定的点作为返回
TGGeCurveSegment TchPrivate::GetCurveContainPointAfterClip(TADSGePoint3d ptPick,
const TGGeCurveSegment &cvSource, const TGGePoly2D &sPoly, const TGGePoly2D &ePoly)
{
TGGeCurveSegment cvOffset = cvSource;
cvOffset.SetLineFlag(LS_FINITE);
TDPtrList<TGGeCurveSegment> lstSource, lstIn, lstOut, lstEdge;
lstSource.Append(new TGGeCurveSegment(cvOffset));
for (int nFrom = 0; nFrom < 2; nFrom++)
{
//起点裁剪和终点裁剪
const TGGePoly2D &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 TGGeCurveSegment(*lstOut[i]));
}
}
}
if (!lstSource)
{
cvOffset = cvSource;
cvOffset.SetEndPoint(cvOffset.GetStartPoint());
}
else
{
BOOL bFind = FALSE;
for (int i = 0; i < lstSource.Length(); i++)
{
TGGeCurveSegment &seg = *lstSource[i];
TADSGePoint3d ptPrj;
if (seg.ProjectToMe(ptPick, ptPrj) == RTNORM && (ptPrj & seg) == PR_INSIDE)
{
cvOffset = seg;
bFind = TRUE;
break;
}
}
if (!bFind)
{
TGGeCurveSegment *pMax = lstSource[0];
for ( i = 1; i < lstSource.Length(); i++)
{
if (lstSource[i]->GetLength() > pMax->GetLength())
{
pMax = lstSource[i];
}
}
cvOffset = *pMax;
}
}
cvOffset.SetLineFlag(cvSource.GetLineFlag());
return cvOffset;
}
int TchPrivate::MakeArcWallSeg(TGGiExplodeDrawBase &dc, const TGGeArc &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;
}
TGGeArc iArc = arc.Offset(-iDist);
TGGeArc oArc = arc.Offset(oDist);
TchPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
TchPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
return RTNORM;
}
void TchPrivate::MakeArcWallSeg(TGGiExplodeDrawBase &dc, const TGGeArc &iArc, const TGGeArc &oArc, ads_real height, int bShowStart, int bShowEnd)
{
TchPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
TchPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
}
// 对xBeg开始,以步长nStep共nDivNum步,高度为nHeight,进行镶嵌,
// 结果存入lstSectFaces。bHasTop, bHasBot, bHasLeft, bHasRight,外围边的可见性
void TchPrivate::Tessellate(TDPtrList<TGGe3DFace> &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;
TGGe3DFace *pFace = new TGGe3DFace;
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, TADSGePoint3d(nPrev, 0.0));
pFace->SetVertex(1, TADSGePoint3d(nNext, 0.0));
pFace->SetVertex(2, TADSGePoint3d(nNext, nHeight));
pFace->SetVertex(3, TADSGePoint3d(nPrev, nHeight));
lstSectFaces.Append(pFace);
nPrev = nNext;
}
}
// 把平面(含洞口)的模型,化解为三角形
// z坐标全部为0
int TchPrivate::AsTriangleFaces(const TGGePolygonEx &polyOut, const TDPtrList<TGGePoly2D> &lstHoles,
TDPtrList<TGGe3DFace> &lstFaces)
{
TGGeTrianglePface lstTris;
if (TchPrivate::Triangulate(polyOut, lstHoles, lstTris))
{
int nFlag = 0;
for (int n = 0; n < lstTris.Length(); n++)
{
TGGeTriangle *triangle = lstTris[n];
ASSERT(triangle);
TGGe3DFace *pFace = new TGGe3DFace;
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 TchPrivate::AsTriangleFaces(const TGGePoly2D &polyOut, const TDPtrList<TGGePoly2D> &lstHoles, TDPtrList<TGGe3DFace> &lstFaces)
{
TGGePoly poly1;
((TGGePoly2D &)polyOut).MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation));
ASSERT(poly1.Length() > 2);
TGGePolygonEx polyEx1(poly1);
if (polyEx1.PathArea() > 0.0)
{
polyEx1.Reverse();
}
return TchPrivate::AsTriangleFaces(polyEx1, lstHoles, lstFaces);
}
BOOL TchPrivate::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 TchPrivate::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 TchPrivate::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 TchPrivate::CreateBlock(CEntityList& entLst,CString& blockName,AcDbObjectId& blockId,AcGePoint3d org)
{
if (!TchPrivate::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)
{
TAcDbEntityPtr* pEnt = entLst.GetNext(pos);
pBlockTableRecord->appendAcDbEntity(pEnt->m_pAcDbEnt);
pEnt->m_pAcDbEnt->close();
}
pBlockTableRecord->close();
return 1;
}
AcDbObjectId TchPrivate::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 TchPrivate::ReleaseC3DFaceList(TAcDbFacePtrList& c3dfaceLst)
{
POSITION pos = c3dfaceLst.GetHeadPosition();
while (pos != NULL)
{
TAcDbFacePtr* pC3DFace = c3dfaceLst.GetNext(pos);
delete pC3DFace;
}
c3dfaceLst.RemoveAll();
}
void TchPrivate::ReleaseCEntityList(CEntityList& centityLst)
{
POSITION pos = centityLst.GetHeadPosition();
while (pos != NULL)
{
TAcDbEntityPtr* pEnt = centityLst.GetNext(pos);
delete pEnt;
}
centityLst.RemoveAll();
}
void TchPrivate::SetLayerOfEntities(CEntityList& entLst,CString layerName, int colorNum)
{
SetLayer(layerName, colorNum);
POSITION pos = entLst.GetHeadPosition();
while (pos != NULL)
{
TAcDbEntityPtr* pEnt = entLst.GetNext(pos);
pEnt->m_pAcDbEnt->setLayer(layerName);
pEnt->m_pAcDbEnt->setColorIndex(256);
}
}
BOOL TchPrivate::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 TchPrivate::SetLayer(CString layerName, int colorNum)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
layerName = _T("0");
}
if (TchPrivate::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 TchPrivate::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 TchPrivate::C3DFaceList2EntityList(TAcDbFacePtrList& c3dFaceLst,CEntityList& entLst)
{
POSITION pos = c3dFaceLst.GetTailPosition();
while (pos != NULL)
{
TAcDbFacePtr* pNode = c3dFaceLst.GetPrev(pos);
TAcDbEntityPtr* pCEnt = new TAcDbEntityPtr(pNode->m_p3DFace);
entLst.AddTail(pCEnt);
}
}
BOOL TchPrivate::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 TchPrivate::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 TchPrivate::WCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
TchPrivate::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);
TchPrivate::Ads2ARXPt(ads_ret,pt);
}
void TchPrivate::UCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
TchPrivate::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);
TchPrivate::Ads2ARXPt(ads_ret,pt);
}
void TchPrivate::UCS2WCS(AcGePoint3d& pt,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
TchPrivate::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);
TchPrivate::Ads2ARXPt(ads_ret,pt);
}
void TchPrivate::WCS2UCS(AcGePoint3d& pt,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
TchPrivate::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);
TchPrivate::Ads2ARXPt(ads_ret,pt);
}
void TchPrivate::ECS2UCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
TchPrivate::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);
TchPrivate::Ads2ARXPt(ads_ret,pt);
}
void TchPrivate::ECS2WCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
TchPrivate::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);
TchPrivate::Ads2ARXPt(ads_ret,pt);
}
BOOL TchPrivate::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 TchPrivate::IsEqualSign(double x1,double x2)
{
if (x1 > fTOL && x2 > fTOL)
{
return 1;
}
if (x1 < fTOL && x2 < fTOL)
{
return 1;
}
return 0;
}
int TchPrivate::TXdataExtract(struct resbuf **rb, int *num)
{
if ((*rb) && ((*rb)->restype == 1070))
{
*num = (*rb)->resval.rint;
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int TchPrivate::TXdataExtract(struct resbuf **rb, ads_real *num)
{
if ((*rb) && ((*rb)->restype == 1040))
{
*num = (*rb)->resval.rreal;
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int TchPrivate::TXdataExtractPt(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 TchPrivate::TXdataExtract(struct resbuf **rb, TCHAR *str)
{
if ((*rb) && ((*rb)->restype == 1000))
{
_tcscpy(str, (*rb)->resval.rstring);
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int TchPrivate::TXdataExtractHandle(struct resbuf **rb, TCHAR *str)
{
if ((*rb) && ((*rb)->restype == 1005))
{
_tcscpy(str, (*rb)->resval.rstring);
(*rb) = (*rb)->rbnext;
return(1);
}
else
{
return(0);
}
}
int TchPrivate::TXdataHandleAssocSingle(ads_name ent, int tag, ads_name assoc_ent)
{
struct resbuf *entdata, *xdata, *tmprb, *rb;
GetAppXdata(ent, NULL, &entdata, &xdata);
if ((entdata == NULL) || (xdata == NULL))
{
ads_relrb(entdata);
return(0);
}
if ((rb = GetXdataTagItem(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 TchPrivate::SetXdataTagItem(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 = GetXdataTagItem(*xdata, tag, &pretag_ptr)) == NULL)
{
if (!tag_xdata)
{
return;
}
rb = ads_newrb(1070);
rb->resval.rint = tag;
Add2Rblist(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 *TchPrivate::GetXdataTagItem(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 * TchPrivate::DetachXdataTagItem( struct resbuf *xdata, int tag)
{
struct resbuf *tmpxd, *tagptr, *pretag_ptr, *lagptr, *old_xdata;
int nested_list;
if ((tagptr = TchPrivate::GetXdataTagItem(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 TchPrivate::DeleteXdataTagItem(struct resbuf * xdata, int tag)
{
struct resbuf *tmp;
tmp = TchPrivate::DetachXdataTagItem(xdata, tag);
if (tmp)
{
ads_relrb(tmp);
return(1);
}
else
{
return(0);
}
}
void TchPrivate::AddXdataTagBraces(struct resbuf **tagdata)
{
struct resbuf *n;
n = ads_newrb(1002);
n->resval.rstring = _tcsdup(_T("{"));
Add2Rblist(tagdata, n, TRUE);
n = ads_newrb(1002);
n->resval.rstring = _tcsdup(_T("}"));
Add2Rblist(tagdata, n, FALSE);
}
int TchPrivate::GetAppXdata(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 TchPrivate::NewStringResbuf(struct resbuf *ebuf, const TCHAR * str,int code)
{
struct resbuf *rb;
if ((rb = GetResbufAtCode(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 TchPrivate::ModifyXPoly2D(TGGePoly2D& poly,TGGeCurveSegment seg)
{
if (poly.Length() < 2)
{
return;
}
TGGeCurveSegment cv;
poly.Nth(0,cv);
*poly.Head() = seg.GetStartPoint();
if (cv.Is(CURVE_ARC))
{
TGGeArc arc;
arc = cv.GetArc();
TVector3D 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))
{
TGGeArc arc;
arc = cv.GetArc();
TVector3D vt = seg.GetEndPoint() - arc.GetCenterPt();
arc.SetEndAngle(vt.AsAcGeVector2d().angle());
poly.SetBulge(poly.Length() - 2, arc.Bulge());
}
}
void TchPrivate::ModifyXPoly2DStart(TGGePoly2D& poly,TGGeCurveSegment seg)
{
if (poly.Length() < 2)
{
return;
}
TGGeCurveSegment cv;
poly.Nth(0,cv);
*poly.Head() = seg.GetStartPoint();
if (cv.Is(CURVE_ARC))
{
TGGeArc arc;
arc = cv.GetArc();
TVector3D vt = seg.GetStartPoint() - arc.GetCenterPt();
arc.SetStarAngle(vt.AsAcGeVector2d().angle());
poly.SetBulge(0, arc.Bulge());
}
}
void TchPrivate::ModifyXPoly2DEnd(TGGePoly2D& poly,TGGeCurveSegment seg)
{
if (poly.Length() < 2)
{
return;
}
TGGeCurveSegment cv;
poly.Nth(poly.TotalSegments() - 1,cv);
*poly.Tail() = seg.GetEndPoint();
if (cv.Is(CURVE_ARC))
{
TGGeArc arc;
arc = cv.GetArc();
TVector3D vt = seg.GetEndPoint() - arc.GetCenterPt();
arc.SetEndAngle(vt.AsAcGeVector2d().angle());
poly.SetBulge(poly.Length() - 2, arc.Bulge());
}
}
void TchPrivate::StringToList(const TCHAR *s, TCStringList &res, TCHAR cSep)
{
const TCHAR *pBeg = s;
const TCHAR *pEnd = NULL;
do
{
pEnd = _tcschr(pBeg, cSep);
TCString sTemp(1024);
StrCpy(sTemp, pBeg, pEnd);
res.Append(tstrnew(sTemp));
if (pEnd)
{
pBeg = pEnd + 1;
}
} while(pEnd != NULL);
}
int TchPrivate::MergeCurve(TGGeCurveSegment &curve, TGGeCurveSegment &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 (IsSameDrt(curve.TGGeLine::Direction(), seg.TGGeLine::Direction(), _angSnap))
{
curve.SetEndPoint(seg.GetEndPoint());
bMerged = 1;
}
}
else
{
TGGeArc arc1 = curve.GetArc();
TGGeArc 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 TchPrivate::CircleToPoly(const TGGeCircle &cir, TGGePoly &poly, int nDiv)
{
double nAng = PI * 2.0 / nDiv;
poly.Reset();
for (int i = 0; i < nDiv; i++)
{
TADSGePoint3d ptVertex;
ads_polar(cir.GetCenterPt(), i * nAng, cir.GetRadius(), ptVertex);
poly.Append(new TADSGePoint3d(ptVertex));
}
}
AcDbObject* TchPrivate::GetDbConfigObjFromDict(AcDbDictionary *pXDict, AcDb::OpenMode mode)
{
Acad::ErrorStatus es=Acad::eOk;
AcDbObjectId idExist;
AcDbObject *pIObj = NULL;
es = pXDict->getAt(_T("ATS_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("ATS_DBCONFIG"), pIObj, id);
ASSERT(es == Acad::eOk);
}
pXDict->downgradeOpen();
}
}
return pIObj;
}
AcDbObject * TchPrivate::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 = TchPrivate::GetDbConfigObjFromDict(pNamedObj, opMode);
pNamedObj->close();
}
return pInitSet;
}
//modify by xlc on 100310 从tch_kernal工程移入
AcDbObjectId TchPrivate::InitDynTextStyle()
{
AcDbObjectId idRet=GetTextStyleId(_T("_TCH_DYN"));
if(!idRet)
{
AcDbTextStyleTableRecord *pStyle=new AcDbTextStyleTableRecord;
pStyle->setName(_T("_TCH_DYN"));
#if ADS < 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;
}
TConfigBase* g_pGlobalConfigBase = NULL;
TConfigBase* TchPrivate::GetGlobalConfigBase()
{
return NULL;
if (g_pGlobalConfigBase == NULL)
{
AcDbObject* pObj = TchPrivate::GetDwgGlobalObj(AcDb::kForRead,g_pCurrentDb);
if (pObj != NULL)
{
g_pGlobalConfigBase = (TConfigBase*)pObj->xData(_T("TDbConfig"));
pObj->close();
}
}
return g_pGlobalConfigBase;
}
BOOL DocGetCurMeterUnitDraw()
{
BOOL bMeterUnitDraw = FALSE;
TConfigBase* pBase = GetGlobalConfigBase();
if (pBase != NULL)
{
bMeterUnitDraw = pBase->DocGetMeterUnitDraw();
}
return bMeterUnitDraw;
}