//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TGGePoly2D 类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TGGePoly2D 类定义 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "TGGePoly2D.h" #include "TADSGePointList.h" #include "dbregion.h" #include "TPushPrec.h" #include "TAcDbObjectPtr.h" #include "TGGePoly3D.h" //#include "TGGeDirectionCurve.h" #include "TList.h" #include "TGGePolygonEx.h" #include "TPointList.h" #include "TchGlobalFunc.h" #include "TchPrivateGlobalFunc.h" #include "TchGlobalCurveFunc.h" #include "geblok3d.h" #include "geblok2d.h" #include "TGGeCurveInline.h" TGGePoly2D::TGGePoly2D() : m_nFlag(0) { m_ardbulges.Reset(); } TGGePoly2D::TGGePoly2D(const TEntitySet& ent) { TEntitySet entPLine = ent; TCString sEntType; TADSGePoint3d pt; double dTAng = 0.0, dAng = 0.0; entPLine.GetData(0, (TCHAR *)sEntType); if (sEntType == _T("CIRCLE")) { TGGeCurveSegment cir(ent); cir.AsPoly2D(*this); return; } else if (sEntType == _T("LINE") || sEntType == _T("ARC")) { TGGeCurveSegment segTemp(ent); if (!segTemp) { return; } segTemp.AsPoly2D(*this); } if ((sEntType != _T("POLYLINE") && sEntType != _T("LWPOLYLINE")) || entPLine.GetData(70, &m_nFlag) != RTNORM) { return; } int nFlag = m_nFlag; if ((nFlag & 2) || (nFlag & 4) || (nFlag & 16) || (nFlag & 32) || (nFlag & 64)) { return; } if (sEntType == _T("POLYLINE")) { OPENOBJ_BEGIN(entPLine, AcDb::kForRead, AcDb3dPolyline, pLine); if (pLine != NULL) { AcDbObjectIterator* pIter = pLine->vertexIterator(); if (pIter != NULL) { for (pIter->start(); !pIter->done(); pIter->step()) { AcDb3dPolylineVertex *pVertex = NULL; acdbOpenObject(pVertex, pIter->objectId(), AcDb::kForRead); if (pVertex != NULL) { if (pVertex->vertexType() == AcDb::k3dSimpleVertex) { m_ardbulges.Append(new double(0.0)); Append(new TADSGePoint3d(pVertex->position())); } pVertex->close(); } } delete pIter; } return; } OPENOBJ_END(); TEntitySet subEnt = entPLine; while ( 1 ) { TEntitySet sub_ent; if (ads_entnext(subEnt, sub_ent) != RTNORM) { break; } subEnt = sub_ent; subEnt.FreeGroups(); if (!subEnt.Is(_T("VERTEX"))) { break; } subEnt.GetData(10, pt); subEnt.GetData(42, &dTAng); if (fabs(dTAng) < 1E-6) { m_ardbulges.Append(new double(0.0)); } else { dAng = atan(dTAng) * 4.0; m_ardbulges.Append(new double(dAng)); } Append(new TADSGePoint3d(pt)); } } else { double dElevation = 0.0; entPLine.GetData(38, &dElevation); resbuf *ebuf = (resbuf *)(entPLine.groups); if (!ebuf) { TchGeLib::adsout << _T("\nResbuf error"); } while(ebuf) { resbuf *rb1 = GetResbufAtCode(ebuf, 10); resbuf *rb2 = rb1 ? GetResbufAtCode(rb1, 42) : NULL; if (rb1 && rb2) { dTAng = rb2->resval.rreal; pt = rb1->resval.rpoint; if (fabs(dTAng) < 1E-6) { m_ardbulges.Append(new double(0.0)); } else { dAng = atan(dTAng) * 4.0; m_ardbulges.Append(new double(dAng)); } pt.z = dElevation; Append(new TADSGePoint3d(pt)); ebuf = rb2->rbnext; } else { break; } } } } TGGePoly2D::TGGePoly2D(int nflg) : m_nFlag(nflg) { m_ardbulges.Reset(); } TGGePoly2D::TGGePoly2D(const TGGePoly2D &src) { TADSGePointList::copyFrom(src); m_ardbulges.Reset(); m_ardbulges.copyFrom( src.m_ardbulges ); m_nFlag = src.GetFlag(); } TGGePoly2D::~TGGePoly2D() { } void TGGePoly2D::CopyFrom(const TGGeEntity* pSrc) { if (this != pSrc && pSrc->IsKindOf(TGGeEntity::ePoly2D)) { m_nFlag = ((TGGePoly2D*)pSrc)->m_nFlag; copyFrom(*((TGGePoly2D*)pSrc)); m_ardbulges.copyFrom(((TGGePoly2D*)pSrc)->m_ardbulges); } } int TGGePoly2D::operator !() const { return (Length() < 2 ? 1 : 0); } TGGePoly2D& TGGePoly2D::operator = (const TGGePoly2D &src) { if (this != &src) { Reset(); m_nFlag = src.m_nFlag; for(int i = 0; i < src.Length(); i++) { const TADSGePoint3d &pt = src[i]; double val = src.m_ardbulges[i]; Append(new TADSGePoint3d(pt)); m_ardbulges.Append(new ads_real(val)); } } return *this; } int TGGePoly2D::IsValid(int nIndex) const { int nLen = Length(); if (nIndex < 0 || nIndex >= nLen) { return 0; } if (!(m_nFlag & 1) && nIndex == nLen - 1) { return 0; } return 1; } int TGGePoly2D::IsClosed() const { return ((m_nFlag & 0x01) ? 1 : 0); } bool TGGePoly2D::SetClosed() { if (Length() > 2) { m_nFlag = 1; return true; } return false; } int TGGePoly2D::TotalSegments() const { int nLen = Length(); return (m_nFlag & 1) ? nLen : nLen - 1; } double TGGePoly2D::Area() const { return fabs(PathArea()); } double TGGePoly2D::GetLength()const { double dLength = 0.0; for (int i = 0; i < TotalSegments(); i++) { TGGeCurveSegment seg; Nth(i, seg); dLength += seg.GetLength(); } return dLength; } void TGGePoly2D::Reset() { TDPtrList::Reset(); m_ardbulges.Reset(); } resbuf* TGGePoly2D::Fence(int nCirDiv) { TGGePoly pts; if (MapToPolygon(pts, nCirDiv) == RTNORM) { return (IsClosed() ? pts.Fence() : pts.Polygon()); } return NULL; } resbuf* TGGePoly2D::Polygon(int nCirDiv) { TGGePoly pts; if (MapToPolygon(pts, nCirDiv) == RTNORM) { return pts.Polygon(); } return NULL; } void TGGePoly2D::AppendNode(const TADSGePoint3d &pt, ads_real dBulge, AcDb::Visibility eVal) { assert(Length() == m_ardbulges.Length()); Append(new TADSGePoint3d(pt)); m_ardbulges.Append(new double(dBulge)); } void TGGePoly2D::InsertNodeAt(int nIndex, const TADSGePoint3d &pt, double dBulge, AcDb::Visibility eVal) { if (nIndex >= Length()) { AppendNode(pt, dBulge); } else { (*this)[nIndex]; Insert(new TADSGePoint3d(pt)); m_ardbulges[nIndex]; m_ardbulges.Insert(new double(dBulge)); } } void TGGePoly2D::InsertNodeAt(const TADSGePoint3d &pt, AcDb::Visibility eVal) { } void TGGePoly2D::RemoveNode(long nIndex) { Remove(nIndex); m_ardbulges.Remove(nIndex); } void TGGePoly2D::TransformBy(const AcGeMatrix3d &mat) { //lfy 2010-08-31 修改 BOOL bIsMirror = IsMirrorMatrix(mat); for (int i = 0; i < Length(); i++) { TADSGePoint3d *pt = (*this)[i]; pt->TransformBy(mat); // lfy 2010-08-31 修改,减少循环 if (bIsMirror) { *m_ardbulges[i] = -*(m_ardbulges[i]); } } /* if (IsMirrorMatrix(mat)) { for (int m = 0; m < Length(); m++) { *m_ardbulges[m] = -*(m_ardbulges[m]); } }*/ } TADSGePoint3d TGGePoly2D::GetPoint(int nIOFlag, ads_real dDist) { TADSGePoint3d ptPick; TGGeCurveSegment curve; if (Nth(0, curve) != RTNORM) { return ptPick; } if (nIOFlag == 0) { ptPick = curve.Offset(PathArea() > 0 ? OFFSET_RIGHT : OFFSET_LEFT, dDist, LS_FINITE).MidPoint(); } else { ptPick = curve.Offset(PathArea() > 0 ? OFFSET_LEFT : OFFSET_RIGHT, dDist, LS_FINITE).MidPoint(); } return ptPick; } TADSGePoint3d TGGePoly2D::GetInsidePoint() { assert(Length()); TGGePoly polyTemp; MapToPolygon(polyTemp); TGGePolygonEx polyEx(polyTemp); TADSGePoint3d pt; if (polyEx.GetInsidePoint(pt, TRUE) == RTNORM) { return pt; } return GetPoint(0, 10 * _DIST_SNAP); } ads_real TGGePoly2D::Distance2d() const { int nLen = TotalSegments(); double dRes = 0.0; for (int i = 0; i < nLen; i++) { dRes += Distance2d(i); } return dRes; } ads_real TGGePoly2D::Distance2d(int nIndex) const { int nLen = Length(); if (nIndex < 0 || nIndex >= nLen) { return 0; } if (!(m_nFlag & 1) && nIndex == nLen - 1) { return 0; } TGGeCurveSegment seg; Nth(nIndex, seg); seg.SetElevation(0.0); return seg.GetLength(); } ads_real TGGePoly2D::Distance3d() const { int nLen = TotalSegments(); double dRes = 0.0; for (int i = 0; i < nLen; i++) { dRes += Distance3d(i); } return dRes; } ads_real TGGePoly2D::Distance3d(int nIndex) const { int nLen = Length(); if (nIndex < 0 || nIndex >= nLen) { return 0; } if (!(m_nFlag & 1) && nIndex == nLen - 1) { return 0; } TGGeCurveSegment seg; Nth(nIndex, seg); return seg.GetLength(); } int TGGePoly2D::HitTestOnCurve(const TADSGePoint3d &ptTest, double dTol) const { const TGGePoly2D &polyPath = *this; TADSGePoint3d pt2d = ptTest; for (int i = 0; i < polyPath.Length(); i++) { if (pt2d.Distance2d(polyPath[i]) < dTol) { return (i + 1); } } TPushPrec vTemp(dTol, _angSnap); int nEdgeNum = polyPath.TotalSegments(); for (i = 0; i < nEdgeNum; i++) { TGGeCurveSegment seg; polyPath.Nth(i, seg); seg.SetElevation(0.0); if ((pt2d & seg) == PR_INSIDE) { return (-i - 1); } } return 0; } inline int TGGePoly2D::Nth(int nIndex, TGGeCurveSegment &curve, AcDb::Visibility *pVal) const { if (!IsValid(nIndex)) { return RTERROR; } static TGGeLine ln; static TGGeArc arc; int nflg = Nth(nIndex, ln, arc); int nFlag = curve.m_nFlag; int nRet = RTNORM; switch(nflg) { case LINE_SEGMENT: //curve = ln; curve.m_startPoint = ln.m_startPoint; curve.m_endPoint = ln.m_endPoint; curve.m_dBulge = 0.0; break; case ARC_SEGMENT: curve = arc; break; default: nRet = RTERROR; } curve.m_nFlag = nFlag; return nRet; } inline int TGGePoly2D::Nth(int nIndex, TGGeLine &xline, TGGeArc &xarc, AcDb::Visibility *pVal) const { if (!IsValid(nIndex)) { return RTERROR; } int nLen = Length(); TADSGePoint3d p1 = (*this)[nIndex]; TADSGePoint3d p2; if (nIndex == nLen - 1) { p2 = (*this)[0]; } else { p2 = (*this)[nIndex + 1]; } double dAng = m_ardbulges[nIndex]; if (fabs(dAng) > 1.0E-6) { xarc.Set(p1,p2,dAng); return ARC_SEGMENT; } else { //xline.SetPoints(p1, p2); xline.m_startPoint = p1; xline.m_endPoint = p2; return LINE_SEGMENT; } } inline int TGGePoly2D::Nth(int nIndex, TGGeDirectionCurve &curve, AcDb::Visibility *pVal) const { if (!IsValid(nIndex)) { return RTERROR; } int nLen = Length(); TADSGePoint3d p1 = (*this)[nIndex], p2; if (nIndex == nLen - 1) { p2 = (*this)[0]; } else { p2 = (*this)[nIndex + 1]; } double dAng = m_ardbulges[nIndex]; curve.m_startPoint = p1; curve.m_endPoint = p2; curve.m_dBulge = dAng; return RTNORM; } int TGGePoly2D::Make(const TCHAR *szlay) const { int nLen = Length(); if (nLen <= 1) { return RTERROR; } // LWPLINE AcDbPolyline *pLwPoly = new AcDbPolyline(nLen); for (int i = 0; i < nLen; i++) { double dBuge = tan(m_ardbulges[i] / 4.0); pLwPoly->addVertexAt(i, (*this)[i].AsAcGePoint2d(), dBuge); } if (szlay) { AssureLayer(szlay, LAYSTAT_UNLOCK); pLwPoly->setLayer(szlay); } pLwPoly->setClosed(m_nFlag ? Adesk::kTrue : Adesk::kFalse); double dThickness = 0.0; TGGetVar(_T("THICKNESS"), &dThickness); pLwPoly->setThickness(dThickness); pLwPoly->setElevation((*this)[0].z); AddToModelSpace(pLwPoly, Adesk::kTrue); return RTNORM; } int TGGePoly2D::MakeSegments(const TCHAR *szlay) const { int nLen = Length(); for (int i = 0; i < nLen; i++) { MakeSegment(i, szlay); } return RTNORM; } int TGGePoly2D::MakeSegment(int nIndex, const TCHAR *szlay) const { TGGeLine line; TGGeArc arc; int nrc = Nth(nIndex, line, arc); if (nrc == LINE_SEGMENT) { line.Make(szlay); } else if (nrc == ARC_SEGMENT) { arc.Make(szlay); } return RTNORM; } // dDrt--ptRes所在的切向 // 按2d距离求点和方向,注意返回的点是3d int TGGePoly2D::Polar2d(ads_real dis, TADSGePoint3d &ptRes, ads_real *dDrt) const { //lfy 2010-08-31 修改存取方式 int nLen = TotalSegments(), iNext = 0; double dSum = 0.0, dAng = 0.0, dsita = 0.0; TADSGePoint3d p1, p2, pt1, pt2; for (int i = 0; i < nLen; i++) { dSum += Distance2d(i); if (dSum > dis - _DIST_SNAP) { p1 = (*this)[i]; iNext = i + 1; if (iNext >= Length()) { iNext = 0; } p2 = (*this)[iNext]; dAng = m_ardbulges[i]; if (fabs(dAng) > 1E-6) { TGGeArc xarc(p1, p2, dAng); dsita = (dSum - dis) / xarc.m_dRadius; if (dAng > 0) { ads_polar(xarc.m_ptCenter, xarc.m_dendAngle - dsita, xarc.m_dRadius, ptRes); if (dDrt) { *dDrt = AngleRangeTo2PI(xarc.m_dendAngle - dsita + PI / 2.0); } } else { ads_polar(xarc.m_ptCenter, xarc.m_dstartAngle + dsita, xarc.m_dRadius, ptRes); if (dDrt) { *dDrt = AngleRangeTo2PI(xarc.m_dstartAngle + dsita - PI / 2.0); } } } else { ads_polar(p2, ads_angle(p2, p1), dSum - dis, ptRes); pt1 = p1; pt2 = p2; pt2.z = pt1.z; ptRes.z += (p1.z - p2.z) / ads_distance(pt2, pt1) * (dSum - dis); if (dDrt) { *dDrt = ads_angle(pt1, pt2); } } return i; } } return RTERROR; } int TGGePoly2D::Polar3d(ads_real dis, TADSGePoint3d &ptRes, TVector3D &vt) const { //lfy 2010-08-31 修改存取方式 int nLen = TotalSegments(), iNext = 0; double dSum = 0.0, dAng = 0.0, dsita = 0.0; TADSGePoint3d p1, p2, pt1, pt2; double dDrt = 0.0; for (int i = 0; i < nLen; i++) { dSum += Distance3d(i); if (dSum > dis - _DIST_SNAP) { p1 = (*this)[i]; iNext = i + 1; if (iNext >= Length()) { iNext = 0; } p2 = (*this)[iNext]; dAng = m_ardbulges[i]; if (fabs(dAng) > 1E-6) { TGGeArc xarc(p1, p2, dAng); dsita = (dSum - dis) / xarc.m_dRadius; if (dAng > 0) { ads_polar(xarc.m_ptCenter, xarc.m_dendAngle - dsita, xarc.m_dRadius, ptRes); dDrt = AngleRangeTo2PI(xarc.m_dendAngle - dsita + PI / 2.0); } else { ads_polar(xarc.m_ptCenter, xarc.m_dstartAngle + dsita, xarc.m_dRadius, ptRes); dDrt = AngleRangeTo2PI(xarc.m_dstartAngle + dsita - PI / 2.0); } vt.x = cos(dDrt); vt.y = sin(dDrt); vt.z = 0; } else { vt = p2 - p1; TVector3D vtNormal = vt; ((AcGeVector3d &)vtNormal).normalize(); vt = vtNormal; vtNormal *= dis - dSum; ptRes = p2 + vtNormal; } return i; } } return RTERROR; } ads_real TGGePoly2D::PathArea() const { int i = 0; int nflg; TGGeArc arc; TGGeLine line; double dresult = 0.0; while ((nflg = Nth(i, line, arc)) != RTERROR) { if (nflg == LINE_SEGMENT) { dresult += line.PathArea(); } else if (m_ardbulges[i] > 0) { dresult += arc.PathArea(); } else { dresult -= arc.PathArea(); } i++; } return dresult; } int TGGePoly2D::MapToPolygon(TGGePoly &pts, int nCirDiv) { //lfy 2010-08-31 修改存取方式 pts.Reset(); int nLen = Length(); int i = 0, n = 0, nNum = 0, nRetFlag = 0; TADSGePoint3d pt; double dincrement = 0.0; for (i = 0; i < nLen; i++) { if (fabs(*m_ardbulges[i]) < 1E-6) { pts.Append(new TADSGePoint3d(*(*this)[i])); } else if (i < nLen - 1 || IsClosed()) { TGGeArc arc; TGGeLine ll; nRetFlag = Nth(i, ll, arc); ASSERT(nRetFlag == ARC_SEGMENT); //圆用30边做成 nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv); nNum = max(nNum, 1); dincrement = arc.Bulge() / nNum; for (n = 0; n < nNum; n++) { if (*m_ardbulges[i] > 0) { ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt); } else { ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt); } pts.Append(new TADSGePoint3d(pt)); } } } return RTNORM; } void TGGePoly2D::Disperse(TGGePoly2D &polyBase1, int nCirDivSeg) const { TGGePoly polyBase; AsOpenPoly(polyBase, nCirDivSeg); int nCount = polyBase.Length(); if (IsClosed()) { nCount--; } for (int n = 0; n < nCount; n++) { polyBase1.AppendNode(*polyBase[n]); } polyBase1.SetFlag(m_nFlag); } int TGGePoly2D::AsOpenPoly(TGGePoly &pts, int nCirDiv) const { //lfy 2010-08-31 修改存取方式 pts.Reset(); int nLen = Length(); const TGGePoly2D &poly = *this; int i = 0, n = 0, nNum = 0, nRetFlag = 0; TADSGePoint3d pt; double dincrement = 0.0; TGGeArc arc; TGGeLine ll; for ( i = 0; i < nLen; i++) { if (fabs(m_ardbulges[i]) < 1E-6) { pts.Append(new TADSGePoint3d(poly[i])); if (i == nLen - 1 && IsClosed()) { //最后一点为起点 pts.Append(new TADSGePoint3d(poly[0])); } } else { //Arc if (!IsClosed() && i == nLen - 1) { //不封闭的最后一点 pts.Append(new TADSGePoint3d(poly[i])); return RTNORM; } nRetFlag = Nth(i, ll, arc); ASSERT(nRetFlag == ARC_SEGMENT); nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv); nNum = max(nNum, 1); dincrement = arc.Bulge() / nNum; if (i == nLen-1 && IsClosed()) { //最后一封闭弧段 nNum += 1; } for (n = 0; n < nNum; n++) { if (m_ardbulges[i] > 0) { ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt); } else { ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt); } pts.Append(new TADSGePoint3d(pt)); } } } return RTNORM; } int TGGePoly2D::MapToPolygon1(TGGePoly &pts, double dDeviation) { //lfy 2010-08-31 修改存取方式 pts.Reset(); int nLen = Length(); int i = 0, n = 0, nNum = 0, nRetFlag = 0, nCirDiv = 0; TADSGePoint3d pt; double dincrement = 0.0; TGGeArc arc; TADSGePoint3d* pPtScr = NULL; TGGeLine ll; for (i = 0; i < nLen; i++) { if (fabs(*m_ardbulges[i]) < 1E-6) { pPtScr = new TADSGePoint3d(*(*this)[i]); pts.Append(pPtScr); } else if (i < nLen - 1 || IsClosed()) { //不到最后一点或闭合的最后一段 nRetFlag = Nth(i, ll, arc); ASSERT(nRetFlag == ARC_SEGMENT); if (arc.GetLength() < _DIST_SNAP) { continue; } nCirDiv = GetCirDivNum(arc.m_dRadius, dDeviation); nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv); nNum = max(nNum, 1); dincrement = arc.Bulge() / nNum; for (n = 0; n < nNum; n++) { if (*m_ardbulges[i] > 0) { ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt); } else { ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt); } pts.Append(new TADSGePoint3d(pt)); } } } return RTNORM; } void TGGePoly2D::Disperse1(TGGePoly2D &polyBase1, double dDeviation) const { TGGePoly polyBase; AsOpenPoly1(polyBase, dDeviation); int nCount = polyBase.Length(); if (IsClosed()) { nCount--; } for (int n = 0; n 0) { ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt); } else { ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt); } pts.Append(new TADSGePoint3d(pt)); } } } return RTNORM; } double TGGePoly2D::PathDistance2d(TADSGePoint3d ptHit) const { double nRet = 0.0; int nHitLeft = HitTestOnCurve(ptHit); if (nHitLeft < 0) { int iLeft = abs(nHitLeft) - 1; TGGeDirectionCurve leftHitCurve; Nth(iLeft, leftHitCurve); nRet = leftHitCurve.PathDistance(ptHit); for (int k = 0; k < iLeft; k++) { Nth(k, leftHitCurve); nRet += leftHitCurve.GetLength(); } } // add by xlc on 110415 ptHit在顶点时计算路径长度 else if (nHitLeft > 0) { for (int k = 0; k < nHitLeft - 1; k++) { TGGeDirectionCurve leftHitCurve; Nth(k, leftHitCurve); nRet += leftHitCurve.GetLength(); } } return nRet; } int TGGePoly2D::CreatePface(int nCirDiv, const TCHAR *pszLay) { TGGePoly pts; MapToPolygon(pts, nCirDiv); return pts.CreatePface(pszLay); } int TGGePoly2D::GetExtend(ads_point lowPt, ads_point upPt) const { int nNum = TotalSegments(); if (!nNum) { return RTERROR; } TGGeCurveSegment seg; TADSGePoint3d ptlow, ptup; ptlow = ptup = ((*this)[0]); for (int n = 0; n < nNum; n++) { if (Nth(n, seg) != RTNORM) { continue; } TADSGePoint3d pt1, pt2; seg.GetExtend(pt1, pt2); ptlow = Min(ptlow, pt1); ptup = Max(ptup, pt2); } ptlow > lowPt; ptup > upPt; return RTNORM; } // 没有判断边重合的情况 BOOL TGGePoly2D::IsSelfIntersect() const { const TGGePoly2D &polyOutline = *this; int nLen = polyOutline.Length(); TGGeArc arc; for (int i = 0; i < nLen - 2; i++) { TGGeLine ln0(LS_FINITE); polyOutline.Nth(i, ln0, arc); if (ln0.GetLength() < _DIST_SNAP) { continue; } for (int j = i + 2; j < ((i == 0 && m_nFlag == 1) ? (nLen - 1) : nLen); j++) { TGGeLine ln1(LS_FINITE); polyOutline.Nth(j, ln1, arc); if (ln1.GetLength() < _DIST_SNAP) { continue; } TADSGePoint3d ptInt; if (ln0.Intersection(&ln1, ptInt)) { return TRUE; } } } return FALSE; } int TGGePoly2D::AppendSegment(const TGGeCurveSegment &curve, int bMinus, int bFinal) { if (bMinus) { Append(new TADSGePoint3d(curve.GetEndPoint())); m_ardbulges.Append(new double(-curve.GetBulge())); if (bFinal && !(m_nFlag & 0x01)) { Append(new TADSGePoint3d(curve.GetStartPoint())); m_ardbulges.Append(new double(0.0)); } } else { Append(new TADSGePoint3d(curve.GetStartPoint())); m_ardbulges.Append(new double(curve.GetBulge())); if (bFinal && !(m_nFlag & 0x01)) { Append(new TADSGePoint3d(curve.GetEndPoint())); m_ardbulges.Append(new double(0.0)); } } return RTNORM; } int TGGePoly2D::Compress(bool bUnionCurve) { if (Length() < 1) { return RTERROR; } const TGGePoly2D &poly = *this; TList ptList; TList anList; ptList.AddTail(poly[0]); for (long i = 1; i < Length(); i++) { if (ptList.GetCurData() != poly[i]) { ptList.AddTail(poly[i]); anList.AddTail(*(m_ardbulges[i - 1])); } } anList.AddTail(*(m_ardbulges[i - 1])); if (IsClosed()) { if (ptList.GetLength() > 1 && poly[0] == ptList.GetCurData()) { ptList.DelCur(); anList.DelCur(); } } if (ptList.GetLength() < Length()) { Reset(); m_ardbulges.Reset(); for (ptList.MoveToFirst(), anList.MoveToFirst(); !ptList.IsOut(); ptList.MoveToNext(), anList.MoveToNext()) { AppendNode(ptList.GetCurData(), anList.GetCurData()); } } if (!bUnionCurve) { return RTNORM; } TGGePoly2D destPoly(m_nFlag); int nTotalSeg = TotalSegments(); TGGeCurveSegment curve; int bMinusCurve = 0, bMinusSeg = 0, bMerged = 0; for (int n = 0; n < nTotalSeg; n++) { TGGeCurveSegment seg; Nth(n, seg); if (!seg) { continue; } bMinusSeg = (*m_ardbulges[n] < -1.0E-8); bMerged = 0; if (!curve) { curve = seg; bMinusCurve = bMinusSeg; continue; } else { bMerged = MergeCurve(curve, seg, bMinusCurve, bMinusSeg); } if (!bMerged) { destPoly.AppendSegment(curve, bMinusCurve); curve = seg; bMinusCurve = bMinusSeg; } } if (!curve) { return RTERROR; } else { destPoly.AppendSegment(curve, bMinusCurve, 1); } if ((destPoly.GetFlag() & 0x01) && destPoly.TotalSegments() >= 2) { int nTotalDest = destPoly.TotalSegments(); int bMinusFirst = (destPoly.GetBulge(0) < -1.0E-8); int bMinusFinal = (destPoly.GetBulge(nTotalDest - 1) < -1.0E-8); TGGeCurveSegment curveFirst, curveFinal; destPoly.Nth(0, curveFirst); destPoly.Nth(nTotalDest - 1, curveFinal); if (MergeCurve(curveFinal, curveFirst, bMinusFinal, bMinusFirst)) { if (bMinusFinal) { destPoly.SetBulge(0,-curveFinal.GetBulge()); destPoly.SetPointListAt(0, curveFinal.EndPoint()); } else { destPoly.SetBulge(0, curveFinal.GetBulge()); destPoly.SetPointListAt(0, curveFinal.StartPoint()); } destPoly.RemoveBugle(nTotalDest - 1); destPoly.RemovePointListAt(nTotalDest - 1); } } *this = destPoly; return RTNORM; } int TGGePoly2D::Reverse() { if (Length() < 2) { return RTERROR; } TGGePoly2D destPoly; int nTotalSeg = TotalSegments(); TGGeDirectionCurve cv; for (int i = nTotalSeg - 1; i >= 0; i--) { Nth(i, cv); destPoly.AppendNode(cv.EndPoint(), -cv.GetBulge()); } if (!(m_nFlag & 0x01)) { destPoly.AppendNode(*((*this)[0]), -(*m_ardbulges[nTotalSeg])); } destPoly.SetFlag(m_nFlag); *this = destPoly; return RTNORM; } int TGGePoly2D::Offset(ads_real dDist, TGGePoly2D &destPoly) const { int nTotalSeg = TotalSegments(); if (!nTotalSeg) { return RTERROR; } if (fabs(dDist) < _DIST_SNAP) { destPoly = *this; return RTNORM; } destPoly.Reset(); destPoly.SetFlag(m_nFlag); TGGeDirectionCurve finalMidSeg, lastSeg; if (m_nFlag & 0x01) { Nth(nTotalSeg - 1, finalMidSeg); lastSeg = finalMidSeg.Offset(dDist, LS_INFINITE); if (!lastSeg) { return RTERROR; } } TADSGePoint3d nextPt,pt1, pt2, curPt; TGGeDirectionCurve curMidSeg, curSeg, nextMidSeg, nextSeg; int nNum = 0, nextIndex = 0; TGGeArc arc; for (int i = 0; i < nTotalSeg; i++) { Nth(i, curMidSeg); curSeg = curMidSeg.Offset(dDist, LS_INFINITE); if (!curSeg) { return RTERROR; } if (!i) { // 求当前点 if (!lastSeg) { curPt = curSeg.GetStartPoint(); } else { nNum = curSeg.Intersection(lastSeg, pt1, pt2); if (nNum == 2) { curPt = TGGeLine(pt1, pt2).NearPoint(curSeg.GetStartPoint()); } else if (nNum == 1) { curPt = pt1; } else { if (IsSameDrt(curSeg.IDirection(0), lastSeg.IDirection(1), _angSnap)) { //同方向, 两段连接. curPt = curSeg.GetStartPoint(); } else { return RTERROR; } } } } else { curPt = nextPt; } // 求下一个端点 if (i == nTotalSeg - 1 && !(m_nFlag & 0x01)) { //不封闭的最后一段 nextPt = curSeg.GetEndPoint(); } else { //为最后时下一段为起始 nextIndex = i >= nTotalSeg - 1 ? 0 : i + 1; Nth(nextIndex, nextMidSeg); nextSeg = nextMidSeg.Offset(dDist, LS_INFINITE); if (!nextSeg) { return RTERROR; } nNum = curSeg.Intersection(nextSeg, pt1, pt2); if (nNum == 2) { nextPt = TGGeLine(pt1, pt2).NearPoint(curSeg.GetEndPoint()); } else if (nNum == 1) { nextPt = pt1; } else { if (IsSameDrt(curSeg.IDirection(1), nextSeg.IDirection(0), _angSnap)) { nextPt = curSeg.GetEndPoint(); } else { return RTERROR; } } } lastSeg = curSeg; if (curSeg.Is(CURVE_ARC)) { arc = curSeg.GetArc(); if (!curSeg.IsMinusArc()) { //逆时针 arc.SetStarAngle(ads_angle(arc.GetCenterPt(), curPt)); arc.SetEndAngle(ads_angle(arc.GetCenterPt(), nextPt)); curSeg.SetBulge(arc.Bulge()); } else { arc.SetStarAngle(ads_angle(arc.GetCenterPt(), nextPt)); arc.SetEndAngle(ads_angle(arc.GetCenterPt(), curPt)); curSeg.SetBulge(-arc.Bulge()); } curSeg.SetStartPoint(curPt); curSeg.SetEndPoint(nextPt); } assert(!curSeg.Is(CURVE_CIRCLE)); //加一段 destPoly.Append(new TADSGePoint3d(curPt)); destPoly.m_ardbulges.Append(new double(curSeg.GetBulge())); if (i == nTotalSeg - 1 && !(m_nFlag & 0x01)) { destPoly.Append(new TADSGePoint3d(nextPt)); destPoly.m_ardbulges.Append(new double(0.0)); } } return RTNORM; } int TGGePoly2D::HasArcSegment() const { for (int i = 0; i < TotalSegments(); i++) { if (fabs(m_ardbulges[i]) > 1.0E-6) { return 1; } } return 0; } int TGGePoly2D::QuickOffset(ads_real dDist, TGGePoly2D &destPoly) const { const TGGePoly2D &basePoly = *this; destPoly.Reset(); destPoly.m_nFlag = m_nFlag; int nVertexNum = basePoly.Length(); TGGeDirectionCurve prevEdge; int bIsClosed = ((basePoly.m_nFlag & 0x01) != 0); if (bIsClosed) { basePoly.Nth(nVertexNum - 1, prevEdge); } TADSGePoint3d newVertex; for (int j = 0; j < nVertexNum; j++) { TGGeDirectionCurve curEdge; double dFromDirection, dToDirection; if (j == nVertexNum - 1) { dToDirection = AngleRangeTo2PI(prevEdge.IDirection(1) - PI); dFromDirection = prevEdge.IDirection(1); if (bIsClosed) { basePoly.Nth(nVertexNum - 1, curEdge); dFromDirection = AngleRangeTo2PI(curEdge.IDirection(0) - PI); } } else { basePoly.Nth(j, curEdge); dFromDirection = AngleRangeTo2PI(curEdge.IDirection(0) - PI); dToDirection = curEdge.IDirection(0); if (j > 0 || bIsClosed) { dToDirection = AngleRangeTo2PI(prevEdge.IDirection(1) - PI); } } double dDirection = TGGeSector(dFromDirection, dToDirection).MidAngle(); const TADSGePoint3d &thisVertex = basePoly[j]; double dSinAng = fabs(sin(AngleRangeTo2PI(dDirection - dFromDirection))); if (fabs(dSinAng) < 1E-6) { return RTERROR; } else { ads_polar(thisVertex, dDirection, dDist / dSinAng, newVertex); } destPoly.AppendNode(newVertex, m_ardbulges[j]); prevEdge = curEdge; } TADSGePoint3d ptMid; double dAbsBulge; assert(TotalSegments() == destPoly.TotalSegments()); for (int i = 0; i < TotalSegments(); i++) { TGGeDirectionCurve cvSrc, cvDest, dv; Nth(i, cvSrc); destPoly.Nth(i, cvDest); if (fabs(cvSrc.GetBulge()) > 1.0E-5) { TGGeDirectionCurve dv = cvSrc.Offset(dDist, LS_FINITE); if (!dv) { return RTERROR; } dv.GetArc().MidPoint(ptMid); TGGeArc ar(cvDest.GetStartPoint(), ptMid, cvDest.GetEndPoint()); dAbsBulge = ar.Bulge(); if (dAbsBulge < 1.0E-5) { return RTERROR; } *destPoly.m_ardbulges[i] = (cvSrc.GetBulge() > 0) ? dAbsBulge : -dAbsBulge; } } return RTNORM; } AcDbRegion* TGGePoly2D::AsRegion() const { const TGGePoly2D &poly = *this; if (!poly.IsClosed()) { return NULL; } AcDbPolyline pline; PolyConvert(poly, pline); AcDbVoidPtrArray curveSegments; curveSegments.append(&pline); AcDbVoidPtrArray regions; if (AcDbRegion::createFromCurves(curveSegments, regions) == Acad::eOk && regions.length() > 0) { AcDbRegion *regioni = (AcDbRegion *)regions[0]; regions.removeAt(0); ReleaseEntSet(regions); return regioni; } //如果整个pline创建region,不成功的时候,再炸开 AcDbVoidPtrArray explodeSegments; pline.explode(explodeSegments); AcDbVoidPtrArray regions2; if (AcDbRegion::createFromCurves(curveSegments, regions2) == Acad::eOk && regions2.length() > 0) { AcDbRegion *regioni = (AcDbRegion *)regions2[0]; regions2.removeAt(0); ReleaseEntSet(regions2); return regioni; } ReleaseEntSet(explodeSegments); return NULL; } bool TGGePoly2D::IsRegionInclude(const TGGePoly2D& poly) const { TGGePoly2D poly1, poly2; poly1 = *this; poly2 = poly; poly1.SetElevation(0.0); poly2.SetElevation(0.0); AcDbRegion *pRegion1 = poly1.AsRegion(); AcDbRegion *pRegion2 = poly2.AsRegion(); double area0; double area1; if (pRegion1 != NULL && pRegion2 != NULL) { pRegion1->getArea(area0); if (pRegion1->booleanOper(AcDb::kBoolUnite,pRegion2) == Acad::eOk) { pRegion1->getArea(area1); if (fabs(area1 - area0) < 1E-6) { delete pRegion1; delete pRegion2; return true; } } } if (pRegion1 != NULL) { delete pRegion1; } if (pRegion2 != NULL) { delete pRegion2; } return false; } bool TGGePoly2D::IsRegionOverlap(const TGGePoly2D& poly) const { TGGePoly2D poly1, poly2; poly1 = *this; poly2 = poly; poly1.SetElevation(0.0); poly2.SetElevation(0.0); AcDbRegion *pRegion1 = poly1.AsRegion(); AcDbRegion *pRegion2 = poly2.AsRegion(); double area; if (pRegion1 != NULL && pRegion2 != NULL) { if (pRegion1->booleanOper(AcDb::kBoolIntersect, pRegion2) == Acad::eOk) { pRegion1->getArea(area); if (area > 1E-6) { delete pRegion1; delete pRegion2; return true; } } } if (pRegion1 != NULL) { delete pRegion1; } if (pRegion2 != NULL) { delete pRegion2; } return false; } AcDbCurve* TGGePoly2D::AsAcDbCurve() const { AcDbPolyline* pLwPoly = new AcDbPolyline(Length()); double dBuge = 0.0; for (int i = 0; i < Length(); i++) { dBuge = tan(m_ardbulges[i] / 4.0); pLwPoly->addVertexAt(i, ((*this)[i]).AsAcGePoint2d(), dBuge); } if (Length() >0) { pLwPoly->setElevation((*this)[0].z); } pLwPoly->setClosed(IsClosed() ? Adesk::kTrue : Adesk::kFalse); return pLwPoly; } bool TGGePoly2D::SetAcDbCurve(AcDbCurve*pCurve) { AcDbPolyline* pLwPoly = AcDbPolyline::cast(pCurve); if (pLwPoly == NULL) { return false; } Reset(); double dElev = pLwPoly->elevation(); AcGePoint2d pt; double dBulge = 0.0; for (long i = 0; i < (long)pLwPoly->numVerts(); i++) { pLwPoly->getPointAt(i, pt); pLwPoly->getBulgeAt(i, dBulge); dBulge = atan(dBulge) * 4; AppendNode(TADSGePoint3d(pt.x, pt.y, dElev), dBulge); } if (pLwPoly->isClosed()) { m_nFlag = 1; } else { m_nFlag = 0; } return true; } void TGGePoly2D::SetFlag(int nFlag) { m_nFlag = nFlag; } int TGGePoly2D::GetFlag() const { return m_nFlag; } void TGGePoly2D::RemoveBugle(int nIndex) { m_ardbulges.Remove(nIndex); } void TGGePoly2D::AppendBugle(ads_real dBugle) { m_ardbulges.Append( new double(dBugle)); } double TGGePoly2D::GetBulge(int nIndex) const { return m_ardbulges[nIndex]; } void TGGePoly2D::SetBulge(int nIndex, double dBugle) { *m_ardbulges[nIndex] = dBugle; } void TGGePoly2D::SetPointListAt(int nIndex, const TADSGePoint3d& pt) { if (Length() > nIndex) { *((*this)[nIndex]) = pt; } } void TGGePoly2D::RemovePointListAt(int nIndex) { if (Length() > nIndex) { Remove(nIndex); } } void TGGePoly2D::AppendPointListAt(TADSGePoint3d* pPt) { Append(pPt); } TADSGePoint3d* TGGePoly2D::GetPointListAt(int nIndex) { return (*this)[nIndex]; } const TADSGePoint3d& TGGePoly2D::GetPointListAt(int nIndex) const { return (*this)[nIndex]; } TGGePoly3D TGGePoly2D::PlaneToWcs(const AcGeVector3d& normal)const { TGGePoly3D poly3d = *this; AcGeMatrix3d mat; mat.setToPlaneToWorld(normal); poly3d.TransformBy(mat); return poly3d; } int TGGePoly2D::SetBulges(const TDPtrList& ardbulges) { if (ardbulges.Length() > 0) { m_ardbulges.Reset(); m_ardbulges.copyFrom(ardbulges); return m_ardbulges.Length(); } return -1; } int TGGePoly2D::GetBulges(TDPtrList& ardbulges) { if (m_ardbulges.Length() > 0) { ardbulges.copyFrom(m_ardbulges); return ardbulges.Length(); } return -1; } TDPtrList& TGGePoly2D::GetBulges() { return m_ardbulges; } bool TGGePoly2D::IsKindOf(TGGeEntity::TEntityId entType) const { switch(entType) { case TGGeEntity::eEntity: case TGGeEntity::eCurve: case TGGeEntity::ePoly2D: return true; } return false; } TGGeEntity::TEntityId TGGePoly2D::Type() const { return TGGeEntity::ePoly2D; }