Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

4317 lines
107 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//-------------------------------------------------------------------------------------------------------+
// 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;
}