888 lines
19 KiB
C++
888 lines
19 KiB
C++
//------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2011, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TGGeVisibilityPoly2D类
|
|
// = Version : ver1.0
|
|
// = Author : cet
|
|
// = CreateDate : 2011-04-13
|
|
// = Description: 具有可见性属性的poly2d类实现
|
|
// = Maintainers:
|
|
//
|
|
//------------------------------------------------------------------------+
|
|
|
|
#include "stdafx.h"
|
|
#include "TGGeVisibilityPoly2D.h"
|
|
#include "TchGlobalDef.h"
|
|
|
|
namespace
|
|
{
|
|
bool IsOnSameLine(const AcGePoint3d &pt1, const AcGePoint3d &pt2, const AcGePoint3d &pt3)
|
|
{
|
|
AcGeVector3d vt1 = pt2 - pt1, vt2 = pt3 - pt2;
|
|
return (vt1.isParallelTo(vt2) == Adesk::kTrue ? true : false);
|
|
}
|
|
|
|
// 求三点构成的弧的角度(pt2为弧中一点, pt1, pt3 为端点)
|
|
double GetAngleBy3Pt(const TADSGePoint3d &pt1, const TADSGePoint3d &pt2, const TADSGePoint3d &pt3)
|
|
{
|
|
AcGeVector3d vt1 = pt1 - pt2;
|
|
AcGeVector3d vt2 = pt3 - pt2;
|
|
double dAngle = vt1.angleTo(vt2); // 夹角
|
|
dAngle = (PI - dAngle) * 2; // 根据圆内接四边形对角互补,并且四边形任意一角是其对应圆心角的一半
|
|
return dAngle;
|
|
}
|
|
}
|
|
|
|
TGGeVisibilityPoly2D::TGGeVisibilityPoly2D()
|
|
{
|
|
m_arnVisibility.Reset();
|
|
}
|
|
|
|
TGGeVisibilityPoly2D::TGGeVisibilityPoly2D( const TGGeVisibilityPoly2D & src )
|
|
{
|
|
TADSGePointList::copyFrom(src);
|
|
m_ardbulges.Reset();
|
|
m_ardbulges.copyFrom( src.m_ardbulges );
|
|
m_arnVisibility.Reset();
|
|
m_arnVisibility.copyFrom(src.m_arnVisibility);
|
|
m_nFlag = src.GetFlag();
|
|
}
|
|
|
|
TGGeVisibilityPoly2D::~TGGeVisibilityPoly2D()
|
|
{
|
|
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::Reset()
|
|
{
|
|
TGGePoly2D::Reset();
|
|
m_arnVisibility.Reset();
|
|
}
|
|
|
|
bool TGGeVisibilityPoly2D::SetAcDbCurve( AcDbCurve* pCurve )
|
|
{
|
|
AcDbPolyline* pLwPoly = AcDbPolyline::cast(pCurve);
|
|
if (pLwPoly == NULL )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Reset(); // 清空数据
|
|
|
|
double dElev = pLwPoly->elevation(); // 标高
|
|
AcDb::Visibility visible = pLwPoly->visibility(); // 可见性
|
|
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; // 角度,直线时为0,弧线时为弧的角度
|
|
AppendNode(TADSGePoint3d(pt.x, pt.y, dElev), dBulge, visible);
|
|
}
|
|
|
|
if (pLwPoly->isClosed())
|
|
{
|
|
m_nFlag = 1;
|
|
}
|
|
else
|
|
{
|
|
m_nFlag = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::Nth( int nIndex, TGGeLine &xline, TGGeArc &xarc, AcDb::Visibility *pVal /*= NULL*/ ) const
|
|
{
|
|
if (!IsValid(nIndex)) // 判断索引是否有效
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
int nLen = Length();
|
|
TADSGePoint3d p1 = (*this)[nIndex]; // 索引nIndex所对应线段的第一个点
|
|
TADSGePoint3d p2;
|
|
if (nIndex == nLen - 1) // 第二个点
|
|
{
|
|
p2 = (*this)[0];
|
|
}
|
|
else
|
|
{
|
|
p2 = (*this)[nIndex + 1];
|
|
}
|
|
|
|
// 线段的可见性
|
|
if (pVal != NULL)
|
|
{
|
|
AcDb::Visibility val = m_arnVisibility[nIndex];
|
|
*pVal = val;
|
|
}
|
|
|
|
double dAng = m_ardbulges[nIndex];
|
|
if (fabs(dAng) > 1.0E-6) // 线段为弧线
|
|
{
|
|
xarc.Set(p1,p2,dAng);
|
|
return ARC_SEGMENT;
|
|
}
|
|
else // 线段为直线
|
|
{
|
|
xline.m_startPoint = p1;
|
|
xline.m_endPoint = p2;
|
|
return LINE_SEGMENT;
|
|
}
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::Nth( int nIndex, TGGeCurveSegment & cvCurve, AcDb::Visibility *pVal /*= NULL*/ ) const
|
|
{
|
|
if (!IsValid(nIndex))
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
static TGGeLine ln;
|
|
static TGGeArc arc;
|
|
int nflg = Nth(nIndex, ln, arc,pVal);
|
|
int nFlag = cvCurve.m_nFlag;
|
|
int nRet = RTNORM;
|
|
|
|
switch(nflg)
|
|
{
|
|
case LINE_SEGMENT:
|
|
cvCurve.m_startPoint = ln.m_startPoint;
|
|
cvCurve.m_endPoint = ln.m_endPoint;
|
|
cvCurve.m_dBulge = 0.0;
|
|
break;
|
|
case ARC_SEGMENT:
|
|
cvCurve = arc;
|
|
break;
|
|
default:
|
|
nRet = RTERROR;
|
|
}
|
|
cvCurve.m_nFlag = nFlag;
|
|
return nRet;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::Nth( int nIndex, TGGeDirectionCurve &curve, AcDb::Visibility *pVal /*= NULL*/ ) 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];
|
|
}
|
|
|
|
if (pVal != NULL)
|
|
{
|
|
*pVal = m_arnVisibility[nIndex];
|
|
}
|
|
|
|
double dAng = m_ardbulges[nIndex];
|
|
curve.m_startPoint = p1;
|
|
curve.m_endPoint = p2;
|
|
curve.m_dBulge = dAng;
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::Reverse()
|
|
{
|
|
if (Length() < 2)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
TGGeVisibilityPoly2D destPoly;
|
|
int nTotalSeg = TotalSegments();
|
|
TGGeDirectionCurve cv;
|
|
AcDb::Visibility visible = AcDb::kVisible;
|
|
|
|
for (int i = nTotalSeg - 1; i >= 0; i--)
|
|
{
|
|
Nth(i, cv, &visible);
|
|
destPoly.AppendNode(cv.EndPoint(), -cv.GetBulge(), visible);
|
|
}
|
|
|
|
if (!(m_nFlag & 0x01)) // 不闭合,添加原pline的第一个点
|
|
{
|
|
destPoly.AppendNode(*((*this)[0]), -(*m_ardbulges[nTotalSeg]), *m_arnVisibility[nTotalSeg]);
|
|
}
|
|
|
|
destPoly.SetFlag(m_nFlag);
|
|
*this = destPoly;
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::Compress( bool bUnionCurve )
|
|
{
|
|
int nLen = Length();
|
|
if (nLen < 1)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
// 删除重复点
|
|
int nIndex = -1; // 重复点索引
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
if (nIndex == -1)
|
|
{
|
|
nIndex = i;
|
|
continue;
|
|
}
|
|
|
|
TADSGePoint3d &pt1 = *((*this)[nIndex]);
|
|
TADSGePoint3d &pt2 = *((*this)[i]);
|
|
if (pt1.Distance(pt2) < _DIST_SNAP) // 两点重合
|
|
{
|
|
RemoveNode(nIndex); // 删除前一个重合点
|
|
--i; // 调整i值使其仍指向pt2点的索引
|
|
--nLen;
|
|
}
|
|
|
|
nIndex = i;
|
|
}
|
|
|
|
// 检查最后一点和第一点是否重合(闭合时)
|
|
if (m_nFlag == 1 && (*((*this)[0])).Distance(*((*this)[nLen - 1])) < _DIST_SNAP) // 两点重合
|
|
{
|
|
RemoveNode(nLen - 1); // 删除最后一点
|
|
}
|
|
|
|
if (!bUnionCurve)
|
|
{
|
|
return RTNORM;
|
|
}
|
|
|
|
// 合并可见性相同的共线或共圆的线段
|
|
nIndex = -1; // nIndex代表需要和当前索引i对应的线段对比的线段索引(前一点索引)
|
|
int bMerged = 0; // 是否可合并
|
|
TGGeArc arc1, arc2;
|
|
TGGeLine line1, line2;
|
|
int nType1 = 0, nType2 = 0; // 线型
|
|
int nNextIndex = -1; // 下一点索引
|
|
for (i = 0; i < Length(); i++)
|
|
{
|
|
if (nIndex == -1)
|
|
{
|
|
nIndex = i;
|
|
continue;
|
|
}
|
|
|
|
nNextIndex = i + 1;
|
|
if (i == Length() - 1 && m_nFlag == 1) // 曲线闭合在最后一点时,修改索引值
|
|
{
|
|
nNextIndex = 0;
|
|
}
|
|
else if (i == Length() - 1 && m_nFlag == 0) // 曲线不闭合在最后一点时,退出
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (*(m_arnVisibility[nIndex]) == *(m_arnVisibility[i])) // 可见性相同
|
|
{
|
|
nType1 = Nth(nIndex, line1, arc1, NULL);
|
|
nType2 = Nth(i, line2, arc2,NULL);
|
|
|
|
if (nType1 == nType2 && nType1 == LINE_SEGMENT) // 同为直线
|
|
{
|
|
if (IsOnSameLine(*((*this)[nIndex]), *((*this)[i]), *((*this)[nNextIndex]))) // 共线
|
|
{
|
|
RemoveNode(i); // 删除共线直线相交的点
|
|
--i; // 调整i值使其指向合并后的直线对应索引
|
|
}
|
|
}
|
|
else if (nType1 == nType2 && nType1 == ARC_SEGMENT) // 同为弧线
|
|
{
|
|
if (fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt()) // 共圆
|
|
{
|
|
double dAngle = GetAngleBy3Pt(*((*this)[nIndex]), *((*this)[i]), *((*this)[nNextIndex])); // 合并后的新弧的角度
|
|
double dBugle = tan(dAngle/4); // 新弧凸度值
|
|
dBugle = tan(*(m_ardbulges[nIndex]) / 4) < g_angleZero ? fabs(dBugle) * (-1) : fabs(dBugle); // 根据TGGeVisibilityPoly2D在nIndex的凸度值确定合并后的弧段的凸度值
|
|
*(m_ardbulges[nIndex]) = atan(dBugle) * 4; // 修改nIndex的凸度值
|
|
RemoveNode(i); // 删除共线直线相交的点
|
|
--i; // 调整i值使其指向合并后的直线对应索引
|
|
}
|
|
}
|
|
}
|
|
nIndex = i;
|
|
}
|
|
|
|
// 曲线闭合时处理最后一段和第一段
|
|
nLen = Length();
|
|
if (m_nFlag == 1 && nLen > 1 && *(m_arnVisibility[0]) == *(m_arnVisibility[nLen - 1]))
|
|
{
|
|
nType1 = Nth(0, line1, arc1, NULL);
|
|
nType2 = Nth(nLen - 1, line2, arc2,NULL);
|
|
|
|
if (nType1 == nType2 && nType1 == LINE_SEGMENT) // 同为直线
|
|
{
|
|
// 检查是否共线
|
|
if (IsOnSameLine(*((*this)[nLen - 1]), *((*this)[0]), *((*this)[1]))) // 共线
|
|
{
|
|
RemoveNode(0); // 删除共线直线相交的点
|
|
}
|
|
}
|
|
else if (nType1 == nType2 && nType1 == ARC_SEGMENT) // 同为弧线
|
|
{
|
|
if (fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt()) // 共圆
|
|
{
|
|
double dAngle = GetAngleBy3Pt(*((*this)[nLen - 1]), *((*this)[0]), *((*this)[1])); // 合并后的新弧的角度
|
|
double dBugle = tan(dAngle/4); // 新弧凸度值
|
|
dBugle = *(m_ardbulges[nLen - 1]) < g_angleZero ? fabs(dBugle) * (-1) : fabs(dBugle); // 根据TGGeVisibilityPoly2D在nIndex的凸度值确定合并后的弧段的凸度值
|
|
*(m_ardbulges[nLen - 1]) = atan(dBugle) * 4; // 修改nIndex的凸度值
|
|
RemoveNode(0); // 删除共线直线相交的点
|
|
}
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::Make( LPCTSTR szLay /*= NULL*/ ) const
|
|
{
|
|
int nLen = Length();
|
|
if (nLen <= 1)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
std::vector<std::vector<int> > vecIndex; // 保存需绘制的所有pline的索引
|
|
std::vector<int> vec;
|
|
bool bExist = false; // 是否在已有的vec中添加索引
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
if (!bExist)
|
|
{
|
|
vec.clear();
|
|
bExist = true;
|
|
}
|
|
|
|
if (m_arnVisibility[i] == AcDb::kVisible)
|
|
{
|
|
vec.push_back(i);
|
|
}
|
|
else
|
|
{
|
|
bExist = false;
|
|
if (!vec.empty())
|
|
{
|
|
vec.push_back(i);
|
|
vecIndex.push_back(vec);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!vec.empty())
|
|
{
|
|
vecIndex.push_back(vec);
|
|
}
|
|
|
|
// 当TGGeVisibilityPoly2D的第一个点和最后一个点均可见并且是闭合线时, 合并第一条和最后一条pline
|
|
int nSize = vecIndex.size();
|
|
std::vector<int>::iterator it;
|
|
if (m_nFlag == 1 // 闭合
|
|
&& m_arnVisibility[0] == AcDb::kVisible && m_arnVisibility[nLen - 1] == AcDb::kVisible // 第一点和最后一点均可见
|
|
&& nSize > 1) // 存在多条pline
|
|
{
|
|
std::vector<int> &vec1 = vecIndex[0], &vec2 = vecIndex[nSize - 1];
|
|
for (it = vec1.begin(); it != vec1.end(); it++)
|
|
{
|
|
vec2.push_back(*it);
|
|
}
|
|
|
|
vecIndex.erase(vecIndex.begin());
|
|
}
|
|
|
|
// 绘制pline
|
|
int nIndex = 0;
|
|
std::vector<std::vector<int> >::iterator it2;
|
|
for (it2 = vecIndex.begin(); it2 != vecIndex.end(); it2++)
|
|
{
|
|
AcDbPolyline *pLine = new AcDbPolyline;
|
|
for (it = (*it2).begin(), nIndex = 0; it != (*it2).end(); it++, nIndex++)
|
|
{
|
|
double dBuge = tan(m_ardbulges[*it] / 4.0);
|
|
pLine->addVertexAt(nIndex, (*this)[*it].AsAcGePoint2d(), dBuge);
|
|
}
|
|
|
|
if (nSize == 1 && m_nFlag == 1 && (*it2).size() == nLen) // 所有点可见并且是闭合线
|
|
{
|
|
pLine->setClosed(Adesk::kTrue);
|
|
}
|
|
|
|
if (szLay)
|
|
{
|
|
AssureLayer(szLay, LAYSTAT_UNLOCK);
|
|
pLine->setLayer(szLay);
|
|
}
|
|
|
|
double dThickness = 0.0;
|
|
TGGetVar(_T("THICKNESS"), &dThickness);
|
|
|
|
pLine->setThickness(dThickness);
|
|
pLine->setElevation((*this)[0].z);
|
|
AddToModelSpace(pLine, Adesk::kTrue);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::MakeSegments( LPCTSTR szLay /*= NULL*/ ) const
|
|
{
|
|
int nLen = Length();
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
MakeSegment(i, szLay);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::MakeSegment( int nIndex, LPCTSTR szLay /*= NULL*/ ) const
|
|
{
|
|
TGGeLine line;
|
|
TGGeArc arc;
|
|
AcDb::Visibility eVal;
|
|
int nrc = Nth(nIndex, line, arc, &eVal);
|
|
if (nrc == LINE_SEGMENT && eVal == AcDb::kVisible)
|
|
{
|
|
line.Make(szLay);
|
|
}
|
|
else if (nrc == ARC_SEGMENT && eVal == AcDb::kVisible)
|
|
{
|
|
arc.Make(szLay);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::TransformBy( const AcGeMatrix3d &mat )
|
|
{
|
|
TGGePoly2D::TransformBy(mat);
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::RemoveNode( long nIndex )
|
|
{
|
|
TGGePoly2D::RemoveNode(nIndex);
|
|
m_arnVisibility.Remove(nIndex);
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::InsertNodeAt( int nIndex, const TADSGePoint3d &pt, double dBulge, AcDb::Visibility eVal )
|
|
{
|
|
if (nIndex >= Length() - 1)
|
|
{
|
|
AppendNode(pt, dBulge, eVal);
|
|
}
|
|
else
|
|
{
|
|
(*this)[nIndex + 1];
|
|
Insert(new TADSGePoint3d(pt));
|
|
m_ardbulges[nIndex + 1];
|
|
m_ardbulges.Insert(new double(dBulge));
|
|
AcDb::Visibility *pVal = new AcDb::Visibility();
|
|
*pVal = eVal;
|
|
m_arnVisibility[nIndex + 1];
|
|
m_arnVisibility.Insert(pVal);
|
|
}
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::InsertNodeAt( const TADSGePoint3d &ptOn, AcDb::Visibility eVal )
|
|
{
|
|
// 检查ptOn是否在线上
|
|
int nLen = Length();
|
|
if (nLen == 2) // 只有一段线时
|
|
{
|
|
TGGeLine line;
|
|
TGGeArc arc;
|
|
int nType = Nth(0, line, arc, NULL); // 获得线段
|
|
if (nType == LINE_SEGMENT)
|
|
{
|
|
TADSGePoint3d ptS = line.StartPoint(), ptE = line.EndPoint();
|
|
double dDist1 = ptS.Distance(ptOn);
|
|
double dDist2 = ptE.Distance(ptOn);
|
|
double dDist = ptS.Distance(ptE);
|
|
if (fabs(dDist - dDist1 - dDist2) > _DIST_SNAP) // 检查点ptOn是否在直线上
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else if (nType == ARC_SEGMENT)
|
|
{
|
|
if (!(arc.PtOnArc(ptOn))) // 检查点ptOn是否在弧线上
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else if ((ptOn & (*this)) != PR_EDGE) // 存在多段线段,并且ptOn不在线上
|
|
{
|
|
return;
|
|
}
|
|
|
|
// ptOn在顶点上
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
TADSGePoint3d pt = *((*this)[i]);
|
|
if (pt.Distance(ptOn) < _DIST_SNAP)
|
|
{
|
|
*(m_arnVisibility[i]) = eVal; // ptOn在顶点上时直接修改其可见性即可
|
|
return;
|
|
}
|
|
}
|
|
|
|
// ptOn在线上并且不为顶点
|
|
TGGeLine line;
|
|
TGGeArc arc;
|
|
TADSGePoint3d pt1, pt2;
|
|
for (i = 0; i < nLen; i++)
|
|
{
|
|
int nType = Nth(i, line, arc); // 获取索引i对应的线段
|
|
if (nType == LINE_SEGMENT)
|
|
{
|
|
line.GetStartPoint(pt1);
|
|
line.GetEndPoint(pt2);
|
|
|
|
double dDist = pt1.Distance(pt2); // 直线长度
|
|
double dDist2 = pt1.Distance(ptOn) + pt2.Distance(ptOn); // ptOn到直线段两点距离之和
|
|
|
|
if (fabs(dDist2 - dDist) < _DIST_SNAP) // 判断点是否在直线上
|
|
{
|
|
if (i == nLen - 1)
|
|
{
|
|
(*this).Append(new TADSGePoint3d(ptOn));
|
|
m_ardbulges.Append(new double(0.0));
|
|
AcDb::Visibility *pVal = new AcDb::Visibility();
|
|
*pVal = eVal;
|
|
m_arnVisibility.Append(pVal);
|
|
}
|
|
else
|
|
{
|
|
(*this)[i+1];
|
|
(*this).Insert(new TADSGePoint3d(ptOn));
|
|
m_ardbulges[i+1];
|
|
m_ardbulges.Insert(new double(0.0));
|
|
AcDb::Visibility *pVal = new AcDb::Visibility();
|
|
*pVal = eVal;
|
|
m_arnVisibility[i+1];
|
|
m_arnVisibility.Insert(pVal);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (nType == ARC_SEGMENT)
|
|
{
|
|
if(arc.PtOnArc(ptOn)) // 判断点是否在弧上
|
|
{
|
|
pt1 = *((*this)[i]);
|
|
if (i == nLen - 1)
|
|
{
|
|
pt2 = *((*this)[0]);
|
|
}
|
|
else
|
|
{
|
|
pt2 = *((*this)[i + 1]);
|
|
}
|
|
|
|
// 求被ptOn分为两段的弧的凸度值
|
|
TADSGePoint3d pt;
|
|
arc.GetStartPoint(pt);
|
|
double dAngle1 = 0.0; // pt1与ptOn弧段的角度
|
|
double dAngle2 = 0.0; // pt2与ptOn弧段的角度
|
|
if (pt1.Distance(pt) < _DIST_SNAP) //pt1为弧起点
|
|
{
|
|
pt = arc.GetCenterPt();
|
|
AcGeVector3d vt1 = pt1 - pt;
|
|
AcGeVector3d vt2 = ptOn - pt;
|
|
AcGeVector3d vt3 = pt2 - pt;
|
|
dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
|
|
dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis);
|
|
}
|
|
else // pt2为弧起点
|
|
{
|
|
pt = arc.GetCenterPt();
|
|
AcGeVector3d vt1 = pt1 - pt;
|
|
AcGeVector3d vt2 = ptOn - pt;
|
|
AcGeVector3d vt3 = pt2 - pt;
|
|
dAngle1 = vt2.angleTo(vt1, AcGeVector3d::kZAxis);
|
|
dAngle2 = vt3.angleTo(vt2, AcGeVector3d::kZAxis);
|
|
}
|
|
|
|
double dBugle1 = tan(dAngle1 / 4); // 凸度值
|
|
double dBugle2 = tan(dAngle2 / 4);
|
|
|
|
// 根据原弧的凸度正负值确定新弧凸度值
|
|
double dBugle = tan(*(m_ardbulges[i]) / 4);
|
|
dBugle1 = dBugle > g_angleZero ? fabs(dBugle1) : fabs(dBugle1) * (-1);
|
|
dBugle2 = dBugle > g_angleZero ? fabs(dBugle2) : fabs(dBugle2) * (-1);
|
|
|
|
dAngle1 = atan(dBugle1) * 4;
|
|
dAngle2 = atan(dBugle2) * 4;
|
|
|
|
// 插入ptOn点
|
|
*(m_ardbulges[i]) = dAngle1; // 修改原弧凸度值
|
|
AcDb::Visibility *pVal = new AcDb::Visibility();
|
|
*pVal = eVal;
|
|
if (i == nLen - 1)
|
|
{
|
|
m_ardbulges.Append(new double(dAngle2));
|
|
m_arnVisibility.Append(pVal);
|
|
(*this).Append(new TADSGePoint3d(ptOn));
|
|
}
|
|
else
|
|
{
|
|
m_ardbulges[i+1];
|
|
m_ardbulges.Insert(new double(dAngle2));
|
|
m_arnVisibility[i+1];
|
|
m_arnVisibility.Insert(pVal);
|
|
(*this)[i+1];
|
|
(*this).Insert(new TADSGePoint3d(ptOn));
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::InsertNodeAt(const TADSGePoint3d &ptOn1, const TADSGePoint3d &ptOn2,AcDb::Visibility eVal)
|
|
{
|
|
int nIndex1 = HitTestOnCurve(ptOn1);
|
|
int nIndex2 = HitTestOnCurve(ptOn2);
|
|
if (nIndex1 == 0 || nIndex2 == 0) // 有点不在线上
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDb::Visibility eValTemp1 = AcDb::kVisible;
|
|
AcDb::Visibility eValTemp2 = AcDb::kVisible;
|
|
|
|
if (nIndex1 < 0) // 非顶点
|
|
{
|
|
eValTemp1 = GetVisibleAt(-nIndex1 - 1);
|
|
}
|
|
|
|
if (nIndex2 < 0) // 非顶点
|
|
{
|
|
eValTemp2 = GetVisibleAt(-nIndex2 - 1);
|
|
}
|
|
|
|
if (nIndex1 < 0) // 非顶点
|
|
{
|
|
InsertNodeAt(ptOn1,eValTemp1);
|
|
}
|
|
|
|
if (nIndex2 < 0) // 非顶点
|
|
{
|
|
InsertNodeAt(ptOn2,eValTemp2);
|
|
}
|
|
|
|
nIndex1 = HitTestOnCurve(ptOn1);
|
|
nIndex2 = HitTestOnCurve(ptOn2);
|
|
|
|
if (nIndex1 <= 0)
|
|
{
|
|
return;
|
|
}
|
|
if (nIndex2 <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
--nIndex1;
|
|
--nIndex2;
|
|
|
|
int nMin = nIndex1 < nIndex2 ? nIndex1 : nIndex2;
|
|
int nMax = nIndex2 < nIndex1 ? nIndex1 : nIndex2;
|
|
for(int i = nMin; i < nMax; i++)
|
|
{
|
|
SetVisibleAt(i, eVal);
|
|
}
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::AppendNode( const TADSGePoint3d &pt, ads_real dBulge, AcDb::Visibility eVal )
|
|
{
|
|
TGGePoly2D::AppendNode(pt, dBulge);
|
|
AcDb::Visibility *pVal = new AcDb::Visibility();
|
|
*pVal = eVal;
|
|
m_arnVisibility.Append(pVal);
|
|
}
|
|
|
|
TGGeVisibilityPoly2D& TGGeVisibilityPoly2D::operator=( const TGGeVisibilityPoly2D &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];
|
|
AcDb::Visibility *pVal = new AcDb::Visibility();
|
|
*pVal = src.GetVisibleAt(i);
|
|
Append(new TADSGePoint3d(pt));
|
|
m_ardbulges.Append(new ads_real(val));
|
|
m_arnVisibility.Append(pVal);
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::SetVisible( AcDb::Visibility dNewVal )
|
|
{
|
|
int nLen = Length();
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
*m_arnVisibility[i] = dNewVal;
|
|
}
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::SetVisibleAt( int nIndex, AcDb::Visibility dNewVal )
|
|
{
|
|
if (!IsValid(nIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
*m_arnVisibility[nIndex] = dNewVal;
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::SetVisibleAt( const TADSGePoint3d& ptOn, AcDb::Visibility dNewVal )
|
|
{
|
|
int nLen = Length();
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
if (ptOn.Distance(*((*this)[i])) < _DIST_SNAP)
|
|
{
|
|
*m_arnVisibility[i] = dNewVal;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TGGeVisibilityPoly2D::SetVisibleAt( int nFrom, int nTo, AcDb::Visibility dNewVal )
|
|
{
|
|
int nLen = Length();
|
|
if (IsValid(nFrom) && IsValid(nTo) && nFrom <= nTo)
|
|
{
|
|
for (int i = nFrom; i <= nTo; i++)
|
|
{
|
|
*m_arnVisibility[i] = dNewVal;
|
|
}
|
|
}
|
|
}
|
|
|
|
AcDb::Visibility TGGeVisibilityPoly2D::GetVisibleAt( int nIndex ) const
|
|
{
|
|
AcDb::Visibility eVal = AcDb::kVisible;
|
|
if (IsValid(nIndex))
|
|
{
|
|
eVal = m_arnVisibility[nIndex];
|
|
}
|
|
|
|
return eVal;
|
|
}
|
|
|
|
AcDb::Visibility TGGeVisibilityPoly2D::GetVisibleAt( const TADSGePoint3d& ptOn ) const
|
|
{
|
|
AcDb::Visibility eVal = AcDb::kVisible;
|
|
int nLen = Length();
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
if ((*this)[i] == ptOn)
|
|
{
|
|
eVal = m_arnVisibility[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return eVal;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::SetVisibilities( TDPtrList<AcDb::Visibility> &arnVisibility )
|
|
{
|
|
if (arnVisibility.Length() > 0)
|
|
{
|
|
m_arnVisibility.copyFrom(arnVisibility);
|
|
return m_arnVisibility.Length();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int TGGeVisibilityPoly2D::GetVisibilities( TDPtrList<AcDb::Visibility> &arnVisibility )
|
|
{
|
|
if (m_arnVisibility.Length() > 0)
|
|
{
|
|
arnVisibility.copyFrom(m_arnVisibility);
|
|
return arnVisibility.Length();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
TDPtrList<AcDb::Visibility>& TGGeVisibilityPoly2D::GetVisibilities()
|
|
{
|
|
return m_arnVisibility;
|
|
}
|
|
|
|
// add by xlc on 110427 获得poly离pt点近的一端指向poly内的方向
|
|
// 返回值:true:成功;false:失败
|
|
bool TGGeVisibilityPoly2D::GetIDirection(AcGePoint3d pt, double& dDir)
|
|
{
|
|
if (TotalSegments() < 1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TGGeCurveSegment cvSeg;
|
|
if (pt.distanceTo(*(*this)[0]) < pt.distanceTo(*(*this)[Length()-1]))
|
|
{
|
|
Nth(0, cvSeg);
|
|
if (cvSeg.GetBulge() < _angSnap) //直线段
|
|
{
|
|
dDir = cvSeg.IDirection(0);
|
|
}
|
|
else
|
|
{
|
|
if (pt.distanceTo(cvSeg.StartPoint()) < pt.distanceTo(cvSeg.EndPoint()))
|
|
{
|
|
dDir = cvSeg.IDirection(0);
|
|
}
|
|
else
|
|
{
|
|
dDir = cvSeg.IDirection(1);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Nth(TotalSegments()-1, cvSeg);
|
|
if (cvSeg.GetBulge() < _angSnap) //直线段
|
|
{
|
|
dDir = cvSeg.IDirection(1);
|
|
}
|
|
else
|
|
{
|
|
if (pt.distanceTo(cvSeg.StartPoint()) < pt.distanceTo(cvSeg.EndPoint()))
|
|
{
|
|
dDir = cvSeg.IDirection(0);
|
|
}
|
|
else
|
|
{
|
|
dDir = cvSeg.IDirection(1);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
} |