3899 lines
76 KiB
C++
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;
|
|
}
|