4317 lines
107 KiB
C++
4317 lines
107 KiB
C++
//-------------------------------------------------------------------------------------------------------+
|
||
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
||
// = FileName : 导出全局函数头文件
|
||
// = Version : ver2.0
|
||
// = Author : zjq
|
||
// = CreateDate : 2002-09-09
|
||
// = Description: 全局函数的声明
|
||
// = Maintainers:
|
||
//
|
||
//-------------------------------------------------------------------------------------------------------+
|
||
|
||
#include "StdAfx.h"
|
||
#include "XGlobalFunc.h"
|
||
#include "XPoly.h"
|
||
#include "XCircle.h"
|
||
#include "XRectAngle.h"
|
||
#include "XScreenDc.h"
|
||
#include "XPushVar.h"
|
||
#include "XPushMemVar.h"
|
||
#include "XSearchRegionFromCurve.h"
|
||
#include "XSearchRegionFromCurve.h"
|
||
#include "XRegion.h"
|
||
#include "XDbObject.h"
|
||
#include "DStack.h"
|
||
#include "XBlockTableRecPtr.h"
|
||
#include "XDirectionCurve.h"
|
||
#include "XCurveSegInters.h"
|
||
#include "XCurveIntersection.h"
|
||
#include "CTempTol.h"
|
||
#include "XConfigBase.h"
|
||
#include "XHoleModel.h"
|
||
#include "AEntityBase.h"
|
||
|
||
#include "XGlobalFunc.h"
|
||
#include "XGlobalCurveFunc.h"
|
||
#include "XPrivateGlobalFunc.h"
|
||
|
||
#if ARX > 17
|
||
#include "AcStatusBar.h"
|
||
#include "AecDbGrip.h"
|
||
#include "AecDbGripDistDim.h"
|
||
#include "AecDbGripAngleDim.h"
|
||
#include "AecDbGripRadiusDim.h"
|
||
#endif
|
||
|
||
#include "XCurveInline.h"
|
||
|
||
static int CompareDouble(const double *p1, const double *p2)
|
||
{
|
||
if(*p1>*p2)
|
||
return 1;
|
||
return -1;
|
||
}
|
||
|
||
static int CompareDouble(double x1, double x2)
|
||
{
|
||
if (fabs(x1 - x2) < _DIST_SNAP)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
if (x1 < x2)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
static void GetPolyRect(const XPoint &ptCorn1, double nAngle, const XPoint &ptCorn2, XPoly2D &poly)
|
||
{
|
||
poly.Reset();
|
||
poly.SetFlag(1);
|
||
|
||
XPoint pt1, pt2;
|
||
|
||
XLine lnSide1(ptCorn1, nAngle);
|
||
XLine lnSide2(ptCorn2, nAngle + PI / 2.0);
|
||
lnSide1.Intersection(&lnSide2, pt1);
|
||
|
||
XLine lnSide3(ptCorn1, nAngle + PI / 2.0);
|
||
XLine lnSide4(ptCorn2, nAngle);
|
||
lnSide3.Intersection(&lnSide4, pt2);
|
||
|
||
poly.AppendNode(ptCorn1);
|
||
poly.AppendNode(pt1);
|
||
poly.AppendNode(ptCorn2);
|
||
poly.AppendNode(pt2);
|
||
}
|
||
|
||
static XPoly2D g_polyRect;
|
||
static double g_nRot;
|
||
static XPoint g_ptCorn1;
|
||
|
||
#if ARX > 22
|
||
static bool MouseMoveMonitor(MSG* msg)
|
||
#else
|
||
static BOOL MouseMoveMonitor(MSG* msg)
|
||
#endif
|
||
{
|
||
if (!acdbCurDwg())
|
||
{
|
||
return FALSE;
|
||
}
|
||
BOOL bRet = FALSE;
|
||
switch(msg->message)
|
||
{
|
||
case WM_MOUSEMOVE:
|
||
{
|
||
CPoint ptClient = msg->pt;
|
||
acedGetAcadDwgView()->ScreenToClient(&ptClient);
|
||
int nVpNum = acedGetWinNum(ptClient.x, ptClient.y);
|
||
int nCurVp = 0;
|
||
VERIFY(xg_getvar(_T("CVPORT"), &nCurVp) == RTNORM);
|
||
if (nVpNum == nCurVp)
|
||
{
|
||
XPoint ptDwgWcs, ptDwgDcs;
|
||
BOOL nRetCode = TRUE;
|
||
if (acedCoordFromPixelToWorld(nVpNum, ptClient, ptDwgWcs))
|
||
{
|
||
XScreenDc dc(-1);
|
||
if (g_polyRect.Length())
|
||
{
|
||
dc << g_polyRect;
|
||
}
|
||
|
||
XPoint ptDwgUcs = Wcs2Ucs(ptDwgWcs);
|
||
ptDwgUcs.z = g_ptCorn1.z;
|
||
GetPolyRect(g_ptCorn1, g_nRot, ptDwgUcs, g_polyRect);
|
||
dc << g_polyRect;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
return bRet;
|
||
}
|
||
|
||
static int GetRectAngle(const XPoint &ptCorn1, double nAngle, XPoint &ptCorn2)
|
||
{
|
||
int nRet = RTNORM;
|
||
g_polyRect.Reset();
|
||
g_polyRect.SetFlag(1);
|
||
g_nRot = nAngle;
|
||
g_ptCorn1 = ptCorn1;
|
||
acedRegisterFilterWinMsg(MouseMoveMonitor);
|
||
nRet = ads_getpoint(NULL, _T(""), ptCorn2);
|
||
acedRemoveFilterWinMsg(MouseMoveMonitor);
|
||
g_polyRect.Reset();
|
||
ads_redraw(NULL,0);
|
||
return nRet;
|
||
}
|
||
|
||
int XExport2::GetRectAngleStatic(const XPoint &ptCorn1, double nAngle, XPoint &ptCorn2)
|
||
{
|
||
return GetRectAngle(ptCorn1, nAngle, ptCorn2);
|
||
}
|
||
|
||
int XExport2::XGetCorner(const XPoint &ptCorn1, const TCHAR *pszMsg, XPoint &ptCorn2)
|
||
{
|
||
if (pszMsg)
|
||
{
|
||
XGeLib::adsout << pszMsg;
|
||
}
|
||
return GetRectAngle(ptCorn1, 0.0, ptCorn2);
|
||
}
|
||
|
||
XCell* XExport2::GetShape(const Point& pickPt)
|
||
{
|
||
XPushVar<int> vOsMode(_T("OSMODE"), 0);
|
||
|
||
Entity eL, entPline;
|
||
eL.GetLast();
|
||
if (SHads_command(RTSTR, _T("-BOUNDARY"), RTPOINT, &pickPt, RTSTR, _T(""), RTNONE) == RTNORM)
|
||
{
|
||
Entity entNew;
|
||
entNew.GetLast();
|
||
if (entNew == eL)
|
||
{
|
||
NULL;
|
||
}
|
||
else
|
||
{
|
||
entPline = entNew;
|
||
}
|
||
}
|
||
if (!entPline)
|
||
{
|
||
return NULL;
|
||
}
|
||
else
|
||
{
|
||
XCell* presult;
|
||
XPoly* pPoly = new XPoly(entPline);
|
||
ads_point ptcen;
|
||
double dw, dh;
|
||
if (pPoly->Length() == 2)
|
||
{
|
||
presult = new XCircle(*(*pPoly)[0], *(*pPoly)[1]);
|
||
}
|
||
else if (pPoly->IsRectAngle(ptcen, &dw, &dh))
|
||
{
|
||
presult = new XRectAngle(ptcen, dw, dh);
|
||
}
|
||
else
|
||
{
|
||
presult = NULL;
|
||
}
|
||
entPline.Delete();
|
||
|
||
PickSet ss(SS_FREE);
|
||
RBList fence = pPoly->Fence();
|
||
if (ss.Get(_T("F"), fence) == RTNORM)
|
||
{
|
||
ads_redraw(NULL, 0);
|
||
}
|
||
if (presult)
|
||
{
|
||
delete pPoly;
|
||
return presult;
|
||
}
|
||
return pPoly;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::ExplodeBlockRef(AcDbBlockTableRecord &blockRec, ads_matrix matForInsert, DList<AcDbEntity> &entSet)
|
||
{
|
||
AcGeMatrix3d mat;
|
||
memcpy(&mat, matForInsert, sizeof(ads_matrix));
|
||
|
||
AcDbBlockTableRecordIterator* pBlockIterator;
|
||
Acad::ErrorStatus es = blockRec.newIterator(pBlockIterator, Adesk::kTrue, Adesk::kFalse);
|
||
ASSERT(es == Acad::eOk);
|
||
|
||
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step())
|
||
{
|
||
AcDbEntity *pEntity;
|
||
es = pBlockIterator->getEntity(pEntity, AcDb::kForRead, Adesk::kTrue);
|
||
ASSERT(es == Acad::eOk);
|
||
|
||
if (pEntity->visibility() == AcDb::kInvisible)
|
||
{
|
||
pEntity->close();
|
||
continue;
|
||
}
|
||
|
||
if (pEntity->isKindOf(AcDbLine::desc()))
|
||
{
|
||
//显示LINE
|
||
AcDbLine *pLine = AcDbLine::cast(pEntity);
|
||
AcGePoint3d ptStart = pLine->startPoint(), ptEnd = pLine->endPoint();
|
||
ptStart.transformBy(mat);
|
||
ptEnd.transformBy(mat);
|
||
entSet.Append(new AcDbLine(ptStart, ptEnd));
|
||
}
|
||
else if (pEntity->isKindOf(AcDbArc::desc()))
|
||
{
|
||
AcDbArc *pArc = AcDbArc::cast(pEntity);
|
||
XPoint ptCen;
|
||
(AcGePoint3d &)ptCen = pArc->center();
|
||
XArc ar(ptCen, pArc->radius(), pArc->startAngle(), pArc->endAngle());
|
||
XPoint ptStart, ptEnd, ptMid;
|
||
ar.GetStartPoint(ptStart);
|
||
ar.GetEndPoint(ptEnd);
|
||
ar.MidPoint(ptMid);
|
||
((AcGePoint3d &)ptStart).transformBy(mat);
|
||
((AcGePoint3d &)ptEnd).transformBy(mat);
|
||
((AcGePoint3d &)ptMid).transformBy(mat);
|
||
XArc arNew(ptStart, ptMid, ptEnd);
|
||
entSet.Append(new AcDbArc(arNew.GetCenterPt(), arNew.GetRadius(), arNew.GetStarAngle(), arNew.GetEndAngle()));
|
||
}
|
||
else
|
||
{
|
||
AcDbEntity *pEntCopy = NULL;
|
||
if (pEntity->getTransformedCopy(mat, pEntCopy) == Acad::eOk && pEntCopy)
|
||
{
|
||
entSet.Append(pEntCopy);
|
||
}
|
||
}
|
||
|
||
pEntity->close();
|
||
}
|
||
delete pBlockIterator;
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 由二维曲线, 求若干个最外边界轮廓线
|
||
int XExport2::GetExternalBoundaryFromCurves(const DList<XCurveSegment> &lstSegs, DList<XPoly2D> &lstPolys)
|
||
{
|
||
if (!lstSegs.Length())
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
DList<XCurveSegment> ss;
|
||
for (int i = 0; i<lstSegs.Length(); i++)
|
||
{
|
||
XCurveSegment seg = lstSegs[i];
|
||
seg.SetElevation(0.0);
|
||
ss.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
if (ss.Length())
|
||
{
|
||
RemoveDupCurves(ss);
|
||
IntersectCurves(ss, _DIST_SNAP);
|
||
|
||
lstPolys.Reset();
|
||
SearchOutRegions(ss, lstPolys);
|
||
|
||
if (!!lstPolys)
|
||
{
|
||
return RTNORM;
|
||
}
|
||
}
|
||
return RTERROR;
|
||
}
|
||
|
||
//extern int CompareDouble(const double *p1, const double *p2);
|
||
void XExport2::IntersectCurves(DList<XCurveSegment> &lstCurves, double dPrec)
|
||
{
|
||
DList<XCurveSegment> ss1;
|
||
int nCount = lstCurves.Length();
|
||
for (int nn = 0; nn < nCount; nn++)
|
||
{
|
||
XCurveSegment *pSeg = lstCurves[nn];
|
||
if (!pSeg->Is(CURVE_CIRCLE) && pSeg->GetLength() > _DIST_SNAP)
|
||
{
|
||
XCurveSegment *pNewSeg = new XCurveSegment(*pSeg);
|
||
pNewSeg->SetLineFlag(LS_FINITE);
|
||
ss1.Append(pNewSeg);
|
||
}
|
||
}
|
||
|
||
int len1 = ss1.Length();
|
||
if (g_bEchoSearch)
|
||
{
|
||
acedSetStatusBarProgressMeter(_T("求交线"), 0, len1);
|
||
}
|
||
|
||
int nStep = len1/100;
|
||
if (nStep<1)
|
||
{
|
||
nStep = 1;
|
||
}
|
||
DList<double> *lstDistArray = new DList<double> [len1];
|
||
for (int nn = 0; nn<len1-1; nn++)
|
||
{
|
||
if (g_bEchoSearch && nStep>1 && !(nn%nStep))
|
||
{
|
||
acedSetStatusBarProgressMeterPos(nn);
|
||
}
|
||
XCurveSegment &line1 = *ss1[nn];
|
||
|
||
for (int kk = nn+1; kk<len1; kk++)
|
||
{
|
||
XCurveSegment &line2 = *ss1[kk];
|
||
XPoint ptInt[2];
|
||
int nInt = line1.Intersection(line2, ptInt[0], ptInt[1]);
|
||
for (int mm = 0; mm<nInt; mm++)
|
||
{
|
||
double nDist1 = line1.PathDistance(ptInt[mm]);
|
||
double nDist2 = line2.PathDistance(ptInt[mm]);
|
||
if (nDist1 < -_DIST_SNAP || nDist2 < -_DIST_SNAP)
|
||
{
|
||
#ifndef NDEBUG
|
||
XGeLib::adsout << _T("\nError found");
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
if (nDist1>_DIST_SNAP)
|
||
{
|
||
lstDistArray[nn].Append(new double(nDist1));
|
||
}
|
||
if (nDist2>_DIST_SNAP)
|
||
{
|
||
lstDistArray[kk].Append(new double(nDist2));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
lstCurves.Reset();
|
||
for (int nn = 0; nn<len1; nn++)
|
||
{
|
||
DList<double> &lstDistSeg = lstDistArray[nn];
|
||
XCurveSegment &line1 = *ss1[nn];
|
||
double nDist0 = line1.GetLength();
|
||
lstDistSeg.QuickSort(CompareDouble);
|
||
lstDistSeg.Append(new double(nDist0));
|
||
XPoint &ptStart = line1.StartPoint();
|
||
XPoint ptS = ptStart;
|
||
for (int kk = 0; kk<lstDistSeg.Length(); kk++)
|
||
{
|
||
XPointDir2d ptE;
|
||
line1.Polar(*lstDistSeg[kk], ptE);
|
||
if (ptS.Distance2d(ptE)>_DIST_SNAP)
|
||
{
|
||
XCurveSegment *pSeg = new XCurveSegment(line1);
|
||
pSeg->SetPoints(ptS, ptE);
|
||
lstCurves.Append(pSeg);
|
||
}
|
||
ptS = ptE;
|
||
}
|
||
}
|
||
|
||
delete [] lstDistArray;
|
||
if (g_bEchoSearch)
|
||
{
|
||
acedRestoreStatusBar();
|
||
}
|
||
}
|
||
|
||
void XExport2::RemoveDupCurves(DList<XCurveSegment> &lstCurves)
|
||
{
|
||
DList<XCurveSegment> lstLines, lstCirArcs;
|
||
ASSERT(lstCurves.GetDelFlag() != FALSE);
|
||
lstCurves.SetDelFlag(FALSE);
|
||
int nCount = lstCurves.Length();
|
||
for (int i = 0; i<nCount; i++)
|
||
{
|
||
XCurveSegment *pSeg = lstCurves[i];
|
||
if (pSeg->Is(CURVE_LINE))
|
||
{
|
||
lstLines.Append(pSeg);
|
||
}
|
||
else
|
||
{
|
||
lstCirArcs.Append(pSeg);
|
||
}
|
||
}
|
||
lstCurves.Reset();
|
||
lstCurves.SetDelFlag(TRUE);
|
||
|
||
{
|
||
XPushMemVar<BOOL> vTemp(g_bEchoSearch, FALSE);
|
||
_RemoveDupCurves(lstCirArcs);
|
||
|
||
lstCirArcs.SetDelFlag(FALSE);
|
||
nCount = lstCirArcs.Length();
|
||
for (int i = 0; i<nCount; i++)
|
||
{
|
||
lstCurves.Append(lstCirArcs[i]);
|
||
}
|
||
}
|
||
|
||
xdRemoveDupCurves(lstLines, FALSE, FALSE);
|
||
lstLines.SetDelFlag(FALSE);
|
||
nCount = lstLines.Length();
|
||
for (int i = 0; i<nCount; i++)
|
||
{
|
||
lstCurves.Append(lstLines[i]);
|
||
}
|
||
}
|
||
|
||
// 由二维曲线, 求最外边界轮廓线
|
||
int XExport2::GetExternalBoundaryFromCurves(const DList<XCurveSegment> &ss, XPoly2D &polyOutline)
|
||
{
|
||
DList<XCurveSegment> lstSegs;
|
||
for (int i = 0; i<ss.Length(); i++)
|
||
{
|
||
XCurveSegment seg = ss[i];
|
||
seg.SetElevation(0.0);
|
||
lstSegs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
RemoveDupCurves(lstSegs);
|
||
IntersectCurves(lstSegs,_DIST_SNAP);
|
||
|
||
XSearchRegionFromCurve aSearch;
|
||
try
|
||
{
|
||
aSearch.InitStart(lstSegs);
|
||
}
|
||
catch(...)
|
||
{
|
||
XGeLib::adsout << /*UMSG*/_T("\n发生例外情况!");
|
||
return RTERROR;
|
||
}
|
||
|
||
XRegion *pExt = aSearch.SearchRegions();
|
||
if (pExt)
|
||
{
|
||
pExt->CenterPoly2D(polyOutline);
|
||
polyOutline.Compress();
|
||
return RTNORM;
|
||
}
|
||
return RTERROR;
|
||
}
|
||
|
||
// 用区域裁剪实体
|
||
void XExport2::ClipEntitiesByPoly(XPoly2D & polyOutline, PickSet &ssBack)
|
||
{
|
||
PickSet ssBackInsert(SS_FREE), ssIn(SS_FREE), ssOut(SS_FREE), ssEdge(SS_FREE);
|
||
ssBackInsert += ssBack;
|
||
RBList rr((RTDXF0, _T("POLYLINE,LWPOLYLINE,INSERT,AEC_BLOCK_INSERT"), NULL));
|
||
ssBackInsert.BaseFilter(rr);
|
||
ssBack -= ssBackInsert;
|
||
|
||
// 裁剪曲线
|
||
PolyClip(ssBack, polyOutline, ssIn, ssOut, ssEdge);
|
||
if (ssIn.Length())
|
||
{
|
||
ssIn.Erase();
|
||
}
|
||
if (ssEdge.Length())
|
||
{
|
||
ssEdge.Erase();
|
||
}
|
||
|
||
// 裁剪图块
|
||
long lCount = ssBackInsert.Length();
|
||
for (long idx = 0L; idx<lCount; idx++)
|
||
{
|
||
Entity entBack = ssBackInsert[idx];
|
||
|
||
PickSet ss(SS_FREE);
|
||
BOOL bBlock = FALSE;
|
||
if (entBack.Is(_T("AEC_BLOCK_INSERT")) || entBack.Is(_T("INSERT")))
|
||
{
|
||
XExport::GetCurveFromInsert2D(entBack, ss);
|
||
bBlock = TRUE;
|
||
}
|
||
else//多段线
|
||
{
|
||
ss.IncludeBegin();
|
||
|
||
OPENOBJ_BEGIN(entBack,AcDb::kForRead,AcDbEntity,pEntity)
|
||
if (pEntity != NULL)
|
||
{
|
||
AcDbVoidPtrArray entSet;
|
||
pEntity->explode(entSet);
|
||
for (long i = 0;i<entSet.length();i++)
|
||
{
|
||
AcDbEntity*pNewEnt = (AcDbEntity*)entSet[i];
|
||
if (XExport::AddToCurrentSpace(pNewEnt,Adesk::kTrue) == AcDbObjectId::kNull)
|
||
{
|
||
delete pNewEnt;
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
ss.IncludeEnd();
|
||
}
|
||
|
||
if (ss.Length()>0)
|
||
{
|
||
PickSet ssIn(SS_FREE), ssOut(SS_FREE), ssEdge(SS_FREE);
|
||
PolyClip(ss,polyOutline, ssIn, ssOut,ssEdge);
|
||
if (ssOut.Length() > 0)//裁剪发生
|
||
{
|
||
if (ssIn.Length() > 0)
|
||
{
|
||
ssIn.Erase();
|
||
}
|
||
if (ssEdge.Length() > 0)
|
||
{
|
||
ssEdge.Erase();
|
||
}
|
||
|
||
if (bBlock)
|
||
{
|
||
XPoint ptInsert;
|
||
entBack.GetData(10, &ptInsert);
|
||
XString sNewBlockName(256);
|
||
if (ssOut.MakeAnonymous(ptInsert, sNewBlockName, FALSE) == RTNORM)
|
||
{
|
||
OPENOBJ_BEGIN(entBack, AcDb::kForWrite, AcDbBlockReference, pInsert);
|
||
if (pInsert)
|
||
{
|
||
pInsert->setBlockTableRecord(GetBlockIdFromString(sNewBlockName));
|
||
pInsert->setScaleFactors(AcGeScale3d(1.0,1.0,1.0));
|
||
pInsert->setRotation(0.0);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
entBack.Erase();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ss.Erase();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
int XExport2::GetClipBoundary(XPoly2D &poly2d)
|
||
{
|
||
const TCHAR *szPrompts[2] = {_T("\n矩形的第一个角点或 [多边形裁剪(P)]<退出>:"),
|
||
_T("\n多边形的第一点或 [矩形裁剪(R)]<退出>:")};
|
||
const TCHAR *szKeywords[2] = {_T("P"), _T("R")};
|
||
int nClipType = 0;
|
||
|
||
XPoint ptStart;
|
||
while(1)
|
||
{
|
||
XGeLib::adsout << szPrompts[nClipType];
|
||
int nCode;
|
||
INITGET_BEG(0, szKeywords[nClipType]);
|
||
nCode = ads_getpoint(NULL, _T(""), ptStart);
|
||
INITGET_END();
|
||
if (nCode == RTKWORD)
|
||
{
|
||
nClipType = 1 - nClipType;
|
||
}
|
||
else
|
||
{
|
||
if (nCode == RTNORM)
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
return nCode;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (nClipType == 0)
|
||
{
|
||
XPoint ptOther;
|
||
int nCode = XGetCorner(ptStart, _T("\n另一个角点<退出>:"), ptOther);
|
||
if (nCode != RTNORM)
|
||
{
|
||
return nCode;
|
||
}
|
||
XRectAngle rect(ptStart, ptOther);
|
||
rect.AsPoly2D(poly2d);
|
||
}
|
||
else
|
||
{
|
||
XPoint pt2;
|
||
XScreenDc dc;
|
||
dc.m_nDrawMode = 1;
|
||
DStack<XPoint> aStack;
|
||
aStack.Push(new XPoint(ptStart));
|
||
while(1)
|
||
{
|
||
XPoint &ptFrom = *aStack.Top();
|
||
if (aStack.Length() >= 3)
|
||
{
|
||
XGeLib::adsout << _T("\n下一点或 [回退(U)]<封闭>: ");
|
||
}
|
||
else
|
||
{
|
||
XGeLib::adsout << _T("\n下一点或 [回退(U)]<退出>: ");
|
||
}
|
||
int rc;
|
||
INITGET_BEG(0, _T("U"));
|
||
rc = ads_getpoint(ptFrom, _T(""), pt2);
|
||
INITGET_END();
|
||
if (rc == RTCAN)
|
||
{
|
||
aStack.Reset();
|
||
return rc;
|
||
}
|
||
else if (rc == RTKWORD)
|
||
{
|
||
if (*aStack.Top() != ptStart)
|
||
{// Not on first state
|
||
XPoint *pPt2 = aStack.Pop();
|
||
XPoint *pPt1 = aStack.Top();
|
||
dc.SetColor(-1);
|
||
dc << XLine(*pPt1, *pPt2);
|
||
delete pPt2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (rc == RTNONE)
|
||
{
|
||
if (aStack.Length() < 3)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
else
|
||
{
|
||
pt2 = ptStart;
|
||
}
|
||
}
|
||
|
||
XLine ln(*aStack.Top(), pt2);
|
||
if (ln.GetLength() > _DIST_SNAP)
|
||
{
|
||
dc.SetColor(7);
|
||
dc << ln;
|
||
if (!(rc == RTNONE))
|
||
{
|
||
aStack.Push(new XPoint(pt2));
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
poly2d.Reset();
|
||
XPoint *ptCur = NULL;
|
||
while((ptCur = aStack.Pop()) != NULL)
|
||
{
|
||
poly2d.AppendNode(*ptCur);
|
||
delete ptCur;
|
||
}
|
||
poly2d.Compress();
|
||
if (!poly2d || poly2d.Length() < 3)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
}
|
||
return RTNORM;
|
||
}
|
||
|
||
// 从块表中取所有的曲线: 包括LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE,以及在INSERT中的前述实体
|
||
void XExport2::Get2DCurveFromBlock(AcDbBlockTableRecord &blockRec, ads_matrix matForInsert, DList<XCurveSegment> &lstResult)
|
||
{
|
||
AcGeMatrix3d mat;
|
||
memcpy(&mat, matForInsert, sizeof(ads_matrix));
|
||
|
||
AcDbBlockTableRecordIterator* pBlockIterator = NULL;
|
||
Acad::ErrorStatus es = blockRec.newIterator(pBlockIterator, Adesk::kTrue, Adesk::kFalse);
|
||
ASSERT(es == Acad::eOk && !!pBlockIterator);
|
||
|
||
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step())
|
||
{
|
||
AcDbEntity *pEntity;
|
||
es = pBlockIterator->getEntity(pEntity, AcDb::kForRead, Adesk::kTrue);
|
||
ASSERT(es == Acad::eOk);
|
||
if (pEntity->visibility() == AcDb::kInvisible)
|
||
{
|
||
pEntity->close();
|
||
continue;
|
||
}
|
||
|
||
if (pEntity->isKindOf(AcDbLine::desc()))
|
||
{
|
||
//显示LINE
|
||
AcDbLine *pLine = AcDbLine::cast(pEntity);
|
||
XPoint ptStart = pLine->startPoint(),ptEnd = pLine->endPoint();
|
||
ptStart.TransformBy(matForInsert);
|
||
ptEnd.TransformBy(matForInsert);
|
||
lstResult.Append(new XCurveSegment(ptStart, ptEnd, 0.0));
|
||
}
|
||
else if (pEntity->isKindOf(AcDbArc::desc()))
|
||
{
|
||
AcDbArc *pArc = AcDbArc::cast(pEntity);
|
||
XPoint ptCen;
|
||
(AcGePoint3d &)ptCen = pArc->center();
|
||
XArc ar(ptCen, pArc->radius(), pArc->startAngle(), pArc->endAngle());
|
||
XPoint ptStart, ptEnd, ptMid;
|
||
ar.GetStartPoint(ptStart);
|
||
ar.GetEndPoint(ptEnd);
|
||
ar.MidPoint(ptMid);
|
||
((AcGePoint3d &)ptStart).transformBy(mat);
|
||
((AcGePoint3d &)ptEnd).transformBy(mat);
|
||
((AcGePoint3d &)ptMid).transformBy(mat);
|
||
XCurveSegment *pSeg = new XCurveSegment;
|
||
*pSeg = XArc(ptStart, ptMid, ptEnd);
|
||
lstResult.Append(pSeg);
|
||
}
|
||
else if (pEntity->isKindOf(AcDbCircle::desc()))
|
||
{ //圆的变换为近似, 不变半径
|
||
AcDbCircle *pCir = AcDbCircle::cast(pEntity);
|
||
XPoint ptCen = pCir->center();
|
||
ptCen.TransformBy(matForInsert);
|
||
XCurveSegment *pSeg = new XCurveSegment;
|
||
*pSeg = XCircle(ptCen, pCir->radius());
|
||
lstResult.Append(pSeg);
|
||
}
|
||
else if (pEntity->isKindOf(AcDbPolyline::desc()) || pEntity->isKindOf(AcDb2dPolyline::desc()))
|
||
{
|
||
AcDbPolyline pline;
|
||
Entity ent;
|
||
acdbGetAdsName(ent.name, pEntity->objectId());
|
||
if (!(!ent))
|
||
{
|
||
XPoly2D poly(ent);
|
||
if (!poly)
|
||
{
|
||
;
|
||
}
|
||
else
|
||
{
|
||
poly.TransUCS(matForInsert);
|
||
for (int i = 0; i<poly.TotalSegments(); i++)
|
||
{
|
||
XCurveSegment *pSeg = new XCurveSegment;
|
||
poly.Nth(i, *pSeg);
|
||
lstResult.Append(pSeg);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (pEntity->isKindOf(AcDbBlockReference::desc()))
|
||
{ //嵌套图块
|
||
AcDbBlockReference *pInsert = AcDbBlockReference::cast(pEntity);
|
||
ASSERT(pInsert);
|
||
XPoint ptLoc = pInsert->position();
|
||
double nRot = pInsert->rotation();
|
||
AcGeScale3d scale = pInsert->scaleFactors();
|
||
AcDbObjectId idBlock = pInsert->blockTableRecord();
|
||
XDbObject objBlock(idBlock, AcDb::kForRead);
|
||
ASSERT(!!objBlock);
|
||
AcDbBlockTableRecord *pRec = AcDbBlockTableRecord::cast(objBlock.m_pObject);
|
||
ASSERT(pRec);
|
||
XPoint ptBase = pRec->origin();
|
||
ads_matrix mat1, mat2;
|
||
get_matrix(ptBase, ptLoc, scale[0], scale[1], scale[2], nRot, mat1);
|
||
AT_multiply_matrix(matForInsert, mat1, mat2);
|
||
Get2DCurveFromBlock(*pRec, mat2, lstResult);
|
||
}
|
||
|
||
pEntity->close();
|
||
}
|
||
delete pBlockIterator;
|
||
}
|
||
|
||
// 由二维图块提取二维曲线段
|
||
int XExport2::GetCurveFromInsert2D(Entity &ent, DList<XCurveSegment> &lstSegs)
|
||
{
|
||
if (!ent.Is(_T("INSERT")) && !ent.Is(_T("AEC_BLOCK_INSERT")) && !ent.Is(_T("AEC_MVINSERT")))
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
ads_matrix mat;
|
||
GetInsertMatrix(ent, mat);
|
||
XString sBlockName(256);
|
||
int nCode = (ent.Is(_T("AEC_MVINSERT"))? 1 : 2);
|
||
VERIFY(ent.GetData(nCode, (TCHAR *)sBlockName) == RTNORM);
|
||
XBlockTableRecPtr rec(sBlockName, AcDb::kForRead);
|
||
ASSERT(!!rec);
|
||
|
||
Get2DCurveFromBlock(*rec.m_pBlockTableRec, mat, lstSegs);
|
||
return RTNORM;
|
||
}
|
||
|
||
// 有若干线搜索区域
|
||
int XExport2::SearchOutRegions(const DList<XCurveSegment> &lstSeg1In, DList<XPoly2D> &lstDest)
|
||
{
|
||
XSearchRegionFromCurve aSearch;
|
||
try
|
||
{
|
||
aSearch.InitStart(lstSeg1In);
|
||
}
|
||
catch(...)
|
||
{
|
||
XGeLib::adsout << /*UMSG*/_T("\n发生例外情况!");
|
||
return RTERROR;
|
||
}
|
||
|
||
|
||
if (aSearch.SearchRegions())
|
||
{
|
||
DList<int> lstOut;
|
||
if (aSearch.GetOutsideRegions1(lstOut) && !!lstOut)
|
||
{
|
||
for (int n = 0; n<lstOut.Length(); n++)
|
||
{
|
||
XPoly2D *pNewPoly = new XPoly2D(1);
|
||
VERIFY(aSearch.m_regions[*lstOut[n]]->CenterPoly2D(*pNewPoly) == RTNORM);
|
||
pNewPoly->Compress();
|
||
lstDest.Append(pNewPoly);
|
||
}
|
||
}
|
||
}
|
||
return RTNORM;
|
||
}
|
||
|
||
// 把Poly2D分解为若干段曲线
|
||
void XExport2::ExplodePoly2D(const XPoly2D &poly, DList<XCurveSegment> &lstSegs)
|
||
{
|
||
for (int i = 0; i<poly.TotalSegments(); i++)
|
||
{
|
||
XCurveSegment *pSeg = new XCurveSegment;
|
||
poly.Nth(i, *pSeg);
|
||
lstSegs.Append(pSeg);
|
||
}
|
||
}
|
||
|
||
// 把XPoly2D转换成AcDbPolyline
|
||
void XExport2::PolyConvert(const XPoly2D &poly, AcDbPolyline &pline)
|
||
{
|
||
pline.assertWriteEnabled(); //支持UNDO
|
||
|
||
AcGeVector3d vtNormal = pline.normal();
|
||
double nThick = pline.thickness();
|
||
double nWidth = 0;
|
||
|
||
Acad::ErrorStatus es = pline.getConstantWidth(nWidth);
|
||
pline.reset(Adesk::kFalse, 0);
|
||
|
||
for (int i = 0; i<poly.Length(); i++)
|
||
{
|
||
pline.addVertexAt(i, poly[i].AsAcGePoint2d(), tan(poly.GetBulge(i)/4));
|
||
}
|
||
|
||
pline.setClosed(poly.IsClosed());
|
||
if (poly.Length())
|
||
{
|
||
pline.setElevation(poly[0].z);
|
||
}
|
||
|
||
pline.setNormal(vtNormal);
|
||
pline.setThickness(nThick);
|
||
if (es == Acad::eOk)
|
||
{
|
||
pline.setConstantWidth(nWidth);
|
||
}
|
||
}
|
||
|
||
// 把AcDbPolyline转换成XPoly2D
|
||
void XExport2::PolyConvert(const AcDbPolyline &pline, XPoly2D &poly)
|
||
{
|
||
poly.Reset();
|
||
|
||
for (Adesk::UInt16 i = 0; i<pline.numVerts(); i++)
|
||
{
|
||
AcGePoint2d ptVert;
|
||
double nBulge = 0.0;
|
||
pline.getPointAt(i, ptVert);
|
||
pline.getBulgeAt(i, nBulge);
|
||
|
||
XPoint pt;
|
||
pt = ptVert;
|
||
nBulge = atan(nBulge)*4;
|
||
poly.AppendNode(pt, nBulge);
|
||
}
|
||
|
||
if (pline.isClosed())
|
||
{
|
||
poly.SetFlag(poly.GetFlag() | 0x01);
|
||
}
|
||
else
|
||
{
|
||
poly.SetFlag(0);
|
||
}
|
||
|
||
poly.SetElevation(pline.elevation());
|
||
}
|
||
|
||
// 支持3D
|
||
AcDbRegion* XExport2::AsRegion(const XPoly2D &poly)
|
||
{
|
||
if (!poly.IsClosed())
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
XPoly2D polyCopy(1);
|
||
poly.Disperse1(polyCopy, _AS_SYS_UNIT(g_nCirDeviation));
|
||
|
||
AcDbVoidPtrArray curveSegments;
|
||
for (int j = 0; j<polyCopy.Length();j++)
|
||
{
|
||
XCurveSegment seg;
|
||
polyCopy.Nth(j, seg);
|
||
if (seg.GetLength()>_DIST_SNAP)
|
||
{
|
||
curveSegments.append(new AcDbLine(seg.GetStartPoint(), seg.GetEndPoint()));
|
||
}
|
||
}
|
||
|
||
AcDbVoidPtrArray regions;
|
||
if (AcDbRegion::createFromCurves(curveSegments, regions) == Acad::eOk && regions.length()>0)
|
||
{
|
||
AcDbRegion *regioni = (AcDbRegion *)regions[0];
|
||
regions.removeAt(0);
|
||
|
||
XExport::ReleaseEntSet(regions);
|
||
XExport::ReleaseEntSet(curveSegments);
|
||
return regioni;
|
||
}
|
||
|
||
XExport::ReleaseEntSet(curveSegments);
|
||
return NULL;
|
||
}
|
||
|
||
int XExport2::FindNearestEdge(const XPoly2D &poly, const XPoint &ptEdge)
|
||
{
|
||
int nEdge = -1;
|
||
double nNearDist = 0.0;
|
||
for (int i = 0; i<poly.TotalSegments(); i++)
|
||
{
|
||
XCurveSegment seg;
|
||
poly.Nth(i, seg);
|
||
XPoint ptOnEdge;
|
||
if (seg.ProjectToMe(ptEdge, ptOnEdge) == RTNORM && (ptOnEdge&seg) == PR_INSIDE)
|
||
{
|
||
double nDist = ptEdge.Distance2d(ptOnEdge);
|
||
if (nEdge == -1)
|
||
{
|
||
nEdge = i;
|
||
nNearDist = nDist;
|
||
}
|
||
else if (nDist<nNearDist)
|
||
{
|
||
nEdge = i;
|
||
nNearDist = nDist;
|
||
}
|
||
}
|
||
}
|
||
return nEdge;
|
||
}
|
||
|
||
|
||
AcDbHatch * XExport2::NewHatchFromPoly2D(const XPoly2D &poly)
|
||
{
|
||
ASSERT(poly.IsClosed());
|
||
|
||
AcGeDoubleArray bulges;
|
||
AcGePoint2dArray vertices;
|
||
|
||
int nVert = poly.Length();
|
||
|
||
AcDbHatch *pHatch = new AcDbHatch();
|
||
pHatch->setAssociative(Adesk::kFalse);
|
||
pHatch->setPattern(AcDbHatch::kPreDefined,_T("SOLID"));
|
||
pHatch->setHatchStyle(AcDbHatch::kNormal);
|
||
bulges.setPhysicalLength(0).setLogicalLength(nVert + 1);
|
||
vertices.setPhysicalLength(0).setLogicalLength(nVert + 1);
|
||
|
||
int i(0);
|
||
for (i = 0; i<nVert; i++)
|
||
{
|
||
vertices[i] = poly[i];
|
||
bulges[i] = tan(poly.GetBulge(i)/4);
|
||
}
|
||
|
||
vertices[i] = vertices[0];
|
||
bulges[i] = bulges[0];
|
||
|
||
pHatch->appendLoop(AcDbHatch::kExternal|AcDbHatch::kPolyline|AcDbHatch::kDerived,vertices,bulges);
|
||
pHatch->evaluateHatch(true);
|
||
|
||
return pHatch;
|
||
}
|
||
|
||
AcDbHatch * XExport2::NewHatchFromPoly2D(const XPoly2D &poly, const TCHAR *pszPattern0, double nScl)
|
||
{
|
||
XString sPattern;
|
||
sPattern = pszPattern0;
|
||
TCHAR *pScale = sPattern.StrChr(_T(':'));
|
||
if (pScale)
|
||
{
|
||
*pScale = EOS;
|
||
pScale++;
|
||
double nScaleAdd = _tstof(pScale);
|
||
if (nScaleAdd > 1.0E-6)
|
||
{
|
||
nScl *= nScaleAdd;
|
||
}
|
||
}
|
||
|
||
AcGeDoubleArray bulges;
|
||
AcGePoint2dArray vertices;
|
||
|
||
int nVert = poly.Length();
|
||
|
||
AcDbHatch *pHatch = new AcDbHatch();
|
||
pHatch->setAssociative(Adesk::kFalse);
|
||
pHatch->setPatternScale(nScl);
|
||
pHatch->setHatchStyle(AcDbHatch::kNormal);
|
||
if (pHatch->setPattern(AcDbHatch::kPreDefined, sPattern) != Acad::eOk)
|
||
{
|
||
delete pHatch;
|
||
return NULL;
|
||
}
|
||
|
||
bulges.setPhysicalLength(0).setLogicalLength(nVert+1);
|
||
vertices.setPhysicalLength(0).setLogicalLength(nVert+1);
|
||
|
||
int i(0);
|
||
for (i = 0; i<nVert; i++)
|
||
{
|
||
vertices[i] = poly[i];
|
||
bulges[i] = tan(poly.GetBulge(i)/4);
|
||
}
|
||
vertices[i] = vertices[0];
|
||
bulges[i] = bulges[0];
|
||
|
||
pHatch->appendLoop(AcDbHatch::kExternal | AcDbHatch::kPolyline | AcDbHatch::kDerived, vertices, bulges);
|
||
Acad::ErrorStatus es;
|
||
if ((es = pHatch->evaluateHatch(true)) != Acad::eOk)
|
||
{
|
||
delete pHatch;
|
||
return NULL;
|
||
}
|
||
|
||
return pHatch;
|
||
}
|
||
|
||
AcDbHatch * XExport2::NewHatchFromPoly2D(const XPoly2D &poly, const TCHAR *pszPattern0, double nScl,double rotation)
|
||
{
|
||
XString sPattern;
|
||
sPattern = pszPattern0;
|
||
TCHAR *pScale = sPattern.StrChr(_T(':'));
|
||
if (pScale)
|
||
{
|
||
*pScale = EOS;
|
||
pScale++;
|
||
double dScaleAdd = _tstof(pScale);
|
||
if (dScaleAdd > 1.0E-6)
|
||
{
|
||
nScl *= dScaleAdd;
|
||
}
|
||
}
|
||
|
||
AcGeDoubleArray bulges;
|
||
AcGePoint2dArray vertices;
|
||
|
||
int nVert = poly.Length();
|
||
|
||
AcDbHatch *pHatch = new AcDbHatch();
|
||
pHatch->setAssociative(Adesk::kFalse);
|
||
pHatch->setPatternScale(nScl);
|
||
pHatch->setPatternAngle(rotation);
|
||
pHatch->setHatchStyle(AcDbHatch::kNormal);
|
||
if (pHatch->setPattern(AcDbHatch::kPreDefined, sPattern) != Acad::eOk)
|
||
{
|
||
delete pHatch;
|
||
return NULL;
|
||
}
|
||
|
||
bulges.setPhysicalLength(0).setLogicalLength(nVert + 1);
|
||
vertices.setPhysicalLength(0).setLogicalLength(nVert + 1);
|
||
|
||
int i(0);
|
||
for (i = 0; i<nVert; i++)
|
||
{
|
||
vertices[i] = poly[i];
|
||
bulges[i] = tan(poly.GetBulge(i)/4);
|
||
}
|
||
vertices[i] = vertices[0];
|
||
bulges[i] = bulges[0];
|
||
|
||
pHatch->appendLoop(AcDbHatch::kExternal|AcDbHatch::kPolyline|AcDbHatch::kDerived,vertices,bulges);
|
||
Acad::ErrorStatus es;
|
||
if ((es = pHatch->evaluateHatch(true)) != Acad::eOk)
|
||
{
|
||
delete pHatch;
|
||
return NULL;
|
||
}
|
||
|
||
return pHatch;
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::ReadPoly2D(AcDbDwgFiler *pFiler, XPoly2D &poly)
|
||
{
|
||
Adesk::UInt8 bIsClosed = 0;
|
||
pFiler->readItem(&bIsClosed);
|
||
Adesk::UInt16 nVertexCount = 0;
|
||
pFiler->readItem(&nVertexCount);
|
||
poly.Reset();
|
||
poly.SetFlag(bIsClosed);
|
||
for (Adesk::UInt16 i = 0; i<nVertexCount; i++)
|
||
{
|
||
AcGePoint2d pt;
|
||
double bulge;
|
||
pFiler->readItem(&pt);
|
||
pFiler->readItem(&bulge);
|
||
poly.AppendNode(XPoint(pt[0],pt[1], 0.0), bulge);
|
||
}
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::WritePoly2D(AcDbDwgFiler *pFiler, const XPoly2D &poly)
|
||
{
|
||
pFiler->writeItem((Adesk::UInt8)poly.GetFlag());
|
||
Adesk::UInt16 nVertexCount = poly.Length();
|
||
pFiler->writeItem(nVertexCount);
|
||
for (Adesk::UInt16 i = 0; i<nVertexCount; i++)
|
||
{
|
||
pFiler->writeItem(poly[i].AsAcGePoint2d());
|
||
pFiler->writeItem(poly.GetBulge(i));
|
||
}
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
int XExport2::_SplitPoly2D(const XPoly2D &poly, const XPoint &pt1, const XPoint &pt2, XPoly2D &res1, XPoly2D &res2)
|
||
{
|
||
ASSERT(poly.IsClosed());
|
||
XPoint ptBreak[2] = {pt1, pt2};
|
||
XPoint ptOnPoly[2] = {pt1, pt2};
|
||
int nBreakIndex[2] = {-1,-1};
|
||
double minDist[2] = {-1.0, -1.0};
|
||
|
||
int nSeg = poly.TotalSegments();
|
||
for (int i = 0; i<nSeg; i++)
|
||
{
|
||
XCurveSegment seg;
|
||
poly.Nth(i, seg);
|
||
for (int n = 0; n<2; n++)
|
||
{
|
||
XPoint ptPrj;
|
||
if (seg.ProjectToMe(ptBreak[n], ptPrj) == RTNORM)
|
||
{
|
||
int nPrFlag = (ptPrj&seg);
|
||
if (nPrFlag == PR_INSIDE || nPrFlag == PR_ONPT1 || nPrFlag == PR_ONPT2)
|
||
{
|
||
double nDist = ads_distance(ptBreak[n], ptPrj);
|
||
if (minDist[n]<-1.0E-3)
|
||
{
|
||
minDist[n] = nDist;
|
||
nBreakIndex[n] = i;
|
||
ptOnPoly[n] = ptPrj;
|
||
}
|
||
else if (nDist<minDist[n])
|
||
{
|
||
minDist[n] = nDist;
|
||
nBreakIndex[n] = i;
|
||
ptOnPoly[n] = ptPrj;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (nBreakIndex[0]<0 || nBreakIndex[1]<0)
|
||
{
|
||
return RTERROR; //找不到切断点
|
||
}
|
||
|
||
int minIndex, maxIndex;
|
||
XPoint ptMin, ptMax;
|
||
if (nBreakIndex[0] == nBreakIndex[1])
|
||
{
|
||
//在同一段,靠近起点为小,靠近终点为大
|
||
XDirectionCurve cvTemp;
|
||
poly.Nth(nBreakIndex[0], cvTemp);
|
||
double nDist0 = cvTemp.PathDistance(ptOnPoly[0]);
|
||
double nDist1 = cvTemp.PathDistance(ptOnPoly[1]);
|
||
if (fabs(nDist0-nDist1) < _DIST_SNAP)
|
||
{
|
||
return RTERROR; //重合
|
||
}
|
||
minIndex = nBreakIndex[0];
|
||
maxIndex = nBreakIndex[1];
|
||
if (nDist0 < nDist1)
|
||
{
|
||
ptMin = ptOnPoly[0];
|
||
ptMax = ptOnPoly[1];
|
||
}
|
||
else
|
||
{
|
||
ptMin = ptOnPoly[1];
|
||
ptMax = ptOnPoly[0];
|
||
}
|
||
}
|
||
else if (nBreakIndex[0]<nBreakIndex[1])
|
||
{
|
||
minIndex = nBreakIndex[0];
|
||
maxIndex = nBreakIndex[1];
|
||
ptMin = ptOnPoly[0];
|
||
ptMax = ptOnPoly[1];
|
||
}
|
||
else
|
||
{
|
||
minIndex = nBreakIndex[1];
|
||
maxIndex = nBreakIndex[0];
|
||
ptMin = ptOnPoly[1];
|
||
ptMax = ptOnPoly[0];
|
||
}
|
||
|
||
// 取得res1
|
||
for (int i = minIndex; i <= maxIndex; i++)
|
||
{
|
||
XDirectionCurve seg;
|
||
poly.Nth(i, seg);
|
||
if (i == minIndex)
|
||
{
|
||
// get ptBreak->ptEnd
|
||
if (ads_distance(ptMin, seg.GetEndPoint()) < _DIST_SNAP)
|
||
{
|
||
continue; //忽略这一段
|
||
}
|
||
double nBulge = 0.0;
|
||
if (seg.IsMinusArc())
|
||
{
|
||
XArc ar = seg.GetArc();
|
||
ar.SetAngleByPoints(seg.GetEndPoint(), ptMin);
|
||
nBulge = -ar.Bulge();
|
||
}
|
||
else
|
||
{
|
||
seg.SetPoints(ptMin, seg.GetEndPoint());
|
||
nBulge = seg.GetBulge();
|
||
}
|
||
res1.AppendNode(ptMin, nBulge);
|
||
}
|
||
if (i == maxIndex)
|
||
{
|
||
// get ptStart->ptBreak
|
||
if (ads_distance(ptMax, seg.GetStartPoint()) < _DIST_SNAP)
|
||
{
|
||
res1.AppendNode(ptMax, 0.0);
|
||
continue; //忽略这一段
|
||
}
|
||
double nBulge = 0.0;
|
||
if (seg.IsMinusArc())
|
||
{
|
||
XArc ar = seg.GetArc();
|
||
ar.SetAngleByPoints(ptMax, seg.StartPoint());
|
||
nBulge = -ar.Bulge();
|
||
}
|
||
else
|
||
{
|
||
seg.SetPoints(seg.StartPoint(), ptMax);
|
||
nBulge = seg.GetBulge();
|
||
}
|
||
res1.AppendNode(seg.StartPoint(), nBulge);
|
||
res1.AppendNode(ptMax, 0.0);
|
||
}
|
||
if (i != minIndex && i != maxIndex)
|
||
{
|
||
res1.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
}
|
||
}
|
||
|
||
// 取得res2
|
||
for (int i = maxIndex; i <= minIndex+nSeg; i++)
|
||
{
|
||
int idx = XExport::DePeriod(nSeg, i);
|
||
XDirectionCurve seg;
|
||
poly.Nth(idx, seg);
|
||
|
||
if (idx == maxIndex)
|
||
{
|
||
// get ptBreak->ptEnd
|
||
if (ads_distance(ptMax, seg.GetEndPoint()) < _DIST_SNAP)
|
||
{
|
||
continue; //忽略这一段
|
||
}
|
||
double nBulge = 0.0;
|
||
if (seg.IsMinusArc())
|
||
{
|
||
XArc ar = seg.GetArc();
|
||
ar.SetAngleByPoints(seg.GetEndPoint(), ptMax);
|
||
nBulge = -ar.Bulge();
|
||
}
|
||
else
|
||
{
|
||
seg.SetPoints(ptMax, seg.GetEndPoint());
|
||
nBulge = seg.GetBulge();
|
||
}
|
||
res2.AppendNode(ptMax, nBulge);
|
||
}
|
||
if (idx == minIndex)
|
||
{
|
||
// get ptStart->ptBreak
|
||
if (ads_distance(ptMin, seg.GetStartPoint()) < _DIST_SNAP)
|
||
{
|
||
res2.AppendNode(ptMin, 0.0);
|
||
continue;
|
||
}
|
||
double nBulge = 0.0;
|
||
if (seg.IsMinusArc())
|
||
{
|
||
XArc ar = seg.GetArc();
|
||
ar.SetAngleByPoints(ptMin, seg.StartPoint());
|
||
nBulge = -ar.Bulge();
|
||
}
|
||
else
|
||
{
|
||
seg.SetPoints(seg.StartPoint(), ptMin);
|
||
nBulge = seg.GetBulge();
|
||
}
|
||
res2.AppendNode(seg.StartPoint(), nBulge);
|
||
res2.AppendNode(ptMin, 0.0);
|
||
}
|
||
if (i != minIndex && i != maxIndex)
|
||
{
|
||
res2.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
}
|
||
}
|
||
return RTNORM;
|
||
}
|
||
|
||
int XExport2::SplitPoly2D(const XPoly2D &poly, const XPoint &pt1, const XPoint &pt2, XPoly2D &res1, XPoly2D &res2)
|
||
{
|
||
ASSERT(poly.IsClosed());
|
||
|
||
AcDbPolyline pline;
|
||
XPoint ptOnCurve1, ptOnCurve2;
|
||
XExport2::PolyConvert(poly, pline);
|
||
|
||
if (pline.getClosestPointTo(pt1, ptOnCurve1) != Acad::eOk || pline.getClosestPointTo(pt2, ptOnCurve2) != Acad::eOk)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
// ARX的SplitCurve有错误,因此自己编写
|
||
int nIndex1 = poly.HitTestOnCurve(ptOnCurve1);
|
||
int nIndex2 = poly.HitTestOnCurve(ptOnCurve2);
|
||
if (!nIndex1 || !nIndex2)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
int nPeriod = poly.Length();
|
||
if (nIndex1>0 && nIndex2>0)
|
||
{ //顶点到顶点
|
||
int nVert1 = nIndex1-1;
|
||
int nVert2 = nIndex2-1;
|
||
if (nVert1 == nVert2)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
// nVert1到nVert2
|
||
int nTo = (nVert2>nVert1) ? nVert2 : nVert2+nPeriod;
|
||
for (int iVert = nVert1; iVert <= nTo; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res1.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
// nVert2到nVert1
|
||
nTo = (nVert1>nVert2) ? nVert1 : nVert1+nPeriod;
|
||
for (int iVert = nVert2; iVert <= nTo; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res2.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
}
|
||
else if (nIndex1<0 && nIndex2<0)
|
||
{ // 边到边
|
||
int nEdge1 = abs(nIndex1)-1;
|
||
int nEdge2 = abs(nIndex2)-1;
|
||
|
||
// Edge1到Edge2
|
||
XDirectionCurve seg;
|
||
if (nEdge1 == nEdge2)
|
||
{
|
||
poly.Nth(nEdge1, seg);
|
||
if (seg.PathDistance(ptOnCurve1)>seg.PathDistance(ptOnCurve2)&&seg.Is(CURVE_ARC))//add by w on 070302,解决两点在同一弧边的问题
|
||
{
|
||
seg.SetPoints(ptOnCurve2, ptOnCurve1);
|
||
seg.Reverse();
|
||
}
|
||
else
|
||
{
|
||
seg.SetPoints(ptOnCurve1, ptOnCurve2);
|
||
}
|
||
|
||
res1.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
res1.AppendNode(seg.EndPoint(),0.0);
|
||
}
|
||
else
|
||
{
|
||
// 第一段
|
||
poly.Nth(nEdge1, seg);
|
||
seg.SetPoints(ptOnCurve1, seg.GetEndPoint());
|
||
res1.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
|
||
// 中间段
|
||
int nToEdge = (nEdge2>nEdge1)? nEdge2 : nEdge2+nPeriod;
|
||
for (int iVert = nEdge1+1; iVert <= nToEdge-1; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res1.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
|
||
// 最后一段
|
||
poly.Nth(nEdge2, seg);
|
||
seg.SetPoints(seg.StartPoint(), ptOnCurve2);
|
||
res1.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
|
||
// 最后一点
|
||
res1.AppendNode(ptOnCurve2, 0.0);
|
||
}
|
||
|
||
// Edge2到Edge1
|
||
// 第一段
|
||
poly.Nth(nEdge2, seg);
|
||
seg.SetPoints(ptOnCurve2, seg.EndPoint());
|
||
res2.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
// 中间段
|
||
int nToEdge = (nEdge1>nEdge2) ? nEdge1 : nEdge1+nPeriod;
|
||
for (int iVert = nEdge2+1; iVert <= nToEdge-1; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res2.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
// 最后一段
|
||
poly.Nth(nEdge1, seg);
|
||
seg.SetPoints(seg.StartPoint(), ptOnCurve1);
|
||
res2.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
// 最后一点
|
||
res2.AppendNode(ptOnCurve1, 0.0);
|
||
}
|
||
else if (nIndex1>0 && nIndex2<0)
|
||
{ //顶点到边
|
||
int nVert1 = nIndex1-1;
|
||
int nEdge2 = abs(nIndex2)-1;
|
||
// nVert1到Edge2
|
||
XDirectionCurve seg;
|
||
// 中间段
|
||
int nToEdge = (nEdge2 >= nVert1)? nEdge2 : nEdge2+nPeriod;
|
||
for (int iVert = nVert1; iVert <= nToEdge-1; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res1.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
|
||
// 最后一段
|
||
poly.Nth(nEdge2, seg);
|
||
seg.SetPoints(seg.StartPoint(), ptOnCurve2);
|
||
res1.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
|
||
// 最后一点
|
||
res1.AppendNode(ptOnCurve2, 0.0);
|
||
|
||
// Edge2到nVert1
|
||
// 第一段
|
||
poly.Nth(nEdge2, seg);
|
||
seg.SetPoints(ptOnCurve2, seg.EndPoint());
|
||
res2.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
// 中间段
|
||
nToEdge = (nVert1 >= nEdge2) ? nVert1 : nVert1+nPeriod;
|
||
for (int iVert = nEdge2+1; iVert <= nVert1-1; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res2.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
// 最后一点
|
||
res2.AppendNode(ptOnCurve1, 0.0);
|
||
}
|
||
else
|
||
{ // 边到顶点
|
||
int nEdge1 = abs(nIndex1)-1;
|
||
int nVert2 = nIndex2-1;
|
||
|
||
// nEdge1到nVert2
|
||
XDirectionCurve seg;
|
||
// 第一段
|
||
poly.Nth(nEdge1, seg);
|
||
seg.SetPoints(ptOnCurve1, seg.EndPoint());
|
||
res1.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
|
||
// 中间段
|
||
int nToEdge = (nVert2>nEdge1) ? nVert2 : nVert2+nPeriod;
|
||
for (int iVert = nEdge1+1; iVert <= nToEdge-1; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res1.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
// 最后一点
|
||
res1.AppendNode(ptOnCurve2, 0.0);
|
||
|
||
// nVert2到nEdge1
|
||
if (nEdge1 == nVert2)
|
||
{
|
||
poly.Nth(nEdge1, seg);
|
||
seg.SetPoints(ptOnCurve2, ptOnCurve1);
|
||
res1.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
res1.AppendNode(seg.EndPoint(),0.0);
|
||
}
|
||
else
|
||
{
|
||
// 中间段
|
||
int nToEdge = (nEdge1>nVert2) ? nEdge1 : nEdge1+nPeriod;
|
||
for (int iVert = nVert2; iVert <= nToEdge-1; iVert++)
|
||
{
|
||
int idx = XExport::DePeriod(nPeriod, iVert);
|
||
res2.AppendNode(poly[idx], poly.GetBulge(idx));
|
||
}
|
||
// 最后一段
|
||
poly.Nth(nEdge1, seg);
|
||
seg.SetPoints(seg.StartPoint(), ptOnCurve1);
|
||
res2.AppendNode(seg.StartPoint(), seg.GetBulge());
|
||
//最后一点
|
||
res2.AppendNode(ptOnCurve1, 0.0);
|
||
}
|
||
}
|
||
return RTNORM;
|
||
}
|
||
|
||
void XExport2::SplitPoly2D(const XPoly2D &poly, AcDbVoidPtrArray &entSet)
|
||
{
|
||
for (int i = 0; i < poly.TotalSegments(); i++)
|
||
{
|
||
XCurveSegment cv;
|
||
if (poly.Nth(i, cv) == RTNORM)
|
||
{
|
||
if (cv.Is(CURVE_LINE))
|
||
{
|
||
XLine ln = cv.GetLine();
|
||
entSet.append(new AcDbLine(ln.GetStartPoint(), ln.GetEndPoint()));
|
||
}
|
||
else if (cv.Is(CURVE_ARC))
|
||
{
|
||
XArc ar = cv.GetArc();
|
||
entSet.append(new AcDbArc(ar.GetCenterPt(), ar.GetRadius(), ar.GetStarAngle(), ar.GetEndAngle()));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 把区域分解为曲线段
|
||
void XExport2::Region2Curves(const AcDbRegion *pClone, DList<XCurveSegment>&lstSegs)
|
||
{
|
||
AcDbVoidPtrArray entSet;
|
||
pClone->explode(entSet);
|
||
int nLen = entSet.length();
|
||
for (int j = 0; j < nLen; j++)
|
||
{
|
||
AcDbEntity *pEnt = (AcDbEntity *)entSet[j];
|
||
AcRxClass *pClass = pEnt->isA();
|
||
if (pClass == AcDbLine::desc())
|
||
{
|
||
AcDbLine *pLine = (AcDbLine *)pEnt;
|
||
lstSegs.Append(new XCurveSegment(XPoint(pLine->startPoint()), XPoint(pLine->endPoint()), 0.0, LS_FINITE));
|
||
}
|
||
else if (pClass == AcDbArc::desc())
|
||
{
|
||
AcDbArc *pLine = (AcDbArc *)pEnt;
|
||
XPoint ptCen;
|
||
(AcGePoint3d &)ptCen = pLine->center();
|
||
XVector3D vtNormal;
|
||
(AcGeVector3d &)vtNormal = pLine->normal();
|
||
ptCen = Wcs2Ecs(ptCen, vtNormal);
|
||
XArc ar(ptCen, pLine->radius(), pLine->startAngle(), pLine->endAngle());
|
||
XCurveSegment *pSeg = new XCurveSegment;
|
||
*pSeg = ar;
|
||
lstSegs.Append(pSeg);
|
||
}
|
||
else if (pClass == AcDbPolyline::desc())
|
||
{
|
||
XPoly2D polyTemp;
|
||
XExport2::PolyConvert(*(AcDbPolyline *)pEnt, polyTemp);
|
||
XExport2::ExplodePoly2D(polyTemp, lstSegs);
|
||
}
|
||
else if (pClass = AcDbRegion::desc())
|
||
{
|
||
XExport2::Region2Curves((AcDbRegion *)pEnt, lstSegs);
|
||
}
|
||
}
|
||
XExport::ReleaseEntSet(entSet);
|
||
}
|
||
|
||
int XExport2::HandleCurveInters(PickSet &ss, double dPrec)
|
||
{
|
||
//_angSnap = 0.001; _DIST_SNAP = 0.1; // for Debug
|
||
PickSet ssNew(SS_FREE|SS_CREATE), ssCir(SS_FREE|SS_CREATE), ssDel(SS_FREE|SS_CREATE);
|
||
|
||
XCurveSegInters::minLen = dPrec;
|
||
ssNew.IncludeBegin();
|
||
|
||
XCurveSegInters::GlobalCurveList.Reset();
|
||
long len = ss.Length();
|
||
DList<XCurveSegInters> &curves = XCurveSegInters::GlobalCurveList;
|
||
for (long i = 0; i<len; i++)
|
||
{
|
||
Entity e1 = ss[i];
|
||
XCurveSegInters * curve = new XCurveSegInters(e1);
|
||
if (curve->GetLength() < _DIST_SNAP)
|
||
{
|
||
delete curve;
|
||
ssDel += ss[i];
|
||
}
|
||
else
|
||
{
|
||
curves.Append(curve);
|
||
}
|
||
}
|
||
|
||
len = curves.Length();
|
||
for (int i = 0; i<len; i++)
|
||
{
|
||
XCurveSegInters *curve = curves[(int)i];
|
||
curve->DivideToSegments();
|
||
if (curve->Update() == RTNORM && curve->Is(CURVE_CIRCLE))
|
||
{
|
||
ssCir += curve->acadEnt;
|
||
}
|
||
}
|
||
|
||
ssNew.IncludeEnd();
|
||
|
||
ss -= ssDel;
|
||
ss -= ssCir;
|
||
ss += ssNew;
|
||
XCurveSegInters::GlobalCurveList.Reset();
|
||
ssDel.Erase();
|
||
ads_redraw(NULL, 0);
|
||
return RTNORM;
|
||
}
|
||
|
||
// 连接桥的确定有问题
|
||
// 新的桥接算法
|
||
// 2D only
|
||
int XExport2::ConnectPolygon(const XPolygonEx &poly1, const XPolygonEx &poly2, const XPolyDist &polyDist, XPolygonEx &res)
|
||
{
|
||
ASSERT(poly1.Length()>1 && poly2.Length()>1);
|
||
|
||
int nIndex1 = polyDist.nIndex1;
|
||
int num1 = poly1.Length();
|
||
int nIndex2 = polyDist.nIndex2; //poly2与pt最近的顶点
|
||
int num2 = poly2.Length();
|
||
res.Reset();
|
||
|
||
BOOL bOnVertex1 = FALSE, bOnVertex2 = FALSE;
|
||
if (polyDist.ptLocation1.Distance2d(poly1.GetVertex(polyDist.nIndex1))<_DIST_SNAP)
|
||
{
|
||
bOnVertex1 = TRUE;
|
||
}
|
||
else if (polyDist.ptLocation1.Distance2d(poly1.GetVertex(polyDist.nIndex1+1))<_DIST_SNAP)
|
||
{
|
||
bOnVertex1 = TRUE;
|
||
nIndex1++;
|
||
}
|
||
|
||
if (polyDist.ptLocation2.Distance2d(poly2.GetVertex(polyDist.nIndex2))<_DIST_SNAP)
|
||
{
|
||
bOnVertex2 = TRUE;
|
||
}
|
||
else if (polyDist.ptLocation2.Distance2d(poly2.GetVertex(polyDist.nIndex2+1))<_DIST_SNAP)
|
||
{
|
||
bOnVertex2 = TRUE;
|
||
nIndex2++;
|
||
}
|
||
|
||
int j = 0, i = 0;
|
||
if (bOnVertex1)
|
||
{
|
||
for (j = nIndex1; j<nIndex1+num1; j++)
|
||
{
|
||
res.AppendNode(poly1.GetVertex(j), poly1.IsVisible(j));
|
||
}
|
||
res.AppendNode(poly1.GetVertex(nIndex1), FALSE);
|
||
}
|
||
else
|
||
{
|
||
res.AppendNode(polyDist.ptLocation1, poly1.IsVisible(nIndex1));
|
||
for (j = nIndex1+1; j <= nIndex1+num1; j++)
|
||
{
|
||
res.AppendNode(poly1.GetVertex(j), poly1.IsVisible(j));
|
||
}
|
||
res.AppendNode(polyDist.ptLocation1, FALSE);
|
||
}
|
||
|
||
if (bOnVertex2)
|
||
{
|
||
for (i = nIndex2; i<nIndex2+num2; i++)
|
||
{
|
||
res.AppendNode(poly2.GetVertex(i), poly2.IsVisible(i));
|
||
}
|
||
res.AppendNode(poly2.GetVertex(nIndex2), FALSE);
|
||
}
|
||
else
|
||
{
|
||
res.AppendNode(polyDist.ptLocation2, poly2.IsVisible(nIndex2));
|
||
for (i = nIndex2+1; i <= nIndex2+num2; i++)
|
||
{
|
||
res.AppendNode(poly2.GetVertex(i), poly2.IsVisible(i));
|
||
}
|
||
res.AppendNode(polyDist.ptLocation2, FALSE);
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
int XExport2::ConnectPolygon(const XPolygonEx &poly1, const XPolygonEx &poly2, XPolygonEx &res)
|
||
{
|
||
ASSERT(poly1.Length()>1 && poly2.Length()>1);
|
||
|
||
int nIndex1 = 0;
|
||
int num1 = poly1.Length();
|
||
int nIndex2 = 0; //poly2与pt最近的顶点
|
||
double dMinDist = 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 dDist = pt.Distance(poly2[i]);
|
||
if (i == 0 && j == 0)
|
||
{
|
||
dMinDist = dDist;
|
||
}
|
||
else if (dDist < dMinDist)
|
||
{
|
||
dMinDist = dDist;
|
||
nIndex2 = i;
|
||
nIndex1 = j;
|
||
}
|
||
}
|
||
}
|
||
|
||
res.Reset();
|
||
for (int j = nIndex1; j<nIndex1+num1; j++)
|
||
{
|
||
res.AppendNode(poly1.GetVertex(j), poly1.IsVisible(j));
|
||
}
|
||
res.AppendNode(poly1.GetVertex(nIndex1), FALSE);
|
||
|
||
for (int i = nIndex2; i<nIndex2+num2; i++)
|
||
{
|
||
res.AppendNode(poly2.GetVertex(i), poly2.IsVisible(i));
|
||
}
|
||
res.AppendNode(poly2.GetVertex(nIndex2), FALSE);
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
void XExport2::_IntersectCurves(DList<XCurveSegment> &lstCurves, double dPrec)
|
||
{
|
||
XCurveIntersection::minLen = dPrec;
|
||
XCurveIntersection::GlobalCurveList.Reset();
|
||
|
||
int len = lstCurves.Length();
|
||
for (int i = 0; i<len; i++)
|
||
{
|
||
XCurveSegment &e1 = *lstCurves[i];
|
||
if (e1.GetLength()<max(_DIST_SNAP,dPrec))
|
||
{
|
||
continue;
|
||
}
|
||
XCurveIntersection::GlobalCurveList.Append(new XCurveIntersection(e1));
|
||
}
|
||
|
||
len = XCurveIntersection::GlobalCurveList.Length();
|
||
if (g_bEchoSearch)
|
||
{
|
||
XString sMsg(256);
|
||
sMsg << _T("对") << len << _T("条线进行处理交线");
|
||
acedSetStatusBarProgressMeter(sMsg, 0, len);
|
||
}
|
||
int nStep = len/100;
|
||
if (nStep<1)
|
||
{
|
||
nStep = 1;
|
||
}
|
||
|
||
lstCurves.Reset();
|
||
for (int i = 0; i<len; i++)
|
||
{
|
||
if (g_bEchoSearch && !(i%nStep))
|
||
{
|
||
acedSetStatusBarProgressMeterPos(i);
|
||
}
|
||
|
||
XCurveIntersection *curve = XCurveIntersection::GlobalCurveList[i];
|
||
curve->DivideToSegments();
|
||
XPoly2D poly;
|
||
curve->segments.AsPoly2D(poly);
|
||
for (int n = 0; n<poly.TotalSegments(); n++)
|
||
{
|
||
XCurveSegment seg;
|
||
poly.Nth(n, seg);
|
||
if (seg.GetLength() > max(_DIST_SNAP,dPrec))
|
||
{
|
||
lstCurves.Append(new XCurveSegment(seg));
|
||
}
|
||
}
|
||
}
|
||
|
||
XCurveIntersection::GlobalCurveList.Reset();
|
||
if (g_bEchoSearch)
|
||
{
|
||
acedRestoreStatusBar();
|
||
}
|
||
}
|
||
|
||
// poly的坐标为当前UCS下的坐标
|
||
// ss1--inside; ss2--outside
|
||
// Status: Only use in WCS
|
||
int XExport2::PolyClip(const DList<XCurveSegment> &ss, XPoly2D &poly, DList<XCurveSegment> &ss1, DList<XCurveSegment> &ss2)
|
||
{
|
||
int len = ss.Length();
|
||
for (int i = 0; i<len; i++)
|
||
{
|
||
XCurveSegment seg = ss[i];
|
||
seg.SetElevation(poly[0]->z); // Z坐标相等
|
||
|
||
PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge());
|
||
IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序
|
||
int listLen = pts.Length();
|
||
|
||
if (pts.curveType == CURVE_CIRCLE)
|
||
{
|
||
if (listLen <= 2)
|
||
{ // circle, but not cut to arcs
|
||
XPoint mpt = seg.GetCircle().GetCenterPt();
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1.Append(new XCurveSegment(ss[i]));
|
||
}
|
||
else
|
||
{
|
||
ss2.Append(new XCurveSegment(ss[i]));
|
||
}
|
||
continue;
|
||
}
|
||
|
||
for (int i = 1; i<listLen; i++)
|
||
{
|
||
XPoint pt2;
|
||
if (i == listLen-1) pt2 = *pts[1];
|
||
else pt2 = *pts[i+1];
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, *pts[i]), ads_angle(pts.center, *pts[i]), ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
XCurveSegment *pCurve = new XCurveSegment;
|
||
*pCurve = arcSeg;
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1.Append(pCurve);
|
||
}
|
||
else
|
||
{
|
||
ss2.Append(pCurve);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j<listLen-1; j++)
|
||
{ // arc and line
|
||
XPoint &pt1 = *pts[j];
|
||
XPoint &pt2 = *pts[j+1];
|
||
if (pts.curveType == CURVE_LINE)
|
||
{
|
||
XLine lineSeg(pt1, pt2);
|
||
XPoint mpt = lineSeg.MidPoint();
|
||
XCurveSegment *pCurve = new XCurveSegment;
|
||
*pCurve = lineSeg;
|
||
if ((mpt & poly) == PR_INSIDE)
|
||
{
|
||
ss1.Append(pCurve);
|
||
}
|
||
else
|
||
{
|
||
ss2.Append(pCurve);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, pt1), ads_angle(pts.center,pt1),ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
XPoint cen = arcSeg.GetCenterPt();
|
||
XCurveSegment *pCurve = new XCurveSegment;
|
||
*pCurve = arcSeg;
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1.Append(pCurve);
|
||
}
|
||
else
|
||
{
|
||
ss2.Append(pCurve);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
// poly的坐标为当前UCS下的坐标
|
||
// ss1--inside; ss2--outside; ssOnEdge--On Edge
|
||
int XExport2::PolyClip(const DList<XCurveSegment> &ss, const XPoly2D &poly1, DList<XCurveSegment> &ss1, DList<XCurveSegment> &ss2, DList<XCurveSegment> &ssOnEdge)
|
||
{
|
||
XPoly2D &poly = (XPoly2D &)poly1;
|
||
ASSERT(!!poly);
|
||
int len = ss.Length();
|
||
for (int i = 0; i<len; i++)
|
||
{
|
||
XCurveSegment seg = ss[i];
|
||
seg.SetElevation(poly[0]->z); // Z坐标相等
|
||
|
||
PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge());
|
||
IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序
|
||
int listLen = pts.Length();
|
||
|
||
if (pts.curveType == CURVE_CIRCLE)
|
||
{
|
||
if (listLen <= 2)
|
||
{ // circle, but not cut to arcs
|
||
XPoint mpt = seg.GetCircle().GetCenterPt();
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1.Append(new XCurveSegment(ss[i]));
|
||
}
|
||
else
|
||
{
|
||
ss2.Append(new XCurveSegment(ss[i]));
|
||
}
|
||
continue;
|
||
}
|
||
|
||
for (int i = 1; i<listLen; i++)
|
||
{
|
||
XPoint pt2;
|
||
if (i == listLen-1)
|
||
{
|
||
pt2 = *pts[1];
|
||
}
|
||
else
|
||
{
|
||
pt2 = *pts[i+1];
|
||
}
|
||
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, *pts[i]), ads_angle(pts.center, *pts[i]), ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
|
||
XCurveSegment *pCurve = new XCurveSegment;
|
||
*pCurve = arcSeg;
|
||
|
||
int nPrFlag = (mpt&poly);
|
||
if (nPrFlag == PR_INSIDE)
|
||
{
|
||
ss1.Append(pCurve);
|
||
}
|
||
else if (nPrFlag == PR_OUTSIDE)
|
||
{
|
||
ss2.Append(pCurve);
|
||
}
|
||
else
|
||
{
|
||
ssOnEdge.Append(pCurve);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j<listLen-1; j++)
|
||
{ // arc and line
|
||
XPoint &pt1 = *pts[j];
|
||
XPoint &pt2 = *pts[j+1];
|
||
if (pts.curveType == CURVE_LINE)
|
||
{
|
||
XLine lineSeg(pt1, pt2);
|
||
XPoint mpt = lineSeg.MidPoint();
|
||
XCurveSegment *pCurve = new XCurveSegment;
|
||
*pCurve = lineSeg;
|
||
|
||
int nPrFlag = (mpt&poly);
|
||
if (nPrFlag == PR_INSIDE)
|
||
{
|
||
ss1.Append(pCurve);
|
||
}
|
||
else if (nPrFlag == PR_OUTSIDE)
|
||
{
|
||
ss2.Append(pCurve);
|
||
}
|
||
else
|
||
{
|
||
ssOnEdge.Append(pCurve);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, pt1), ads_angle(pts.center,pt1), ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
XPoint cen = arcSeg.GetCenterPt();
|
||
XCurveSegment *pCurve = new XCurveSegment;
|
||
*pCurve = arcSeg;
|
||
int nPrFlag = (mpt&poly);
|
||
if (nPrFlag == PR_INSIDE)
|
||
{
|
||
ss1.Append(pCurve);
|
||
}
|
||
else if (nPrFlag == PR_OUTSIDE)
|
||
{
|
||
ss2.Append(pCurve);
|
||
}
|
||
else
|
||
{
|
||
ssOnEdge.Append(pCurve);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
// poly的坐标为当前UCS下的坐标
|
||
// ss1--inside; ss2--OnEdge and Outside
|
||
// Status: Only use in WCS
|
||
int XExport2::PolyClip(PickSet &ss, XPoly2D &poly, PickSet &ss1, PickSet &ss2)
|
||
{
|
||
RBList mask(RTDXF0,_T("ARC,LINE,CIRCLE"), NULL);
|
||
ss.BaseFilter(mask);
|
||
long len = ss.Length();
|
||
for (long i = 0; i<len; i++)
|
||
{
|
||
Entity ent = ss[i];
|
||
XCurveSegment seg(ent);
|
||
seg.SetElevation(poly[0]->z); // Z坐标相等
|
||
|
||
PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge());
|
||
IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序
|
||
int listLen = pts.Length();
|
||
|
||
Entity entRef = ent;
|
||
if (pts.curveType == CURVE_CIRCLE)
|
||
{
|
||
if (listLen <= 2)
|
||
{ // circle, but not cut to arcs
|
||
XPoint mpt = seg.GetCircle().GetCenterPt();
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1 += ent;
|
||
}
|
||
else
|
||
{
|
||
ss2 += ent;
|
||
}
|
||
continue;
|
||
}
|
||
// 圆被裁为弧
|
||
TCHAR lay[80] = _T("0");
|
||
entRef.GetData(8, lay);
|
||
for (int i = 1; i<listLen; i++)
|
||
{
|
||
XPoint pt2;
|
||
if (i == listLen-1) pt2 = *pts[1];
|
||
else pt2 = *pts[i+1];
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, *pts[i]), ads_angle(pts.center, *pts[i]),
|
||
ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
if (arcSeg.Make(lay) == RTNORM)
|
||
{
|
||
Entity eL;
|
||
eL.GetLast();
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1 += eL;
|
||
}
|
||
else
|
||
{
|
||
ss2 += eL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else for (int j = 0; j < listLen-1; j++)
|
||
{ // arc and line
|
||
XPoint &pt1 = *pts[j];
|
||
XPoint &pt2 = *pts[j+1];
|
||
if (pts.curveType == CURVE_LINE)
|
||
{
|
||
XLine lineSeg(pt1, pt2);
|
||
XPoint mpt = lineSeg.MidPoint();
|
||
if (lineSeg.MakeEntity(&entRef) == RTNORM)
|
||
{
|
||
Entity eL;
|
||
eL.GetLast();
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1 += eL;
|
||
}
|
||
else
|
||
{
|
||
ss2 += eL;
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, pt1), ads_angle(pts.center,pt1),ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
XPoint cen = arcSeg.GetCenterPt();
|
||
if (arcSeg.MakeEntity(&entRef) == RTNORM)
|
||
{
|
||
Entity eL;
|
||
eL.GetLast();
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1 += eL;
|
||
}
|
||
else
|
||
{
|
||
ss2 += eL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
ent.Delete();
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
// poly的坐标为当前UCS下的坐标
|
||
// ss1--inside; ss2--outSide, ss3--OnEdge
|
||
// Status: Only use in WCS
|
||
int XExport2::PolyClip(PickSet &ss, XPoly2D &poly, PickSet &ss1, PickSet &ss2, PickSet &ss3)
|
||
{
|
||
RBList mask(RTDXF0,_T("ARC,LINE,CIRCLE"), NULL);
|
||
ss.BaseFilter(mask);
|
||
long len = ss.Length();
|
||
for (long i = 0; i<len; i++)
|
||
{
|
||
Entity ent = ss[i];
|
||
XCurveSegment seg(ent);
|
||
seg.SetElevation(poly[0]->z); // Z坐标相等
|
||
|
||
PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge());
|
||
IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序
|
||
int listLen = pts.Length();
|
||
|
||
Entity entRef = ent;
|
||
if (pts.curveType == CURVE_CIRCLE)
|
||
{
|
||
if (listLen <= 2)
|
||
{ // circle, but not cut to arcs
|
||
XPoint mpt = seg.GetCircle().GetCenterPt();
|
||
if ((mpt&poly) == PR_INSIDE)
|
||
{
|
||
ss1 += ent;
|
||
}
|
||
else
|
||
{
|
||
ss2 += ent;
|
||
}
|
||
continue;
|
||
}
|
||
// 圆被裁为弧
|
||
TCHAR lay[80] = _T("0");
|
||
entRef.GetData(8, lay);
|
||
for (int i = 1; i<listLen; i++)
|
||
{
|
||
XPoint pt2;
|
||
if (i == listLen-1)
|
||
{
|
||
pt2 = *pts[1];
|
||
}
|
||
else
|
||
{
|
||
pt2 = *pts[i+1];
|
||
}
|
||
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, *pts[i]), ads_angle(pts.center, *pts[i]), ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
if (arcSeg.Make(lay) == RTNORM)
|
||
{
|
||
Entity eL;
|
||
eL.GetLast();
|
||
int nPrFlag = (mpt&poly);
|
||
if (nPrFlag == PR_INSIDE)
|
||
{
|
||
ss1 += eL;
|
||
}
|
||
else if (nPrFlag == PR_OUTSIDE)
|
||
{
|
||
ss2 += eL;
|
||
}
|
||
else
|
||
{
|
||
ss3 += eL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else for (int j = 0; j<listLen-1; j++)
|
||
{ // arc and line
|
||
XPoint &pt1 = *pts[j];
|
||
XPoint &pt2 = *pts[j+1];
|
||
if (pts.curveType == CURVE_LINE)
|
||
{
|
||
XLine lineSeg(pt1, pt2);
|
||
XPoint mpt = lineSeg.MidPoint();
|
||
|
||
if (lineSeg.MakeEntity(&entRef) == RTNORM)
|
||
{
|
||
Entity eL;
|
||
eL.GetLast();
|
||
int nPrFlag = (mpt&poly);
|
||
if (nPrFlag == PR_INSIDE)
|
||
{
|
||
ss1 += eL;
|
||
}
|
||
else if (nPrFlag == PR_OUTSIDE)
|
||
{
|
||
ss2 += eL;
|
||
}
|
||
else
|
||
{
|
||
ss3 += eL;
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
XArc arcSeg(pts.center, ads_distance(pts.center, pt1), ads_angle(pts.center,pt1), ads_angle(pts.center, pt2));
|
||
XPoint mpt;
|
||
arcSeg.MidPoint(mpt);
|
||
|
||
XPoint cen = arcSeg.GetCenterPt();
|
||
if (arcSeg.MakeEntity(&entRef) == RTNORM)
|
||
{
|
||
Entity eL;
|
||
eL.GetLast();
|
||
|
||
int nPrFlag = (mpt&poly);
|
||
if (nPrFlag == PR_INSIDE)
|
||
{
|
||
ss1 += eL;
|
||
}
|
||
else if (nPrFlag == PR_OUTSIDE)
|
||
{
|
||
ss2 += eL;
|
||
}
|
||
else
|
||
{
|
||
ss3 += eL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
ent.Delete();
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
// 把区域分解为逆时针排列的XPoly2D
|
||
void XExport2::Region2XPoly2D(const AcDbRegion *pClone, XPoly2D &poly2D)
|
||
{
|
||
// 091119,临时将精确度改为g_globleSnap
|
||
CTempTol globleTol(g_globleSnap);
|
||
|
||
// 清空
|
||
poly2D.Reset();
|
||
|
||
// 将区域分解
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
AcDbVoidPtrArray arpCurve;
|
||
if ((es = pClone->explode(arpCurve)) != Acad::eOk)
|
||
{
|
||
return;
|
||
}
|
||
|
||
int nLen = arpCurve.length();
|
||
if (nLen < 1)
|
||
{
|
||
XExport::ReleaseEntSet(arpCurve);
|
||
return;
|
||
}
|
||
|
||
// 求由一组曲线组成的边界,返回polyline线
|
||
AcDbVoidPtrArray arpResult;
|
||
AcDbCurve* pBound = ConvertCurves2Loops(arpCurve, arpResult);
|
||
if (pBound == NULL)
|
||
{
|
||
XExport::ReleaseEntSet(arpCurve);
|
||
return;
|
||
}
|
||
|
||
AcRxClass *pClass = pBound->isA();
|
||
if (pClass = AcDbPolyline::desc())
|
||
{
|
||
// 将AcDbPolyline转化为XPoly2D
|
||
XExport2::PolyConvert(*(AcDbPolyline *)pBound, poly2D);
|
||
}
|
||
|
||
XExport::ReleaseEntSet(arpCurve);
|
||
if (pBound != NULL)
|
||
{
|
||
delete pBound;
|
||
}
|
||
|
||
// 设置闭合
|
||
poly2D.SetFlag(1);
|
||
}
|
||
|
||
// 布尔运算,与PolyBoolOper函数接口不变,但使用AcDbRegion::booleanOper函数,内部计算时,将标高设置为0
|
||
void XExport2::RegionBoolOper(const XPoly2D &poly1, const XPoly2D &poly2, DList<XPoly2D> &lstResult, AcDb::BoolOperType operation)
|
||
{
|
||
// 091119,临时将精确度改为g_globleSnap
|
||
CTempTol globleTol(g_globleSnap);
|
||
|
||
// 清空
|
||
lstResult.Reset();
|
||
|
||
XPoly2D pline1 = poly1,
|
||
pline2 = poly2;
|
||
|
||
// 强制设置PLine封闭
|
||
pline1.SetFlag(1);
|
||
pline2.SetFlag(1);
|
||
|
||
// 强制将标高设置为0
|
||
pline1.SetElevation(0.0);
|
||
pline2.SetElevation(0.0);
|
||
|
||
// 将PLine转化为Region
|
||
AcDbRegion *pRegion1 = pline1.AsRegion(),
|
||
*pRegion2 = pline2.AsRegion();
|
||
|
||
if (pRegion1 != NULL && pRegion2 != NULL)
|
||
{
|
||
// 对两区域进行布尔运算
|
||
if (pRegion1->booleanOper(operation, pRegion2) == Acad::eOk)
|
||
{
|
||
// 把区域分解为逆时针排列的XPoly2D
|
||
XPoly2D *pNewPoly = new XPoly2D(1);
|
||
XExport2::Region2XPoly2D(pRegion1, *pNewPoly);
|
||
|
||
if (pNewPoly->Length() > 0)
|
||
{
|
||
lstResult.Append(pNewPoly);
|
||
}
|
||
else
|
||
{
|
||
delete pNewPoly;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (pRegion1 != NULL)
|
||
{
|
||
delete pRegion1;
|
||
}
|
||
|
||
if (pRegion2 != NULL)
|
||
{
|
||
delete pRegion2;
|
||
}
|
||
}
|
||
|
||
|
||
// 8.0先解决角度不大于MIN_PL_ANGEL的情况
|
||
// 自动处理封闭的XPoly2D,只处理外轮廓线
|
||
// 若某段长度不大于MIN_PL_DISTANCE,或者相临两段夹角不大于MIN_PL_ANGEL度,则自动减点
|
||
void XExport2::AutoDelExPoly2DPt(XPoly2D &poly)
|
||
{
|
||
int nLen = poly.Length(); // 总点数
|
||
if (nLen < 3)
|
||
{
|
||
return;
|
||
}
|
||
|
||
XPoly2D dest(1); // 设置闭合
|
||
double dAngle = 0.0, // 以当前点为顶点,前后点连线为边的夹角
|
||
dBulge = 0.0; // 当前点应该有的Bulge值
|
||
|
||
BOOL bAdd2Dest = TRUE; // 标记是否将当前点添加到dest中
|
||
int nPrev(0), nNext(0); // 前、后点标号
|
||
XPoint ptCur, ptPrev, ptNext;
|
||
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
bAdd2Dest = TRUE; // 标记是否将当前点添加到dest中
|
||
|
||
// 封闭路径,周期查找
|
||
nPrev = XExport::DePeriod(nLen, i - 1);
|
||
nNext = XExport::DePeriod(nLen, i + 1);
|
||
|
||
ptCur = *poly[i]; // 当前点
|
||
ptPrev = *poly[nPrev]; // 前一点
|
||
ptNext = *poly[nNext]; // 后一点
|
||
|
||
dBulge = poly.GetBulge(i); // 默认取当前点的Bulge值
|
||
|
||
AcGeVector3d vec1 = ptPrev.AsAcGePoint3d() - ptCur.AsAcGePoint3d(),
|
||
vec2 = ptNext.AsAcGePoint3d() - ptCur.AsAcGePoint3d();
|
||
|
||
dAngle = vec1.angleTo(vec2); // 角度在[0,PI]范围内
|
||
if (dAngle < MIN_PL_ANGEL + _angSnap) // 角度不大于1
|
||
{
|
||
double dPrevBulge = poly.GetBulge(nPrev);
|
||
if (fabs(dBulge)<_angSnap && fabs(dPrevBulge)<_angSnap)
|
||
{
|
||
bAdd2Dest = FALSE;
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 将当前点添加到dest中
|
||
if (bAdd2Dest)
|
||
{
|
||
dest.AppendNode(ptCur, dBulge);
|
||
}
|
||
}
|
||
|
||
poly.Reset();
|
||
poly = dest;
|
||
}
|
||
|
||
void XExport2::GetGripPoints(const XPoly2D &poly, AcGePoint3dArray &gripPoints)
|
||
{
|
||
int nVertexCount = poly.Length();
|
||
for (int i = 0; i<nVertexCount; i++)
|
||
{
|
||
const XPoint &pt = poly[i];
|
||
gripPoints.append(pt);
|
||
}
|
||
//边上的夹点
|
||
int nEdgeNum = poly.TotalSegments();
|
||
for (int i = 0; i<nEdgeNum; i++)
|
||
{
|
||
XCurveSegment seg;
|
||
poly.Nth(i, seg);
|
||
XPoint ptMid = seg.MidPoint();
|
||
gripPoints.append(ptMid);
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::MoveGripPointsAt(XPoly2D &poly, const AcDbIntArray& indices, const AcGeVector3d& offset)
|
||
{
|
||
int nVertexCount = poly.Length();
|
||
|
||
XPoint vtOffset = *(XPoint *)&offset;
|
||
vtOffset.z = 0;
|
||
|
||
for (int i = 0; i < indices.length(); i++)
|
||
{
|
||
int idx = indices[i];
|
||
if (idx < nVertexCount)
|
||
{ // Move vertex
|
||
*poly[idx] += vtOffset;
|
||
continue;
|
||
}
|
||
// Move Edge or Shape
|
||
int nEdgeIndex = idx-nVertexCount;
|
||
int nTotalEdge = poly.TotalSegments();
|
||
if (nEdgeIndex >= nTotalEdge)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
//移动边
|
||
XDirectionCurve cv;
|
||
poly.Nth(nEdgeIndex, cv);
|
||
ASSERT(!!cv);
|
||
if (cv.Is(CURVE_LINE))
|
||
{ // Move
|
||
XLine ln = cv.GetLine();
|
||
ln.SetStartPoint(ln.GetStartPoint() + vtOffset);
|
||
ln.SetEndPoint(ln.GetEndPoint() + vtOffset);
|
||
ln.SetLineFlag(LS_INFINITE);
|
||
XDirectionCurve prevSeg, nextSeg;
|
||
int nPrev = nEdgeIndex-1, nNext = nEdgeIndex+1;
|
||
if (poly.IsClosed())
|
||
{
|
||
nPrev = XExport::DePeriod(nTotalEdge, nPrev);
|
||
nNext = XExport::DePeriod(nTotalEdge, nNext);
|
||
}
|
||
|
||
XPoint ptStart, ptEnd;
|
||
BOOL bUpdateIt = TRUE;
|
||
//更新起点
|
||
if (nPrev >= 0 && nPrev<nTotalEdge)
|
||
{
|
||
poly.Nth(nPrev, prevSeg);
|
||
prevSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
{
|
||
ptStart = ptInt[0];
|
||
}
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetStartPoint());
|
||
}
|
||
else
|
||
{
|
||
bUpdateIt = FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ptStart = *poly[nEdgeIndex] + vtOffset;
|
||
}
|
||
|
||
// 更新下一点
|
||
if (nNext >= 0 && nNext<nTotalEdge)
|
||
{
|
||
poly.Nth(nNext, nextSeg);
|
||
nextSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
{
|
||
ptEnd = ptInt[0];
|
||
}
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetEndPoint());
|
||
}
|
||
else
|
||
{
|
||
bUpdateIt = FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ptEnd = *poly[nEdgeIndex+1] + vtOffset;
|
||
}
|
||
|
||
if (bUpdateIt)
|
||
{
|
||
double nPrevBulge = 0.0, nNextBulge = 0.0;
|
||
if (fabs(prevSeg.GetBulge()) > 1.0E-5)
|
||
{
|
||
XArc prevArc = prevSeg.GetArc();
|
||
double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.GetStartPoint());
|
||
double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart);
|
||
if (prevSeg.IsMinusArc())
|
||
{
|
||
nPrevBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nPrevBulge = XExport::CT_std_angle(nAngEnd-nAngBeg);
|
||
}
|
||
}
|
||
if (fabs(nextSeg.GetBulge()) > 1.0E-5)
|
||
{
|
||
XArc nextArc = nextSeg.GetArc();
|
||
double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd);
|
||
double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.GetEndPoint());
|
||
if (nextSeg.IsMinusArc())
|
||
{
|
||
nNextBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nNextBulge = XExport::CT_std_angle(nAngEnd-nAngBeg);
|
||
}
|
||
}
|
||
|
||
*poly[nEdgeIndex] = ptStart;
|
||
if (nNext >= 0 && nNext < poly.Length())
|
||
{
|
||
*poly[nNext] = ptEnd;
|
||
poly.SetBulge(nNext, nNextBulge);
|
||
}
|
||
if (nPrev >= 0 && nPrev < poly.Length())
|
||
{
|
||
poly.SetBulge(nPrev, nPrevBulge);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{ // Change Arc Segment--bulge
|
||
XPoint ptMid = cv.MidPoint();
|
||
XPoint ptMidNew = ptMid + vtOffset;
|
||
XArc arNew(cv.GetStartPoint(), ptMidNew, cv.GetEndPoint());
|
||
if (!!arNew)
|
||
{ //新的弧有效
|
||
XCurveSegment cvLine(cv.GetStartPoint(), cv.GetEndPoint(), 0.0);
|
||
int nSideOld = cvLine.OnWhichSide(ptMid);
|
||
int nSideNew = cvLine.OnWhichSide(ptMidNew);
|
||
double dSignal = cv.GetBulge() / fabs(cv.GetBulge());
|
||
if (nSideOld == nSideNew)
|
||
{
|
||
poly.SetBulge(nEdgeIndex, dSignal * arNew.Bulge());
|
||
}
|
||
else
|
||
{
|
||
poly.SetBulge(nEdgeIndex, -dSignal * arNew.Bulge());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
poly.Compress(false);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
void XExport2::GetGripPoints(const XPoly2D &poly,AcGeVector3d &normal,AcGePoint3dArray &gripPoints)
|
||
{
|
||
int nVertexCount = poly.Length();
|
||
for (int i = 0; i < nVertexCount; i++)
|
||
{
|
||
const XPoint &pt = poly[i];
|
||
gripPoints.append(Ecs2Wcs(pt,normal).AsAcGePoint3d());
|
||
}
|
||
//边上的夹点
|
||
int nEdgeNum = poly.TotalSegments();
|
||
for (int i = 0; i < nEdgeNum; i++)
|
||
{
|
||
XCurveSegment seg;
|
||
poly.Nth(i, seg);
|
||
XPoint ptMid = seg.MidPoint();
|
||
gripPoints.append(Ecs2Wcs(ptMid,normal).AsAcGePoint3d());
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::MoveGripPointsAt(XPoly2D &polyPath,
|
||
AcGeVector3d &vtNormal,
|
||
const AcDbIntArray& indices,
|
||
const AcGeVector3d& offset)
|
||
{
|
||
int nVertexCount = polyPath.Length();
|
||
|
||
XPoint vtOffset = Wcs2Ecs(*(XPoint *)&offset, vtNormal);
|
||
for (int i = 0; i < indices.length(); i++)
|
||
{
|
||
int idx = indices[i];
|
||
if (idx<nVertexCount)
|
||
{ // Move vertex
|
||
*polyPath[idx] += vtOffset;
|
||
}
|
||
else
|
||
{ // Move Edge or Shape
|
||
XPoly2D poly2d(polyPath);
|
||
poly2d.SetElevation(0.0);
|
||
|
||
int nEdgeIndex = idx-nVertexCount;
|
||
int nTotalEdge = poly2d.TotalSegments();
|
||
if (nEdgeIndex<nTotalEdge)
|
||
{ //移动边
|
||
XDirectionCurve cv;
|
||
poly2d.Nth(nEdgeIndex, cv);
|
||
ASSERT(!!cv);
|
||
if (cv.Is(CURVE_LINE))
|
||
{ // Move
|
||
XLine ln = cv.GetLine();
|
||
ln.SetStartPoint(ln.GetStartPoint()+ vtOffset);
|
||
ln.SetEndPoint(ln.GetEndPoint() + vtOffset);
|
||
ln.SetLineFlag(LS_INFINITE);
|
||
XDirectionCurve prevSeg, nextSeg;
|
||
int nPrev = nEdgeIndex-1, nNext = nEdgeIndex+1;
|
||
if (poly2d.IsClosed())
|
||
{
|
||
nPrev = XExport::DePeriod(nTotalEdge, nPrev);
|
||
nNext = XExport::DePeriod(nTotalEdge, nNext);
|
||
}
|
||
|
||
XPoint ptStart, ptEnd;
|
||
BOOL bUpdateIt = TRUE;
|
||
//更新起点
|
||
if (nPrev >= 0 && nPrev < nTotalEdge)
|
||
{
|
||
poly2d.Nth(nPrev, prevSeg);
|
||
prevSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
{
|
||
ptStart = ptInt[0];
|
||
}
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetStartPoint());
|
||
}
|
||
else
|
||
{
|
||
bUpdateIt = FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ptStart = *poly2d[nEdgeIndex] + vtOffset;
|
||
}
|
||
|
||
// 更新下一点
|
||
if (nNext >= 0 && nNext < nTotalEdge)
|
||
{
|
||
poly2d.Nth(nNext, nextSeg);
|
||
nextSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
{
|
||
ptEnd = ptInt[0];
|
||
}
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetEndPoint());
|
||
}
|
||
else
|
||
{
|
||
bUpdateIt = FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ptEnd = *poly2d[nEdgeIndex+1] + vtOffset;
|
||
}
|
||
|
||
if (bUpdateIt)
|
||
{
|
||
double nPrevBulge = 0.0, nNextBulge = 0.0;
|
||
if (fabs(prevSeg.GetBulge())>1.0E-5)
|
||
{
|
||
XArc prevArc = prevSeg.GetArc();
|
||
double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.GetStartPoint());
|
||
double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart);
|
||
if (prevSeg.IsMinusArc())
|
||
{
|
||
nPrevBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nPrevBulge = XExport::CT_std_angle(nAngEnd-nAngBeg);
|
||
}
|
||
}
|
||
if (fabs(nextSeg.GetBulge()) > 1.0E-5)
|
||
{
|
||
XArc nextArc = nextSeg.GetArc();
|
||
double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd);
|
||
double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.GetEndPoint());
|
||
if (nextSeg.IsMinusArc())
|
||
{
|
||
nNextBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nNextBulge = XExport::CT_std_angle(nAngEnd-nAngBeg);
|
||
}
|
||
}
|
||
|
||
*poly2d[nEdgeIndex] = ptStart;
|
||
if (nNext >= 0 && nNext < poly2d.Length())
|
||
{
|
||
*poly2d[nNext] = ptEnd;
|
||
poly2d.SetBulge(nNext, nNextBulge);
|
||
}
|
||
if (nPrev >= 0 && nPrev < poly2d.Length())
|
||
{
|
||
poly2d.SetBulge(nPrev, nPrevBulge);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
else
|
||
{ // Change Arc Segment--bulge
|
||
XPoint ptMid = cv.MidPoint();
|
||
XPoint ptMidNew = ptMid + vtOffset;
|
||
XArc arNew(cv.GetStartPoint(), ptMidNew, cv.GetEndPoint());
|
||
if (!!arNew)
|
||
{ //新的弧有效
|
||
XCurveSegment cvLine(cv.GetStartPoint(), cv.GetEndPoint(), 0.0);
|
||
int nSideOld = cvLine.OnWhichSide(ptMid);
|
||
int nSideNew = cvLine.OnWhichSide(ptMidNew);
|
||
double dSignal = cv.GetBulge()/fabs(cv.GetBulge());
|
||
if (nSideOld == nSideNew)
|
||
{
|
||
poly2d.SetBulge(nEdgeIndex, dSignal * arNew.Bulge());
|
||
}
|
||
else
|
||
{
|
||
poly2d.SetBulge(nEdgeIndex, -dSignal * arNew.Bulge());
|
||
}
|
||
}
|
||
}
|
||
|
||
for (int n = 0; n<poly2d.Length(); n++)
|
||
{
|
||
poly2d[n]->z = polyPath[n]->z;
|
||
}
|
||
polyPath = poly2d;
|
||
}
|
||
}
|
||
}
|
||
polyPath.Compress(false);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::GetGripText(const XPoly2D&poly,int idx,CString &cs)
|
||
{
|
||
Acad::ErrorStatus es = Acad::eNotApplicable;
|
||
|
||
int nVertexCount = poly.Length();
|
||
if (idx<nVertexCount)
|
||
{ // Move vertex
|
||
cs.Format(_T("移动第%d个顶点"), idx+1);
|
||
es = Acad::eOk;
|
||
}
|
||
else
|
||
{ // Move Edge or Shape
|
||
int nEdgeIndex = idx-nVertexCount;
|
||
int nTotalEdge = poly.TotalSegments();
|
||
if (nEdgeIndex<nTotalEdge)
|
||
{ //移动边
|
||
cs.Format(_T("移动第%d条边"), nEdgeIndex+1);
|
||
es = Acad::eOk;
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
#if ARX > 17
|
||
void XExport2::CreateGrip(AEntityBase* pThis,XPoly2D& poly,int iFirst)
|
||
{
|
||
XPoly2D&m_polyBase = poly;
|
||
//节点
|
||
for (long i = 0;i < m_polyBase.Length();i++)
|
||
{
|
||
if (m_polyBase.IsClosed() || i > 0)//有前段
|
||
{
|
||
bool bPreArc = fabs(m_polyBase.GetBulge((i - 1 + m_polyBase.Length()) % m_polyBase.Length())) > 1E-5;//前段是否为弧段
|
||
if (!bPreArc)//直段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripDistDim(AcDbDimData::kDimResultantLength));//长度
|
||
}
|
||
else//弧段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//包络角度[0,360)
|
||
}
|
||
}
|
||
|
||
if (m_polyBase.IsClosed() || i < m_polyBase.Length() - 1)//有后段
|
||
{
|
||
bool bNextArc = fabs(m_polyBase.GetBulge(i % m_polyBase.Length())) > 1E-5;//后段的是否为弧段
|
||
if (!bNextArc)//直段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripDistDim(AcDbDimData::kDimResultantLength));//长度
|
||
}
|
||
else//弧段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//包络角度[0,360)
|
||
}
|
||
}
|
||
|
||
if (m_polyBase.IsClosed()||i>0)//有前段
|
||
{
|
||
bool bPreArc = fabs(m_polyBase.GetBulge((i - 1 + m_polyBase.Length()) % m_polyBase.Length())) > 1E-5;//前段是否为弧段
|
||
if (!bPreArc)//直段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//角度[0,180]
|
||
}
|
||
else//弧段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//前弧终止角度[0,180]
|
||
}
|
||
}
|
||
|
||
if (m_polyBase.IsClosed() || i < m_polyBase.Length() - 1)//有后段
|
||
{
|
||
bool bNextArc = fabs(m_polyBase.GetBulge(i % m_polyBase.Length())) > 1E-5;//后段的是否为弧段
|
||
if (!bNextArc)//直段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//角度[0,180]
|
||
}
|
||
else//弧段
|
||
{
|
||
pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//后弧起始角度[0,180]
|
||
}
|
||
}
|
||
}
|
||
|
||
//边中点
|
||
for (int i = 0;i<m_polyBase.TotalSegments();i++)
|
||
{
|
||
bool bArc = fabs(m_polyBase.GetBulge(i)) > 1E-5;//是否弧边
|
||
long iSeg = i+m_polyBase.Length();
|
||
if (bArc)
|
||
{
|
||
pThis->GetGrip(iSeg + iFirst)->AppendDim(new AecDbGripRadiusDim(AcDbDimData::kDimRadius));//半径
|
||
pThis->GetGrip(iSeg + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//包络角度[0,360)
|
||
}
|
||
else
|
||
{
|
||
pThis->GetGrip(iSeg + iFirst)->AppendDim(new AecDbGripDistDim(AcDbDimData::kDimDeltaLength,false));//偏移
|
||
}
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::EntityToDim(AEntityBase* pThis,XPoly2D polyPath,long iGrip,long iDim,int iFirst)
|
||
{
|
||
AecDbGripDim *pDim = pThis->GetGripDim(iGrip,iDim);
|
||
if (pDim == NULL)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
iGrip -= iFirst;
|
||
XPoly2D m_polyBase;
|
||
AcGeVector3d normal;
|
||
pThis->GetPathPoly(m_polyBase,normal);
|
||
XPoint ptLow,ptUp;
|
||
polyPath.GetExtend(ptLow,ptUp);
|
||
//中点
|
||
if (iGrip >= polyPath.Length())
|
||
{
|
||
int nPos = iGrip - polyPath.Length();
|
||
XDirectionCurve seg;
|
||
polyPath.Nth(nPos, seg);
|
||
bool bArc = fabs(polyPath.GetBulge(nPos)) > 1E-5;//是否为弧段
|
||
if (!bArc)//直段
|
||
{
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
AecDbGripDistDim* pDistDim = (AecDbGripDistDim*)pDim;
|
||
XDirectionCurve seg1;
|
||
m_polyBase.Nth(nPos, seg1);
|
||
|
||
XPoint pt;
|
||
seg1.ProjectToMe(seg.MidPoint().AsAcGePoint3d(),pt);
|
||
pDistDim->SetData(pt.AsAcGePoint3d(),seg.MidPoint().AsAcGePoint3d(),0);
|
||
}
|
||
break;
|
||
default:
|
||
return Acad::eNotImplementedYet;
|
||
}
|
||
}
|
||
else//弧段
|
||
{
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
AecDbGripRadiusDim* pRadiusDim = (AecDbGripRadiusDim* )pDim;
|
||
pRadiusDim->SetData(seg.GetArc().GetCenterPt().AsAcGePoint3d(),seg.MidPoint().AsAcGePoint3d());
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
if ( seg.GetBulge() < 0)
|
||
{
|
||
seg.Reverse();
|
||
}
|
||
pAngleDim->SetData(seg);
|
||
}
|
||
break;
|
||
default:
|
||
return Acad::eNotImplementedYet;
|
||
}
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 端点
|
||
bool bPre = polyPath.IsClosed() || iGrip > 0;
|
||
int nPre = (iGrip - 1 + polyPath.Length()) % polyPath.Length();
|
||
|
||
XDirectionCurve segPre;
|
||
polyPath.Nth(nPre, segPre);
|
||
|
||
AcGeVector2d vtPre = segPre.Direction3d().AsAcGeVector2d();
|
||
bool bPreArc = fabs(polyPath.GetBulge(nPre)) > 1E-5;//前段是否为弧段
|
||
|
||
bool bNext = polyPath.IsClosed() || iGrip < polyPath.Length() - 1;
|
||
int nNext = iGrip % polyPath.Length();
|
||
|
||
XDirectionCurve segNext;
|
||
polyPath.Nth(nNext, segNext);
|
||
|
||
AcGeVector2d vtNext = segNext.Direction3d().AsAcGeVector2d();
|
||
bool bNextArc = fabs(polyPath.GetBulge(nNext)) > 1E-5;//后段的是否为弧段
|
||
|
||
if (bPre && bNext)
|
||
{// 有前段有后段
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
if (!bPreArc)//长度
|
||
{
|
||
AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim;
|
||
double dGrip = vtPre.angle() - vtNext.angle();
|
||
if ( dGrip < -1E-6 )
|
||
{
|
||
dGrip += 2 * PI;
|
||
}
|
||
|
||
if ( dGrip > 0 && dGrip < PI )
|
||
{
|
||
segPre.Reverse();
|
||
}
|
||
pDistDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(), segPre.GetEndPoint().AsAcGePoint3d());
|
||
}
|
||
else//包络角度
|
||
{
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
if ( segPre.GetBulge() < 0)
|
||
{
|
||
segPre.Reverse();
|
||
}
|
||
pAngleDim->SetData(segPre);
|
||
}
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
if (!bNextArc)//长度
|
||
{
|
||
AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim;
|
||
double dGrip = vtPre.angle() - vtNext.angle();
|
||
if ( dGrip < -1E-6 )
|
||
{
|
||
dGrip += 2 * PI;
|
||
}
|
||
|
||
if ( dGrip > 0 && dGrip < PI )
|
||
{
|
||
segNext.Reverse();
|
||
}
|
||
pDistDim->SetData(segNext.GetStartPoint().AsAcGePoint3d(), segNext.GetEndPoint().AsAcGePoint3d());
|
||
}
|
||
else//包络角度
|
||
{
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
if ( segNext.GetBulge() < 0)
|
||
{
|
||
segNext.Reverse();
|
||
}
|
||
pAngleDim->SetData(segNext);
|
||
}
|
||
}
|
||
break;
|
||
case 2:
|
||
{
|
||
if (!bPreArc)//角度
|
||
{
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XPoint ptEnd = segPre.GetStartPoint() + XPoint(1000,0,0);
|
||
pAngleDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d());
|
||
}
|
||
else//前弧终止角度
|
||
{
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XArc arc = segPre.GetArc();
|
||
XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0);
|
||
pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d());
|
||
}
|
||
}
|
||
break;
|
||
case 3:
|
||
{
|
||
if (!bNextArc)//角度
|
||
{
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XPoint ptEnd = segNext.GetEndPoint() + XPoint(1000,0,0);
|
||
pAngleDim->SetData(segNext.GetEndPoint().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d());
|
||
}
|
||
else//前弧终止角度
|
||
{
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XArc arc = segNext.GetArc();
|
||
XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0);
|
||
pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d());
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
return Acad::eNotImplementedYet;
|
||
}
|
||
}
|
||
else if (bPre && !bNext)
|
||
{// 有前段无后段
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
if (!bPreArc)
|
||
{//长度
|
||
AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim;
|
||
if ( segPre.Direction3d().y >= 0 )
|
||
{
|
||
pDistDim->SetData(segPre.GetEndPoint().AsAcGePoint3d(), segPre.GetStartPoint().AsAcGePoint3d());
|
||
}
|
||
else
|
||
{
|
||
pDistDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(), segPre.GetEndPoint().AsAcGePoint3d());
|
||
}
|
||
}
|
||
else
|
||
{//包络角度
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
if ( segPre.GetBulge() < 0)
|
||
{
|
||
segPre.Reverse();
|
||
}
|
||
pAngleDim->SetData(segPre);
|
||
}
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
if (!bPreArc)
|
||
{//角度
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XPoint ptEnd = segPre.GetStartPoint() + XPoint(1000,0,0);
|
||
pAngleDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d());
|
||
}
|
||
else
|
||
{//后弧起始角度
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XArc arc = segPre.GetArc();
|
||
XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0);
|
||
pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d());
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
return Acad::eNotImplementedYet;
|
||
}
|
||
}
|
||
else if (!bPre && bNext)
|
||
{// 无前段有后段
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
if (!bNextArc)
|
||
{//长度
|
||
AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim;
|
||
if ( segNext.Direction3d().y >= 0 )
|
||
{
|
||
pDistDim->SetData(segNext.GetEndPoint().AsAcGePoint3d(), segNext.GetStartPoint().AsAcGePoint3d());
|
||
}
|
||
else
|
||
{
|
||
pDistDim->SetData(segNext.GetStartPoint().AsAcGePoint3d(), segNext.GetEndPoint().AsAcGePoint3d());
|
||
}
|
||
}
|
||
else
|
||
{//包络角度
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
if ( segNext.GetBulge() < 0)
|
||
{
|
||
segNext.Reverse();
|
||
}
|
||
pAngleDim->SetData(segNext);
|
||
}
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
if (!bNextArc)
|
||
{//角度
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XPoint ptEnd = segNext.GetEndPoint() + XPoint(1000,0,0);
|
||
pAngleDim->SetData(segNext.GetEndPoint().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d());
|
||
}
|
||
else
|
||
{//后弧起始角度
|
||
AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim;
|
||
XArc arc = segNext.GetArc();
|
||
XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0);
|
||
pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d());
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
return Acad::eNotImplementedYet;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Acad::eNotImplementedYet;
|
||
}
|
||
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus XExport2::DimToEntity(AEntityBase* pThis,XPoly2D &m_polyBase,long iGrip,long iDim,double newValue,const AcGeVector3d& offset,int iFirst)
|
||
{
|
||
AcGePoint3d ptNew = pThis->GetGripPoint(iGrip) + offset;
|
||
|
||
iGrip -= iFirst;
|
||
//中点
|
||
if (iGrip >= m_polyBase.Length())
|
||
{
|
||
int nPos = iGrip - m_polyBase.Length();
|
||
bool bArc = fabs(m_polyBase.GetBulge(nPos)) > 1E-5;//是否为弧段
|
||
if (!bArc)//直段
|
||
{
|
||
switch(iDim)
|
||
{
|
||
case 0://偏移
|
||
{
|
||
XPoly2D poly2d(m_polyBase);
|
||
poly2d.SetElevation(0.0);
|
||
|
||
int nTotalEdge = poly2d.TotalSegments();
|
||
XDirectionCurve seg;
|
||
poly2d.Nth(nPos, seg);
|
||
|
||
AcGeVector3d vtOffset = offset;
|
||
vtOffset.normalize();
|
||
|
||
double dAngle = vtOffset.angleTo(seg.Direction3d().AsAcGeVector3d());
|
||
vtOffset *= newValue / sin(dAngle);
|
||
|
||
if (seg.OnWhichSide(ptNew) == 0)
|
||
{//左边
|
||
newValue *= -1;
|
||
}
|
||
|
||
XLine ln = seg.GetLine();
|
||
ln = ln.Offset(newValue);
|
||
ln.SetLineFlag( LS_INFINITE);
|
||
|
||
XDirectionCurve prevSeg, nextSeg;
|
||
int nPrev = nPos - 1;
|
||
int nNext = nPos + 1;
|
||
|
||
if (poly2d.IsClosed())
|
||
{
|
||
nPrev = XExport::DePeriod(nTotalEdge, nPrev);
|
||
nNext = XExport::DePeriod(nTotalEdge, nNext);
|
||
}
|
||
|
||
XPoint ptStart, ptEnd;
|
||
BOOL bUpdateIt = TRUE;
|
||
//更新起点
|
||
if (nPrev >= 0 && nPrev < nTotalEdge)
|
||
{
|
||
poly2d.Nth(nPrev, prevSeg);
|
||
prevSeg.SetLineFlag( LS_INFINITE);
|
||
|
||
XPoint ptInt[2];
|
||
int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
{
|
||
ptStart = ptInt[0];
|
||
}
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetStartPoint());
|
||
}
|
||
else
|
||
{
|
||
bUpdateIt = FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ptStart = *poly2d[nPos] + vtOffset;
|
||
}
|
||
|
||
// 更新下一点
|
||
if (nNext >= 0 && nNext < nTotalEdge)
|
||
{
|
||
poly2d.Nth(nNext, nextSeg);
|
||
nextSeg.SetLineFlag(LS_INFINITE);
|
||
|
||
XPoint ptInt[2];
|
||
int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
{
|
||
ptEnd = ptInt[0];
|
||
}
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetEndPoint());
|
||
}
|
||
else
|
||
{
|
||
bUpdateIt = FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ptEnd = *poly2d[nPos + 1] + vtOffset;
|
||
}
|
||
|
||
if (bUpdateIt)
|
||
{
|
||
double nPrevBulge = 0.0, nNextBulge = 0.0;
|
||
if (fabs(prevSeg.GetBulge()) > 1.0E-5)
|
||
{
|
||
XArc prevArc = prevSeg.GetArc();
|
||
double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.GetStartPoint());
|
||
double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart);
|
||
if (prevSeg.IsMinusArc())
|
||
{
|
||
nPrevBulge = -XExport::CT_std_angle(nAngBeg - nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nPrevBulge = XExport::CT_std_angle(nAngEnd - nAngBeg);
|
||
}
|
||
}
|
||
if (fabs(nextSeg.GetBulge()) > 1.0E-5)
|
||
{
|
||
XArc nextArc = nextSeg.GetArc();
|
||
double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd);
|
||
double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.GetEndPoint());
|
||
if (nextSeg.IsMinusArc())
|
||
{
|
||
nNextBulge = -XExport::CT_std_angle(nAngBeg - nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nNextBulge = XExport::CT_std_angle(nAngEnd - nAngBeg);
|
||
}
|
||
}
|
||
|
||
*poly2d[nPos] = ptStart;
|
||
if (nNext >= 0 && nNext < poly2d.Length())
|
||
{
|
||
*poly2d[nNext] = ptEnd;
|
||
poly2d.SetBulge(nNext, nNextBulge);
|
||
}
|
||
if (nPrev >= 0 && nPrev < poly2d.Length())
|
||
{
|
||
poly2d.SetBulge(nPrev, nPrevBulge);
|
||
}
|
||
|
||
for (int n = 0; n < poly2d.Length(); n++)
|
||
{
|
||
poly2d[n]->z = m_polyBase[n]->z;
|
||
}
|
||
|
||
m_polyBase = poly2d;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
XDirectionCurve seg;
|
||
m_polyBase.Nth(nPos, seg);
|
||
switch(iDim)
|
||
{
|
||
case 0://半径
|
||
{
|
||
XCurveSegment line(seg.GetStartPoint(),seg.GetEndPoint(),0);
|
||
double len = line.GetLength();
|
||
if (newValue < 0.5 * len)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
newValue = 2.0 * asin(len* 0.5 / newValue);
|
||
XPoint ptMid = seg.MidPoint();
|
||
if (ptMid.Distance2d(ptNew) > len / 2)
|
||
{
|
||
newValue = 2.0 * PI - newValue;
|
||
}
|
||
}
|
||
case 1://包络角
|
||
{
|
||
seg.SetBulge(0);
|
||
if (seg.OnWhichSide(ptNew) == 0)
|
||
{//左边
|
||
newValue *= -1;
|
||
}
|
||
|
||
m_polyBase.SetBulge(nPos, newValue);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 端点
|
||
bool bPre = m_polyBase.IsClosed() || iGrip > 0;
|
||
int nPre = (iGrip - 1 + m_polyBase.Length()) % m_polyBase.Length();
|
||
XDirectionCurve segPre;
|
||
m_polyBase.Nth(nPre, segPre);
|
||
|
||
bool bPreArc = fabs(m_polyBase.GetBulge(nPre)) > 1E-5;//前段是否为弧段
|
||
|
||
bool bNext = m_polyBase.IsClosed() || iGrip < m_polyBase.Length() - 1;
|
||
int nNext = iGrip % m_polyBase.Length();
|
||
XDirectionCurve segNext;
|
||
m_polyBase.Nth(nNext, segNext);
|
||
|
||
bool bNextArc = fabs(m_polyBase.GetBulge(nNext)) > 1E-5;//后段的是否为弧段
|
||
|
||
if (bPre && bNext)
|
||
{// 有前段有后段
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
if (!bPreArc)//长度
|
||
{
|
||
if (newValue>1E-6)
|
||
{
|
||
XPoint vt = segPre.Direction3d();
|
||
AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d();
|
||
if (vt.AsAcGeVector3d().dotProduct(vt1) > 0)
|
||
{
|
||
vt *= newValue;
|
||
}
|
||
else
|
||
{
|
||
vt *= -newValue;
|
||
}
|
||
*m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt;
|
||
}
|
||
}
|
||
else//包络角度
|
||
{
|
||
XArc arc = segPre.GetArc();
|
||
if (segPre.GetBulge() < 0)
|
||
{
|
||
arc.SetStarAngle(arc.GetEndAngle() - newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
|
||
m_polyBase.SetBulge(nPre, -arc.Bulge());
|
||
*m_polyBase[nPre + 1] = segPre.GetStartPoint();
|
||
}
|
||
else
|
||
{
|
||
arc.SetEndAngle(arc.GetStarAngle() + newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
m_polyBase.SetBulge(nPre, arc.Bulge());
|
||
*m_polyBase[nPre + 1] = segPre.GetEndPoint();
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
if (!bNextArc)
|
||
{//长度
|
||
if (newValue>1E-6)
|
||
{
|
||
XPoint vt = segNext.Direction3d();
|
||
AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d();
|
||
if (vt.AsAcGeVector3d().dotProduct(vt1) > 0)
|
||
{
|
||
vt *= newValue;
|
||
}
|
||
else
|
||
{
|
||
vt *= -newValue;
|
||
}
|
||
*m_polyBase[nNext] = segNext.GetEndPoint() + vt;
|
||
}
|
||
}
|
||
else
|
||
{//包络角度
|
||
XArc arc = segNext.GetArc();
|
||
if (segNext.GetBulge() < 0)
|
||
{
|
||
arc.SetEndAngle(arc.GetStarAngle() + newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, -arc.Bulge());
|
||
*m_polyBase[nNext] = segNext.GetEndPoint();
|
||
}
|
||
else
|
||
{
|
||
arc.SetStarAngle(arc.GetEndAngle() - newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, arc.Bulge());
|
||
*m_polyBase[nNext] = segNext.GetStartPoint();
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 2:
|
||
{
|
||
if (!bPreArc)
|
||
{//角度
|
||
AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d();
|
||
if (vt1.y < 0)
|
||
{
|
||
newValue *= -1;
|
||
}
|
||
|
||
XPoint vt2(segPre.GetLength(),0,0);
|
||
vt2.Rotate(newValue);
|
||
*m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt2;
|
||
}
|
||
else
|
||
{//前弧终止角度
|
||
XArc arc = segPre.GetArc();
|
||
if (ptNew.y < arc.GetCenterPt().y)
|
||
{
|
||
newValue = 2.0 * PI - newValue;
|
||
}
|
||
|
||
if (segPre.GetBulge() < 0)
|
||
{
|
||
arc.SetStarAngle( newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
m_polyBase.SetBulge(nPre, -arc.Bulge());
|
||
}
|
||
else
|
||
{
|
||
arc.SetEndAngle(newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
m_polyBase.SetBulge(nPre, arc.Bulge());
|
||
}
|
||
*m_polyBase[nPre + 1] = segPre.GetEndPoint();
|
||
}
|
||
}
|
||
break;
|
||
case 3:
|
||
{
|
||
if (!bNextArc)
|
||
{//角度
|
||
AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d();
|
||
if (vt1.y < 0)
|
||
{
|
||
newValue *= -1;
|
||
}
|
||
|
||
XPoint vt2(segNext.GetLength(),0,0);
|
||
vt2.Rotate(newValue);
|
||
*m_polyBase[nNext] = segNext.GetEndPoint() + vt2;
|
||
}
|
||
else
|
||
{//后弧起始角度
|
||
XArc arc = segNext.GetArc();
|
||
if (ptNew.y < arc.GetCenterPt().y)
|
||
{
|
||
newValue = 2.0 * PI - newValue;
|
||
}
|
||
|
||
if (segNext.GetBulge() < 0)
|
||
{
|
||
arc.SetEndAngle(newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, -arc.Bulge());
|
||
}
|
||
else
|
||
{
|
||
arc.SetStarAngle(newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, arc.Bulge());
|
||
}
|
||
*m_polyBase[nNext] = segNext.GetStartPoint();
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else if (bPre && !bNext)
|
||
{// 有前段无后段
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
if (!bPreArc)//长度
|
||
{
|
||
if (newValue > 1E-6)
|
||
{
|
||
XPoint vt = segPre.Direction3d();
|
||
AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d();
|
||
if (vt.AsAcGeVector3d().dotProduct(vt1) > 0)
|
||
{
|
||
vt *= newValue;
|
||
}
|
||
else
|
||
{
|
||
vt *= -newValue;
|
||
}
|
||
*m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt;
|
||
}
|
||
}
|
||
else//包络角度
|
||
{
|
||
XArc arc = segPre.GetArc();
|
||
if (segPre.GetBulge() < 0)
|
||
{
|
||
arc.SetStarAngle(arc.GetEndAngle() - newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
m_polyBase.SetBulge(nPre, -arc.Bulge());
|
||
*m_polyBase[nPre + 1] = segPre.GetStartPoint();
|
||
}
|
||
else
|
||
{
|
||
arc.SetEndAngle(arc.GetStarAngle() + newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
m_polyBase.SetBulge(nPre, arc.Bulge());
|
||
*m_polyBase[nPre + 1] = segPre.GetEndPoint();
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
if (!bPreArc)
|
||
{//角度
|
||
AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d();
|
||
if (vt1.y < 0)
|
||
{
|
||
newValue *= -1;
|
||
}
|
||
|
||
XPoint vt2(segPre.GetLength(),0,0);
|
||
vt2.Rotate(newValue);
|
||
*m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt2;
|
||
}
|
||
else
|
||
{//前弧终止角度
|
||
XArc arc = segPre.GetArc();
|
||
if (ptNew.y < arc.GetCenterPt().y)
|
||
{
|
||
newValue = 2.0 * PI - newValue;
|
||
}
|
||
if (segPre.GetBulge() < 0)
|
||
{
|
||
arc.SetStarAngle(newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
m_polyBase.SetBulge(nPre, -arc.Bulge());
|
||
}
|
||
else
|
||
{
|
||
arc.SetEndAngle(newValue);
|
||
arc.GetStartPoint(segPre.StartPoint());
|
||
arc.GetEndPoint(segPre.EndPoint());
|
||
m_polyBase.SetBulge(nPre, arc.Bulge());
|
||
}
|
||
*m_polyBase[nPre + 1] = segPre.GetEndPoint();
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else if (!bPre && bNext)
|
||
{// 无前段有后段
|
||
switch(iDim)
|
||
{
|
||
case 0:
|
||
{
|
||
if (!bNextArc)
|
||
{//长度
|
||
if (newValue > 1E-6)
|
||
{
|
||
XPoint vt = segNext.Direction3d();
|
||
AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d();
|
||
if (vt.AsAcGeVector3d().dotProduct(vt1) > 0)
|
||
{
|
||
vt *= newValue;
|
||
}
|
||
else
|
||
{
|
||
vt *= -newValue;
|
||
}
|
||
*m_polyBase[nNext] = segNext.GetEndPoint() + vt;
|
||
}
|
||
}
|
||
else
|
||
{//包络角度
|
||
XArc arc = segNext.GetArc();
|
||
if (segNext.GetBulge() < 0)
|
||
{
|
||
arc.SetEndAngle(arc.GetStarAngle() + newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, -arc.Bulge());
|
||
*m_polyBase[nNext] = segNext.GetEndPoint();
|
||
}
|
||
else
|
||
{
|
||
arc.SetStarAngle(arc.GetEndAngle() - newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, arc.Bulge());
|
||
*m_polyBase[nNext] = segNext.GetStartPoint();
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
if (!bNextArc)
|
||
{//角度
|
||
AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d();
|
||
if (vt1.y<0)
|
||
{
|
||
newValue *= -1;
|
||
}
|
||
|
||
XPoint vt2(segNext.GetLength(),0,0);
|
||
vt2.Rotate(newValue);
|
||
*m_polyBase[nNext] = segNext.GetEndPoint() + vt2;
|
||
}
|
||
else
|
||
{//后弧起始角度
|
||
XArc arc = segNext.GetArc();
|
||
if (ptNew.y < arc.GetCenterPt().y)
|
||
{
|
||
newValue = 2.0 * PI - newValue;
|
||
}
|
||
if (segNext.GetBulge() < 0)
|
||
{
|
||
arc.SetEndAngle(newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, -arc.Bulge());
|
||
}
|
||
else
|
||
{
|
||
arc.SetStarAngle(newValue);
|
||
arc.GetStartPoint(segNext.StartPoint());
|
||
arc.GetEndPoint(segNext.EndPoint());
|
||
m_polyBase.SetBulge(nNext, arc.Bulge());
|
||
}
|
||
*m_polyBase[nNext] = segNext.GetStartPoint();
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
return Acad::eOk;
|
||
}
|
||
#endif
|
||
|
||
|
||
// 区域的布尔运算
|
||
Adesk::Boolean XExport2::PolyBoolOper(const XPoly2D &poly1, const XPoly2D & poly2, DList<XPoly2D> & poly, AcDb::BoolOperType operation)
|
||
{
|
||
int nRetCode = RTERROR;
|
||
|
||
if ( XPrivate::GetGlobalConfigBase() != NULL)
|
||
{
|
||
nRetCode = XPrivate::GetGlobalConfigBase()->BoolOper(operation,(LPVOID)&poly1,(LPVOID)&poly2,(LPVOID)&poly);
|
||
}
|
||
|
||
return (nRetCode == RTNORM ? Adesk::kTrue : Adesk::kFalse);
|
||
}
|
||
|
||
// 区域的并集
|
||
void XExport2::Union(const DList<XPoly2D> &lstSourcePolies, const DList<XPoly2D> &lstClipPolies, DList<XPoly2D> &lstResultPolies)
|
||
{
|
||
//return;//zjq---
|
||
|
||
DList<XPoly2D> lstSource, lstDest, *pSource = NULL, *pDest = NULL;
|
||
pSource = &lstSource;
|
||
pDest = &lstDest;
|
||
for (int i = 0; i<lstSourcePolies.Length(); i++)
|
||
{
|
||
lstSource.Append(new XPoly2D(lstSourcePolies[i]));
|
||
}
|
||
int nPiceNum = lstClipPolies.Length();
|
||
int nStep = nPiceNum / 100;
|
||
if (nStep<1)
|
||
{
|
||
nStep = 1;
|
||
}
|
||
if (g_bEchoSearch && nStep > 1)
|
||
{
|
||
acedSetStatusBarProgressMeter(_T("求并集"), 0, nPiceNum);
|
||
}
|
||
for (int i = 0; i<lstClipPolies.Length(); i++)
|
||
{
|
||
if (g_bEchoSearch && nStep>1 && !(i%nStep))
|
||
{
|
||
acedSetStatusBarProgressMeterPos(i);
|
||
}
|
||
const XPoly2D &polyClip = lstClipPolies[i];
|
||
pDest->Reset();
|
||
for (int j = 0; j<pSource->Length(); j++)
|
||
{
|
||
XPoly2D &polySrc = *(*pSource)[j];
|
||
if ( XPrivate::GetGlobalConfigBase() != NULL)
|
||
{
|
||
XPrivate::GetGlobalConfigBase()->BoolOper(AcDb::kBoolUnite,(LPVOID)&polySrc,(LPVOID)&polyClip,(LPVOID)pDest);
|
||
}
|
||
|
||
//Union(polySrc, polyClip, *pDest);
|
||
}
|
||
Exchange(pSource, pDest);
|
||
}
|
||
if (g_bEchoSearch && nStep > 1)
|
||
{
|
||
acedRestoreStatusBar();
|
||
}
|
||
for (int i = 0; i<pSource->Length(); i++)
|
||
{
|
||
XPoly2D *pPoly = new XPoly2D(*(*pSource)[i]);
|
||
pPoly->Compress();
|
||
lstResultPolies.Append(pPoly);
|
||
}
|
||
}
|
||
|
||
// 区域的减法
|
||
void XExport2::Subtract(const DList<XPoly2D> &lstSourcePolies, const DList<XPoly2D> &lstClipPolies, DList<XPoly2D> &lstResultPolies)
|
||
{
|
||
//return;//zjq---
|
||
DList<XPoly2D> lstSource, lstDest, *pSource = NULL, *pDest = NULL;
|
||
pSource = &lstSource;
|
||
pDest = &lstDest;
|
||
for (int i = 0; i<lstSourcePolies.Length(); i++)
|
||
{
|
||
lstSource.Append(new XPoly2D(lstSourcePolies[i]));
|
||
}
|
||
|
||
for (int i = 0; i<lstClipPolies.Length(); i++)
|
||
{
|
||
const XPoly2D &polyClip = lstClipPolies[i];
|
||
pDest->Reset();
|
||
for (int j = 0; j<pSource->Length(); j++)
|
||
{
|
||
XPoly2D &polySrc = *(*pSource)[j];
|
||
|
||
if ( XPrivate::GetGlobalConfigBase() != NULL)
|
||
{
|
||
XPrivate::GetGlobalConfigBase()->BoolOper(AcDb::kBoolSubtract,(LPVOID)&polySrc,(LPVOID)&polyClip,(LPVOID)pDest);
|
||
}
|
||
|
||
//Subtract(polySrc, polyClip, *pDest);
|
||
}
|
||
Exchange(pSource, pDest);
|
||
}
|
||
for (int i = 0; i<pSource->Length(); i++)
|
||
{
|
||
XPoly2D *pPoly = new XPoly2D(*(*pSource)[i]);
|
||
pPoly->Compress();
|
||
lstResultPolies.Append(pPoly);
|
||
}
|
||
}
|
||
|
||
// 区域的减法
|
||
void XExport2::Intersect(const DList<XPoly2D> &lstSourcePolies, const DList<XPoly2D> &lstClipPolies, DList<XPoly2D> &lstResultPolies)
|
||
{
|
||
//return;//zjq---
|
||
DList<XPoly2D> lstSource, lstDest, *pSource = NULL, *pDest = NULL;
|
||
pSource = &lstSource;
|
||
pDest = &lstDest;
|
||
for (int i = 0; i<lstSourcePolies.Length(); i++)
|
||
{
|
||
lstSource.Append(new XPoly2D(lstSourcePolies[i]));
|
||
}
|
||
|
||
for (int i = 0; i<lstClipPolies.Length(); i++)
|
||
{
|
||
const XPoly2D &polyClip = lstClipPolies[i];
|
||
pDest->Reset();
|
||
for (int j = 0; j<pSource->Length(); j++)
|
||
{
|
||
XPoly2D &polySrc = *(*pSource)[j];
|
||
if ( XPrivate::GetGlobalConfigBase() != NULL)
|
||
{
|
||
XPrivate::GetGlobalConfigBase()->BoolOper(AcDb::kBoolIntersect,(LPVOID)&polySrc,(LPVOID)&polyClip,(LPVOID)pDest);
|
||
}
|
||
|
||
//XExport2::Intersect(polySrc, polyClip, *pDest);
|
||
}
|
||
Exchange(pSource, pDest);
|
||
}
|
||
for (int i = 0; i<pSource->Length(); i++)
|
||
{
|
||
XPoly2D *pPoly = new XPoly2D(*(*pSource)[i]);
|
||
pPoly->Compress();
|
||
lstResultPolies.Append(pPoly);
|
||
}
|
||
}
|
||
|
||
void XExport2::InitModel(const XMasterProperties &prop, const AcDbEntity *pEntity,
|
||
AcGeMatrix3d *pMatTran, AcDbVoidPtrArray &entSet3dface)
|
||
{
|
||
TCHAR szMatch[256] = _T("AEC_*");
|
||
|
||
XMasterProperties subProp(prop);
|
||
subProp.SetFrom(pEntity);
|
||
if (pEntity->isKindOf(AcDbFace::desc()))
|
||
{
|
||
AcDbFace *pFace = (AcDbFace *)pEntity->clone();
|
||
ASSERT(pFace);
|
||
if (pMatTran)
|
||
{
|
||
if (pFace->transformBy(*pMatTran) != Acad::eOk)
|
||
{
|
||
AcGePoint3d ptArray[4];
|
||
for (int i = 0; i<4; i++)
|
||
{
|
||
pFace->getVertexAt(i, ptArray[i]);
|
||
ptArray[i].transformBy(*pMatTran);
|
||
pFace->setVertexAt(i, ptArray[i]);
|
||
}
|
||
}
|
||
}
|
||
subProp.SetTo(pFace);
|
||
entSet3dface.append(pFace);
|
||
}
|
||
else if (pEntity->isKindOf(AcDbPolyFaceMesh::desc()) || pEntity->isKindOf(AcDbPolygonMesh::desc()))
|
||
{
|
||
AcDbVoidPtrArray entSet1;
|
||
VERIFY(pEntity->explode(entSet1) == Acad::eOk);
|
||
InitModel(subProp, entSet1, pMatTran, entSet3dface);
|
||
XExport::ReleaseEntSet(entSet1);
|
||
}
|
||
else if (pEntity->isKindOf(AcDbBlockReference::desc()))
|
||
{
|
||
AcDbBlockReference *pInsert = AcDbBlockReference::cast(pEntity);
|
||
ASSERT(pInsert);
|
||
AcGeMatrix3d matNew = BlockTransform(pInsert);
|
||
if (pMatTran)
|
||
{
|
||
matNew.preMultBy(*pMatTran);
|
||
}
|
||
AcDbObjectId idBlock = pInsert->blockTableRecord();
|
||
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockTableRecord);
|
||
if (pBlockTableRecord)
|
||
{
|
||
AcDbBlockTableRecordIterator *pBlockIterator = NULL;
|
||
VERIFY(pBlockTableRecord->newIterator(pBlockIterator) == Acad::eOk && pBlockIterator);
|
||
for (pBlockIterator->start(); !pBlockIterator->done();pBlockIterator->step())
|
||
{
|
||
AcDbEntity *pEntNew = NULL;
|
||
if (pBlockIterator->getEntity(pEntNew, AcDb::kForRead) != Acad::eOk || !pEntNew)
|
||
{
|
||
continue;
|
||
}
|
||
if (pEntNew->visibility() == AcDb::kVisible)
|
||
{
|
||
XExport2::InitModel(subProp, pEntNew, &matNew, entSet3dface);
|
||
}
|
||
pEntNew->close();
|
||
}
|
||
delete pBlockIterator;
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
else if (ads_wcmatch(pEntity->isA()->dxfName(), szMatch) == RTNORM)
|
||
{ // 在2000i/20002下,$对象的分解由于调用了Region的运算导致出错有问题
|
||
AcDbVoidPtrArray entSet1;
|
||
if (pEntity->explode(entSet1) == Acad::eOk)
|
||
{
|
||
XExport2::InitModel(subProp, entSet1, pMatTran, entSet3dface);
|
||
XExport::ReleaseEntSet(entSet1);
|
||
}
|
||
}
|
||
else if (_tcsicmp(pEntity->isA()->dxfName(), _T("3DSOLID")) == 0 || _tcsicmp(pEntity->isA()->dxfName(), _T("REGION")) == 0 ||
|
||
_tcsicmp(pEntity->isA()->dxfName(), _T("3DBODY")) == 0 )
|
||
{
|
||
AcDbVoidPtrArray entSet;
|
||
ExplodeAcis(pEntity, entSet);
|
||
XExport2::InitModel(subProp, entSet, pMatTran, entSet3dface);
|
||
XExport::ReleaseEntSet(entSet);
|
||
}
|
||
else if (_tcsicmp(pEntity->isA()->dxfName(), _T("SOLID")) == 0)
|
||
{ //二维物体
|
||
AcDbSolid *pClone = (AcDbSolid *)pEntity->clone();
|
||
ASSERT(pClone);
|
||
if (pMatTran)
|
||
{
|
||
if (pClone->transformBy(*pMatTran) != Acad::eOk)
|
||
{
|
||
AcGePoint3d ptArray[4];
|
||
for (int i = 0; i<4; i++)
|
||
{
|
||
pClone->getPointAt(i, ptArray[i]);
|
||
ptArray[i].transformBy(*pMatTran);
|
||
pClone->setPointAt(i, ptArray[i]);
|
||
}
|
||
}
|
||
}
|
||
subProp.SetTo(pClone);
|
||
entSet3dface.append(pClone);
|
||
}
|
||
else if (pEntity->isA() == AcDbLine::desc())
|
||
{
|
||
AcDbLine *pLine = (AcDbLine *)pEntity->clone();
|
||
ASSERT(pLine);
|
||
if (pMatTran)
|
||
{
|
||
if (pLine->transformBy(*pMatTran) != Acad::eOk)
|
||
{
|
||
AcGePoint3d pt1 = pLine->startPoint();
|
||
AcGePoint3d pt2 = pLine->endPoint();
|
||
AcGeVector3d vt = pLine->normal();
|
||
AcGeVector3d vtNormal = vt;
|
||
vt *= pLine->thickness();
|
||
pt1.transformBy(*pMatTran);
|
||
pt2.transformBy(*pMatTran);
|
||
vt.transformBy(*pMatTran);
|
||
vtNormal.transformBy(*pMatTran);
|
||
if (vt.length()>_DIST_SNAP)
|
||
{
|
||
AcDbFace *pFace = new AcDbFace(pt1, pt2, pt2+vt, pt1+vt);
|
||
subProp.SetTo(pFace);
|
||
entSet3dface.append(pFace);
|
||
delete pLine;
|
||
}
|
||
else
|
||
{
|
||
pLine->setStartPoint(pt1);
|
||
pLine->setEndPoint(pt2);
|
||
pLine->setThickness(0.0);
|
||
vtNormal.normalize();
|
||
pLine->setNormal(vtNormal);
|
||
subProp.SetTo(pLine);
|
||
entSet3dface.append(pLine);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
subProp.SetTo(pLine);
|
||
entSet3dface.append(pLine);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
AcGeVector3d vt = pLine->normal();
|
||
AcGeVector3d vtNormal = vt;
|
||
vt *= pLine->thickness();
|
||
AcGePoint3d pt1 = pLine->startPoint();
|
||
AcGePoint3d pt2 = pLine->endPoint();
|
||
if (vt.length()>_DIST_SNAP)
|
||
{
|
||
AcDbFace *pFace = new AcDbFace(pt1, pt2, pt2+vt, pt1+vt);
|
||
subProp.SetTo(pFace);
|
||
entSet3dface.append(pFace);
|
||
delete pLine;
|
||
}
|
||
else
|
||
{
|
||
pLine->setStartPoint(pt1);
|
||
pLine->setEndPoint(pt2);
|
||
pLine->setThickness(0.0);
|
||
vtNormal.normalize();
|
||
pLine->setNormal(vtNormal);
|
||
subProp.SetTo(pLine);
|
||
entSet3dface.append(pLine);
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{ //拉伸的曲线
|
||
AcDbPolyline *pline = AsPolyline(pEntity);
|
||
if (pline)
|
||
{
|
||
if (pline->thickness()>_DIST_SNAP)
|
||
{
|
||
// 没有消除圆弧折线化后的不可见边
|
||
double nThick = pline->thickness();
|
||
XPoly2D poly;
|
||
XExport2::PolyConvert(*pline, poly);
|
||
|
||
if (poly.IsClosed() && poly.PathArea()>0.0)
|
||
{
|
||
poly.Reverse(); //确保逆时针
|
||
}
|
||
XVector3D vtNormal;
|
||
AcGeVector3d vt = pline->normal();
|
||
(AcGeVector3d &)vtNormal = vt;
|
||
|
||
double nWidth = 0.0;
|
||
if (pline->getConstantWidth(nWidth) != Acad::eOk)
|
||
{
|
||
nWidth = 0.0;
|
||
}
|
||
if (nWidth>_DIST_SNAP)
|
||
{
|
||
XPoly2D poly1, poly2;
|
||
poly.Offset(-nWidth/2, poly1);
|
||
poly.Offset(nWidth/2, poly2);
|
||
ThickPoly2Face(subProp, poly1, vtNormal, nThick, entSet3dface, pMatTran);
|
||
ThickPoly2Face(subProp, poly2, vtNormal, nThick, entSet3dface, pMatTran);
|
||
|
||
if (poly.IsClosed())
|
||
{
|
||
poly1.SetFlag(0);
|
||
poly2.SetFlag(0);
|
||
poly1.AppendNode(*poly1.Head());
|
||
poly2.AppendNode(*poly2.Head());
|
||
}
|
||
XPoly2D poly3(poly1);
|
||
poly2.Reverse();
|
||
for (int n = 0; n<poly2.Length(); n++)
|
||
{
|
||
poly3.AppendNode(*poly2[n], poly2.GetBulge(n));
|
||
}
|
||
XPoly polygon;
|
||
poly3.AsOpenPoly1(polygon, _AS_SYS_UNIT(g_nCirDeviation));
|
||
|
||
DList<XTriangle> lstTris[2];
|
||
|
||
XHoleModel model;
|
||
for (int k = 0; k < polygon.Length(); k++)
|
||
{
|
||
//model.m_outline.AppendNode(*polygon[k], TRUE);
|
||
model.GetOutLine().AppendNode(*poly1[k], TRUE);
|
||
}
|
||
model.Triangulate(FALSE, lstTris[0]);
|
||
|
||
XPoint vtN = vtNormal;
|
||
vtN *= nThick;
|
||
for (int n = 0; n<lstTris[0].Length(); n++)
|
||
{
|
||
XTriangle *pTri = lstTris[0][n];
|
||
XTriangle *pTri1 = new XTriangle(*pTri);
|
||
pTri1->vertex1 += vtN;
|
||
pTri1->vertex2 += vtN;
|
||
pTri1->vertex3 += vtN;
|
||
lstTris[1].Append(pTri1);
|
||
}
|
||
for (int ii = 0; ii<2; ii++)
|
||
{
|
||
for (int jj = 0; jj<lstTris[ii].Length(); jj++)
|
||
{
|
||
XTriangle *triangle = lstTris[ii][jj];
|
||
triangle->vertex1 = Ecs2Wcs(triangle->vertex1, vtNormal);
|
||
triangle->vertex2 = Ecs2Wcs(triangle->vertex2, vtNormal);
|
||
triangle->vertex3 = Ecs2Wcs(triangle->vertex3, vtNormal);
|
||
Adesk::Boolean bSide1 = !(triangle->m_nFlag&SIDE1_INVISIBLE);
|
||
Adesk::Boolean bSide2 = !(triangle->m_nFlag&SIDE2_INVISIBLE);
|
||
Adesk::Boolean bSide3 = !(triangle->m_nFlag&SIDE3_INVISIBLE);
|
||
AcDbFace *pFace = new AcDbFace(triangle->vertex1, triangle->vertex2,
|
||
triangle->vertex3, triangle->vertex1, bSide1, bSide2, bSide3);
|
||
subProp.SetTo(pFace);
|
||
entSet3dface.append(pFace);
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
ThickPoly2Face(subProp, poly, vtNormal, nThick, entSet3dface, pMatTran);
|
||
}
|
||
delete pline;
|
||
}
|
||
else
|
||
{
|
||
if (!pMatTran)
|
||
{
|
||
subProp.SetTo(pline);
|
||
entSet3dface.append(pline);
|
||
}
|
||
else if (pline->transformBy(*pMatTran) == Acad::eOk)
|
||
{
|
||
subProp.SetTo(pline);
|
||
entSet3dface.append(pline);
|
||
}
|
||
else
|
||
{
|
||
XPoly2D poly2d, polyDest;
|
||
XExport2::PolyConvert(*pline, poly2d);
|
||
|
||
poly2d.Disperse1(polyDest, _AS_SYS_UNIT(g_nCirDeviation));
|
||
AcGeVector3d vtNormal = pline->normal();
|
||
XVector3D vtN(vtNormal[0], vtNormal[1], vtNormal[2]);
|
||
Groups gv(vtN), g0(0);
|
||
polyDest.TransUCS((const resbuf *)&gv, (const resbuf *)&g0);
|
||
|
||
ads_matrix mat;
|
||
AsAdsMatrix(*pMatTran, mat);
|
||
polyDest.TransUCS(mat);
|
||
|
||
int nSeg = polyDest.TotalSegments();
|
||
for (int iSeg = 0; iSeg<nSeg; iSeg++)
|
||
{
|
||
XCurveSegment ln;
|
||
polyDest.Nth(iSeg,ln);
|
||
AcDbCurve *pCurve = ln.AsAcDbCurve();
|
||
subProp.SetTo(pCurve);
|
||
entSet3dface.append(pCurve);
|
||
}
|
||
delete pline;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void XExport2::InitModel(const XMasterProperties &prop, const AcDbVoidPtrArray &entSet, AcGeMatrix3d *pMatTran, AcDbVoidPtrArray &entSet3dface)
|
||
{
|
||
int nCount = entSet.length();
|
||
for (int i = 0; i<nCount; i++)
|
||
{
|
||
AcDbEntity *pEntity = (AcDbEntity *)entSet[i];
|
||
XExport2::InitModel(prop, pEntity, pMatTran, entSet3dface);
|
||
}
|
||
}
|
||
|
||
int XExport2::SearchRegions(const DList<XCurveSegment> &lstSeg1In, DList<XPoly2D> &lstDest)
|
||
{
|
||
try
|
||
{
|
||
XSearchRegionFromCurve aSearch;
|
||
aSearch.InitStart(lstSeg1In);
|
||
if (aSearch.SearchRegions())
|
||
{
|
||
aSearch.RemoveDupRegions();
|
||
for (int n = 0; n<aSearch.m_regions.Length(); n++)
|
||
{
|
||
XPoly2D *pNewPoly = new XPoly2D(1);
|
||
if (aSearch.m_regions[n]->CenterPoly2D(*pNewPoly) == RTNORM)
|
||
{
|
||
lstDest.Append(pNewPoly);
|
||
}
|
||
else
|
||
{
|
||
delete pNewPoly;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
if (g_bEchoSearch)
|
||
{
|
||
XGeLib::adsout << /*UMSG*/_T("\n发生例外情况!");
|
||
}
|
||
return RTERROR;
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|