Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/DbApron.cpp
T
2026-09-28 15:28:50 +08:00

1785 lines
43 KiB
C++
Raw 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.
#include "stdafx.h"
#include "TDbColumn.h"
#include "TDbWallPatch.h"
inline CString DoubleToString(double dValue, int nPreci)
{
CString csRet;
CString csFormat;
csFormat.Format(_T("%%.%df"), nPreci);
csRet.Format(csFormat, dValue);
return csRet;
}
const Adesk::UInt8 TDbApron::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSApron, ATSPolyCurveEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_APRON, "ATS_APRON图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbApron);
//////////////////////////////////////////////////////////////////////
TDbApron::TDbApron()
{
m_dInHeight = _AS_SYS_UNIT(20);
m_dOutHeight = _AS_SYS_UNIT(10);
m_nFlag = 0;
}
TDbApron::~TDbApron()
{
ReleaseEntSet(m_entSet); // sg add 090521,释放掉外边界点
}
//////////////////////////////////////////////////////////////////////
void TDbApron::SetInHeight(double dHeight)
{
assertWriteEnabled();
m_dInHeight = dHeight;
}
double TDbApron::GetInHeight() const
{
assertReadEnabled();
return m_dInHeight;
}
void TDbApron::SetOutHeight(double dHeight)
{
assertWriteEnabled();
m_dOutHeight = dHeight;
}
double TDbApron::GetOutHeight() const
{
assertReadEnabled();
return m_dOutHeight;
}
void TDbApron::SetDistArray(const Array<double> &aryDist)
{
assertWriteEnabled();
m_aryDist = aryDist;
}
void TDbApron::GetDistArray(Array<double> &aryDist) const
{
assertReadEnabled();
aryDist = m_aryDist;
}
//////////////////////////////////////////////////////////////////////
int TDbApron::GetDistNum() const
{
return m_aryDist.GetLength();
}
void TDbApron::SetAllDists(double dDist, long lLength)
{
assertWriteEnabled();
if (GetDistNum() != 0)
{
m_aryDist.Clear(); // 首先清空
}
if (lLength == -1) // 使用路径的段数
{
lLength = m_polyBase.TotalSegments();
}
m_aryDist.Realloc(lLength);
m_aryDist.SetAll(dDist);
}
BOOL TDbApron::SetDistAt(long lIndex, double dDist)
{
assertWriteEnabled();
int nLength = GetDistNum();
if (lIndex<0 || lIndex>nLength-1)
{
return FALSE;
}
m_aryDist.SetAt(lIndex, dDist);
return TRUE;
}
double TDbApron::GetDistAt(long lIndex) const
{
int nLength = GetDistNum();
if (lIndex<0 || lIndex>nLength-1)
{
return -1;
}
return m_aryDist.GetAt(lIndex);
}
BOOL TDbApron::InsertDistAt(long lIndex, double dDist)
{
if (lIndex < 0)
{
return FALSE;
}
int nLength = GetDistNum();
if (lIndex >= nLength) // 超过数组长度,不考虑位置,在最后添加
{
m_aryDist.AddTail(dDist);
}
else // 在指定位置插入宽度值
{
m_aryDist.Insert(lIndex, dDist);
}
int nSegNum = m_polyBase.TotalSegments();
if (nSegNum==3 && nLength==1 && m_polyBase.IsClosed())
{
m_aryDist.AddTail(dDist); // 注:此情况下,需要增加两段
}
return TRUE;
}
BOOL TDbApron::RemoveDistAt(long lIndex)
{
int nLength = GetDistNum();
if (lIndex<0 || lIndex>=nLength)
{
return FALSE;
}
m_aryDist.Del(lIndex);
int nSegNum = m_polyBase.TotalSegments();
if (nSegNum==1 && nLength==3)
{
m_aryDist.DelTail(); // 注:此情况下,需要删除两段
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
void TDbApron::Get2DInPoly(XPoly2D &poly2d) const
{
assertReadEnabled();
poly2d = m_polyBase;
poly2d.SetElevation(0);
}
// aryIndex:polyBase的各顶点对应poly2d的顶点编号
// aryShow:polyBase的各线段对应poly2d的线段编号
BOOL TDbApron::Get2DOutPoly(XPoly2D &poly2d, Array<int> &aryIndex,
Array<int> &aryShow) const
{
assertReadEnabled();
XPoly2D polyBase; // 内侧路径点
Get2DInPoly(polyBase);
int nDistNum = GetDistNum(), // “宽度”数组数量
nSegNum = polyBase.TotalSegments(); // “段”数
if (nDistNum!=nSegNum || !IsValid())
return FALSE;
double dDist = m_aryDist.GetAt(0);
polyBase.QuickOffset(dDist, poly2d); // 首先快速生成一个外侧路径poly2d
int nTmp = poly2d.TotalSegments();
if (nTmp != nSegNum) // sg add 090522,当内侧路径有重合时,快速生成的路径数量和原来不一致,导致致命错误
return FALSE;
aryIndex.Realloc(polyBase.Length()); // sg add 081013,与内侧顶点对应的外侧顶点编号
aryIndex.SetAll(0);
aryShow.Realloc(nDistNum); // 与内侧段对应的外侧段编号
aryShow.SetAll(0);
// 以polyBase中的“段”为单位进行循环,对poly2d、aryIndex、aryShow进行修改
for (int i=0, j=0; i<nSegNum; i++, j++) // sg modify 081013,j为aryShow中的数
{
XDirectionCurve cvBase, cvOffset;
polyBase.Nth(i, cvBase); // 获取当前内侧段
cvOffset = cvBase.Offset(m_aryDist.GetAt(i), LS_INFINITE); // 外侧段
int nPrev = i - 1, // 前一段编号
nNext = i + 1; // 后一段编号
if (poly2d.IsClosed()) // 封闭路径,周期查找
{
nPrev = DePeriod(nSegNum, nPrev);
nNext = DePeriod(nSegNum, nNext);
}
int nIndex = j; // sg add 081013,aryIndex中的数值
XPoint ptStart, ptEnd;
XDirectionCurve cvPrev, cvPrevOffset, cvNext, cvNextOffset;
if (nPrev>=0 && nPrev<nSegNum) // 第2到最后1段,封闭路径时,包括第1段
{
polyBase.Nth(nPrev, cvPrev); // 前一段
cvPrevOffset = cvPrev.Offset(m_aryDist.GetAt(nPrev), LS_INFINITE);
XPoint ptInt[2];
int nIntNum = cvOffset.Intersection(cvPrevOffset, ptInt[0], ptInt[1]); // 求交点
if (nIntNum == 1) // 判断交点个数
{
ptStart = ptInt[0];
}
else if (nIntNum == 2)
{
ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(cvOffset.StartPoint());
}
else // 没有交点,sg modfify,081013
{
XPoint pt1 = cvOffset.StartPoint(),
pt2 = cvPrevOffset.EndPoint();
ptStart = pt1;
if (pt1.Distance(pt2) > _DIST_SNAP) // 两个偏移后的点不重合,需要加点
{
if (i == 0) // sg add 090602,解决首顶点处宽度不一致时,产生错误的情况
*poly2d[j] = pt2;
poly2d.SetBulge(j, 0); // 与新增加的点,直线连接
poly2d.InsertNodeAt(++j, pt1, cvBase.GetBulge());
}
if (fabs(cvBase.GetBulge())<1.0E-5 && fabs(cvPrev.GetBulge())<1.0E-5) // 两直线
{
if (m_aryDist.GetAt(i) > m_aryDist.GetAt(nPrev) + 1.0E-5)
{
nIndex++; // pt1离cvBase.StartPoint()较远
}
}
else // 有弧线
{
BOOL bSwap(FALSE); // 标记是否有弧段反向
XPoint ptArcStart, ptArcEnd;
if (fabs(cvBase.GetBulge()) > 1.0E-5) // 当前段是弧段
{
XArc arc = cvBase.GetArc();
arc.GetStartPoint(ptArcStart);
arc.GetEndPoint(ptArcEnd);
bSwap = ptArcStart.Distance(cvPrev.EndPoint()) > _DIST_SNAP; // 弧段反向
}
if (!bSwap && fabs(cvPrev.GetBulge())>1.0E-5) // 前一段是弧段
{
XArc arc = cvPrev.GetArc();
arc.GetStartPoint(ptArcStart);
arc.GetEndPoint(ptArcEnd);
bSwap = ptArcEnd.Distance(cvBase.StartPoint()) > _DIST_SNAP;
}
if (bSwap) // 有弧线产生了反向
{
nIndex = -1; // 不绘制“转角线”
}
else if (m_aryDist.GetAt(i) > m_aryDist.GetAt(nPrev) + 1.0E-5) // pt1较远
{
nIndex++;
XDirectionCurve(pt1, cvBase.StartPoint()).Intersection(cvPrevOffset,
ptArcStart, ptArcEnd); // 求交点
*poly2d[j-1] = XLine(ptArcStart, ptArcEnd).NearPoint(cvOffset.StartPoint());
}
else // pt2较远
{
XDirectionCurve(pt2, cvBase.StartPoint()).Intersection(cvOffset,
ptArcStart, ptArcEnd); // 求交点
ptStart = XLine(ptArcStart, ptArcEnd).NearPoint(cvOffset.StartPoint());
}
}
}
}
else // 不封闭路径时的第1段
{
ptStart = cvOffset.StartPoint();
}
if (nNext>=0 && nNext<nSegNum) // 第1到倒数第2段,封闭路径时,包括最后1段
{
polyBase.Nth(nNext, cvNext); // 后一段
cvNextOffset = cvNext.Offset(m_aryDist.GetAt(nNext), LS_INFINITE);
XPoint ptInt[2];
int nIntNum = cvOffset.Intersection(cvNextOffset, ptInt[0], ptInt[1]); // 求交点
if (nIntNum == 1) // 判断交点个数
{
ptEnd = ptInt[0];
}
else if (nIntNum == 2)
{
ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(cvOffset.EndPoint());
}
else // 没有交点,sg modfify,081013
{
ptEnd = cvOffset.EndPoint(); // 获取最近点
}
}
else // 不封闭路径时的最后1段
{
ptEnd = cvOffset.EndPoint();
aryIndex.SetAt(i+1, j+1); // 不封闭路径时,处理最后1点的对应关系
}
double dBulge = cvBase.GetBulge(); // 更新点的位置及Bulge
if (fabs(cvOffset.GetBulge()) > 1.0E-5) // 当前段是弧段,需要修改起点的Bulge
{
XPoint ptMid = cvOffset.MidPoint();
// sg add 091029,解决弧段较小时,出现的反向错误
XArc arcTmp = cvOffset.GetArc();
XPoint ptTmpCen = arcTmp.GetCenterPt();
XLine lineTmp(ptTmpCen, ptMid, LS_FINITE);
int nSide1 = lineTmp.OnWhichSide(ptStart),
nSide2 = lineTmp.OnWhichSide(ptEnd);
BOOL bSame = nSide1==nSide2;
XArc arc(ptStart, ptMid, ptEnd);
// if (!!arc) // 新弧有效
// sg modify 091029,解决弧段较小时,出现的反向错误
if (!bSame && !!arc) // 新弧有效
{
XPoint ptArcStart, ptArcEnd;
arc.GetStartPoint(ptArcStart);
arc.GetEndPoint(ptArcEnd);
dBulge = arc.Bulge();
if (ptArcStart.Distance(ptStart) > _DIST_SNAP) // 判断是否自动修改了弧的起点、终点
{
dBulge *= -1;
}
}
}
aryShow.SetAt(i, j); // sg add 081013
aryIndex.SetAt(i, nIndex);
*poly2d[j] = ptStart;
poly2d.SetBulge(j, dBulge);
if (j < poly2d.Length() - 1)
{
*poly2d[j+1] = ptEnd;
}
}
poly2d.SetElevation(0);
return TRUE;
}
BOOL TDbApron::Get2DRegion(XPoly2D &poly2d) const
{
AcGeVector3d vt = m_vtNormal;
if ((vt==AcGeVector3d(0,0,1)) && !m_polyBase.IsClosed())
{
XPoly2D poly1, poly2;
Get2DInPoly(poly1);
Array<int> aryIndex, aryShow;
if (!Get2DOutPoly(poly2, aryIndex, aryShow))
return FALSE;
poly2.Reverse();
aryIndex.Reverse();
aryShow.Reverse();
int nLength = poly2.Length();
for (int i=0; i<nLength; i++)
{
poly1.AppendNode(*poly2[i], poly2.GetBulge(i));
}
poly2d = poly1;
return TRUE;
}
return FALSE;
}
BOOL TDbApron::GetShapePoly(long lIndex, XPoly2D &poly) const
{
double dDist = GetDistAt(lIndex);
if (dDist < -1.0E-5)
{
return FALSE;
}
poly.SetFlag(1); // 设置闭合
XPoint ptVertex;
poly.AppendNode(ptVertex);
ptVertex.x += dDist;
poly.AppendNode(ptVertex);
ptVertex.y += m_dOutHeight;
poly.AppendNode(ptVertex);
ptVertex.x = 0;
ptVertex.y = m_dInHeight;
poly.AppendNode(ptVertex);
return TRUE;
}
//////////////////////////////////////////////////////////////////////
BOOL TDbApron::AddNewVertex(XPoint ptAdd)
{
assertWriteEnabled();
XPoint ptOnCurve;
if (!GetClosestPoint2d(ptAdd, ptOnCurve)) // 获取最近点
{
return FALSE;
}
XPoly2D poly2d,
polyPath = m_polyBase;
Get2DInPoly(poly2d);
int nPos = HitTestOnBase2d(ptOnCurve);
if (nPos < 0) // 命中边
{
nPos = abs(nPos);
nPos--; // 获取边的索引号
ptAdd.z = polyPath[nPos]->z; // 统一标高
XDirectionCurve seg;
poly2d.Nth(nPos, seg);
if (seg.IsMinusArc())
{
XArc ar1 = seg.GetArc(),
ar2 = seg.GetArc();
ar1.SetAngleByPoints(seg.EndPoint(), ptOnCurve);
ar2.SetAngleByPoints(ptOnCurve, seg.StartPoint());
polyPath.SetBulge(nPos, -ar2.Bulge());
polyPath.InsertNodeAt(nPos+1, ptAdd, ar1.Bulge());
}
else
{
XCurveSegment seg1 = seg,
seg2 = seg;
seg1.SetPoints(seg.StartPoint(), ptOnCurve);
seg2.SetPoints(ptOnCurve, seg.EndPoint());
polyPath.SetBulge(nPos, seg1.GetBulge());
polyPath.InsertNodeAt(nPos+1, ptAdd, seg2.GetBulge());
}
m_polyBase = polyPath;
return TRUE;
}
ptAdd.z = 0;
ptOnCurve.z = 0;
if (nPos>0 && ptOnCurve!=ptAdd) // 命中顶点
{
nPos--; // 获取顶点的索引号
ptAdd.z = polyPath[nPos]->z; // 统一标高
int nPrev = nPos - 1, // 前一点
nNext = nPos + 1; // 后一点
int nLength = polyPath.Length();
if (polyPath.IsClosed()) // 封闭路径,周期查找
{
nPrev = DePeriod(nLength, nPrev);
nNext = DePeriod(nLength, nNext);
}
BOOL bAddAfter(TRUE); // 标志是否将新点放在最近点之后
if (nPrev<0 || nPrev>=nLength) // 最近点为首顶点,且路径不闭合
{
bAddAfter = FALSE;
}
else if (nNext>=0 && nNext<nLength)
{
ptOnCurve = ptAdd;
ptOnCurve.z = 0;
XCurveSegment seg(*poly2d[nPrev], *poly2d[nNext], 0, LS_FINITE); // 前1点及后1点的连线
double dDistOld = fabs(seg.GetDist2Me(*poly2d[nPos])),
dDistNew = fabs(seg.GetDist2Me(ptOnCurve));
if (fabs(dDistOld - dDistNew) < _DIST_SNAP) // 距离连线的距离相等,比较左右情况
{
seg.SetPoints(*poly2d[nPrev], *poly2d[nPos]);
int nRet = seg.OnWhichSide(ptOnCurve);
bAddAfter = nRet==0; // 在右侧时,应该在最近点之前添加新点
}
else if (dDistOld > dDistNew + _DIST_SNAP) // 新点距离连线近
{
bAddAfter = FALSE;
}
else // 新点距离连线远
{
seg.SetPoints(*poly2d[nPos], *poly2d[nNext]);
int nRet = seg.OnWhichSide(ptOnCurve);
bAddAfter = nRet!=2; // 注:防止新点、最近点和下一点共线
}
}
if (bAddAfter) // 放到最近点之后,否则放在最近点之前
{
nPos++;
}
polyPath.InsertNodeAt(nPos, ptAdd);
m_polyBase = polyPath;
return TRUE;
}
return FALSE;
}
Acad::ErrorStatus TDbApron::SetPathPoly(const XPoly2D &polyPath, const AcGeVector3d&normal)
{
Acad::ErrorStatus es = TDbPolyCurveEnt::SetPathPoly(polyPath, normal);
XPoly2D poly2d;
Get2DInPoly(poly2d);
int nSegNum = poly2d.TotalSegments(),
nDistNum = GetDistNum();
while (nSegNum > nDistNum)
{
InsertDistAt(nDistNum, _AS_SYS_UNIT(600));
nDistNum++;
}
while (nSegNum < nDistNum)
{
RemoveDistAt(nDistNum-1);
nDistNum--;
}
return es;
}
//////////////////////////////////////////////////////////////////////
double TDbApron::GetPathLength() const
{
return m_polyBase.Distance3d();
}
double TDbApron::GetShapePerimeter(long lIndex) const
{
XPoly2D poly2d;
if (GetShapePoly(lIndex, poly2d)) // 获取指定段的截面
{
return poly2d.Distance2d();
}
return 0.0;
}
double TDbApron::GetShapeArea(long lIndex) const
{
XPoly2D poly2d;
if (!GetShapePoly(lIndex, poly2d)) // 获取指定段的截面
{
return 0.0;
}
if (!poly2d.IsClosed()) // 不闭合,不考虑面积
{
return 0.0;
}
return poly2d.Area();
}
double TDbApron::GetSideArea() const
{
double dArea(0.0);
int nLength = GetDistNum(); // 段数
for (int i=0; i<nLength; i++)
{
double dPathLength = m_polyBase.Distance3d(i);
dArea += GetShapePerimeter(i)*dPathLength;
}
return dArea;
}
double TDbApron::GetVolume() const
{
double dVolume(0.0);
int nLength = GetDistNum(); // 段数
for (int i=0; i<nLength; i++)
{
double dPathLength = m_polyBase.Distance3d(i);
dVolume += GetShapeArea(i)*dPathLength;
}
return dVolume;
}
//////////////////////////////////////////////////////////////////////
BOOL TDbApron::IsValid() const
{
BOOL bRet = TDbPolyCurveEnt::IsValid();
if (!bRet)
{
return bRet;
}
bRet = (m_polyBase.Length()>1 && m_aryDist.GetLength()>0);
return bRet;
}
bool TDbApron::IsClipMe(const TEntityBase* pEnt)const
{
if (TEntityBase::IsClipMe(pEnt))
{
return true;
}
//if (pEnt->GetMe()->isKindOf(TDbColumn::desc())|| // 柱子
// pEnt->GetMe()->isKindOf(TDbWallPatch::desc())) // 墙体附件
//{
// return true;
//}
// sg modify 110504,根据8.5测试反馈,修改为内凹墙体造型不遮挡散水
if (pEnt->GetMe()->isKindOf(TDbColumn::desc())) // 柱子
{
return true;
}
if (pEnt->GetMe()->isKindOf(TDbWallPatch::desc())) // 墙体附件
{
TDbWallPatch *pWallPatch = TDbWallPatch::cast(pEnt->GetMe());
if (pWallPatch != NULL)
{
if (pWallPatch->GetUsageFlag() == TDbWallPatch::kConcave) // 内凹墙体造型不遮挡散水
{
return false;
}
return true;
}
}
TDbWall *pWall = TDbWall::cast(pEnt->GetMe());
if (pWall != NULL)
{
if (pWall->HasOpeningOutWall())
return true;
}
else
{
TDbOpening *pOpen = TDbOpening::cast(pEnt->GetMe());
if (pOpen != NULL)
{
// 未处理组合门窗...
if (pOpen->GetKind() == TOpeningData::OP_PROWIN) // 窗
{
return true;
}
}
else
{
TDbCornerWin* pCornerWin = TDbCornerWin::cast(pEnt->GetMe());
if (pCornerWin!=NULL && pCornerWin->IsProtrude()) // 角窗
{
return true;
}
else
{
TDbBalcony *pBalcony = TDbBalcony::cast(pEnt->GetMe());
if (pBalcony != NULL) // 阳台
{
return true;
}
else
{
TDbAscent *pAscent = TDbAscent::cast(pEnt->GetMe());
if (pAscent != NULL) // 坡道
{
return true;
}
else
{
TDbStep *pStep = TDbStep::cast(pEnt->GetMe());
if (pStep != NULL) // 台阶
{
return true;
}
}
}
}
}
}
return false;
}
//////////////////////////////////////////////////////////////////////
void TDbApron::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyCurveEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbApron *pSrc = TDbApron::cast(pSrcEntity);
if (pSrc != NULL)
{
m_dInHeight = pSrc->m_dInHeight;
m_dOutHeight = pSrc->m_dOutHeight;
m_nFlag = pSrc->m_nFlag;
Array<double> aryDist;
pSrc->GetDistArray(aryDist);
SetDistArray(aryDist);
XPoly2D poly2D;
AcGeVector3d vec = pSrc->GetNormal();
double dElev = pSrc->GetElevationAt(0);
pSrc->GetPathPoly(poly2D, vec);
poly2D.SetElevation(dElev);
SetPathPoly(poly2D, vec);
}
}
Acad::ErrorStatus TDbApron::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
//////////////////////////////////////////////////////////////////////
// 从DWG读入数据:
Acad::ErrorStatus TDbApron::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyCurveEnt::dwgInFields(pFiler);
if (es != Acad::eOk)
{
return es;
}
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if (nVer > g_nVersion) // Version is too new
{
return Acad::eMakeMeProxy;
}
pFiler->readItem(&m_dInHeight);
pFiler->readItem(&m_dOutHeight);
if (m_aryDist.GetLength() != 0)
{
m_aryDist.Clear();
}
Adesk::UInt16 nTemp = 0;
pFiler->readItem(&nTemp);
for (Adesk::UInt16 i=0; i<nTemp; i++)
{
double dNum(0);
pFiler->readItem(&dNum);
m_aryDist.AddTail(dNum);
}
pFiler->readItem(&m_nFlag);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbApron::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyCurveEnt::dwgOutFields(pFiler);
if (es != Acad::eOk)
{
return es;
}
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_dInHeight);
pFiler->writeItem(m_dOutHeight);
Adesk::UInt16 nCount = (Adesk::UInt16)m_aryDist.GetLength();
pFiler->writeItem(nCount);
for (Adesk::UInt16 i=0; i<nCount; i++)
{
double dNum = m_aryDist.GetAt(i);
pFiler->writeItem(dNum);
}
pFiler->writeItem(m_nFlag);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbApron::dxfInFields (AcDbDxfFiler* pFiler)
{
Acad::ErrorStatus es = TDbPolyCurveEnt::dxfInFields(pFiler);
if (es != Acad::eOk)
{
return es;
}
if (!pFiler->atSubclassData(_T("TDbApron")))
{
return Acad::eBadDxfSequence;
}
resbuf rb;
Adesk::UInt32 nFlag = 0;
Array<double> aryDist;
double dInHeight(0), dOutHeight(0);
while ((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk))
{
switch(rb.restype)
{
case AcDb::kDxfAngle:
dInHeight = rb.resval.rreal;
break;
case AcDb::kDxfAngle+1:
dOutHeight = rb.resval.rreal;
break;
case AcDb::kDxfAngle+2:
aryDist.AddTail(rb.resval.rreal);
break;
case AcDb::kDxfInt32:
nFlag = rb.resval.rlong;
break;
default:
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
if (es != Acad::eEndOfFile)
{
return Acad::eInvalidResBuf;
}
long lCount = aryDist.GetLength();
if (lCount < 1)
{
pFiler->setError(_T("\nError DXF group code: 11, 51"));
return Acad::eMissingDxfField;
}
m_dInHeight = dInHeight;
m_dOutHeight = dOutHeight;
if (m_aryDist.GetLength() != 0)
{
m_aryDist.Clear();
}
for (long i=0; i<lCount; i++)
{
double dNum = aryDist.GetAt(i);
m_aryDist.AddTail(dNum);
}
m_nFlag = nFlag;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbApron::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es = TDbPolyCurveEnt::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("TDbApron"));
assert(es == Acad::eOk);
pFiler->writeDouble(AcDb::kDxfAngle, m_dInHeight);
pFiler->writeDouble(AcDb::kDxfAngle+1, m_dOutHeight);
long lCount = m_aryDist.GetLength();
for (long i=0; i<lCount; i++)
{
double dNum = m_aryDist.GetAt(i);
pFiler->writeDouble(AcDb::kDxfAngle+2, dNum);
}
pFiler->writeInt32(AcDb::kDxfInt32, m_nFlag);
return es;
}
//////////////////////////////////////////////////////////////////////
Acad::ErrorStatus TDbApron::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbPolyCurveEnt::subTransformBy(xform);
if (IsMirrorMatrix(xform))
{
m_polyBase.Reverse();
m_aryDist.Reverse();
return Acad::eOk;
}
return Acad::eOk;
}
// sg modify 090521
Acad::ErrorStatus TDbApron::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
int nCount = m_entSet.length();
for (int i=0; i<nCount; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)m_entSet[i];
pEnt->getOsnapPoints(osnapMode, gsSelectionMark, pickPoint, lastPoint,
viewXform, snapPoints, geomIds);
}
return Acad::eOk;
}
Acad::ErrorStatus TDbApron::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
TDbPolyCurveEnt::subGetGripPoints(gripPoints, osnapModes, geomIds);
XPoly2D poly2D; // 外侧线
Array<int> aryIndex, aryShow;
if (!Get2DOutPoly(poly2D, aryIndex, aryShow))
return Acad::eOk;
double dElev = GetElevationAt(0); // 获取路径标高
poly2D.SetElevation(dElev);
int nLength = aryShow.GetLength();
for (long i=0; i<nLength; i++)
{
XDirectionCurve cv;
int nNum = aryShow.GetAt(i); // polyIn的各段对应polyOut的段编号
poly2D.Nth(nNum, cv);
XPoint ptMid = cv.MidPoint();
gripPoints.append(ptMid); // 增加外侧边中点为改变宽度的夹点
}
return Acad::eOk;
}
Acad::ErrorStatus TDbApron::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
double dElev = GetElevationAt(0);
TDbPolyCurveEnt::subMoveGripPointsAt(indices, offset);
m_polyBase.SetElevation(dElev); // 统一标高
int nVertexCount = m_polyBase.Length(); // 路径点数量
XPoint vtOffset = Wcs2Ecs(*(XPoint *)&offset, m_vtNormal);
XPoly2D poly2d;
Array<int> aryIndex, aryShow;
if (!Get2DOutPoly(poly2d, aryIndex, aryShow))
return Acad::eOk;
poly2d.SetElevation(dElev);
for (int i=0; i<indices.length(); i++)
{
int idx = indices[i],
nTotalEdge = aryShow.GetLength(); // Poly的总边数,“宽度数组”的数量
int nIndex = idx - nVertexCount - nTotalEdge;
if (nIndex>=0 && nIndex<nTotalEdge) // 只需要处理用于“改变宽度”的夹点
{
XDirectionCurve cv; // 被移动的边,不修改点的位置,只修改宽度
int nNum = aryShow.GetAt(nIndex);
poly2d.Nth(nNum, cv);
ASSERT(!!cv);
AcGeVector3d vecMove; // 允许的偏移方向
if (cv.Is(CURVE_LINE)) // 直线
{
AcGeVector3d vecEdge = XVector3D(cv.EndPoint() - cv.StartPoint()).AsAcGeVector3d();
vecMove = vecEdge.perpVector(); // 垂直方向
}
else // 弧线
{
XArc arc = cv.GetArc();
XPoint ptStart, ptEnd, ptMid;
arc.MidPoint(ptMid);
arc.GetStartPoint(ptStart);
arc.GetEndPoint(ptEnd);
if (ptStart.Distance(cv.StartPoint()) > _DIST_SNAP) // 自动交换了起点、终点
{
vecMove = XVector3D(ptMid - arc.GetCenterPt()).AsAcGeVector3d();
}
else // 未交换起点、终点
{
vecMove = XVector3D(arc.GetCenterPt() - ptMid).AsAcGeVector3d();
}
}
vecMove.normalize();
double dNewDist = vtOffset.AsAcGeVector3d().dotProduct(vecMove), // 拖拽宽度
dOldDist = GetDistAt(nIndex); // 旧宽度
double dDist = dOldDist - dNewDist; // 新宽度
//if (dDist < _DIST_SNAP) // 只允许往外侧拖拽
if (dOldDist*dDist < _DIST_SNAP) // sg add 110126,解决8.5版本支持宽度为负数的情况,只允许往外侧拖拽
{
dDist = 0.0;
}
SetDistAt(nIndex, dDist);
}
}
return Acad::eOk;
}
//////////////////////////////////////////////////////////////////////
Acad::ErrorStatus TDbApron::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet,
BOOL *bErase) // sg add 081021
{
Acad::ErrorStatus es = Acad::eOk;
if (g_nSaveTArchVer >= GetFirstVersion()) // 导出为T8格式
{
if (bErase)
{
*bErase = FALSE;
}
es = TDbPolyCurveEnt::DownGradeSave(nDrawMode, entSet, bErase);
}
else if (g_nSaveTArchVer == 7) // 导出为T7格式
{
Array<double> aryTmp = m_aryDist;
double dDist = m_aryDist.GetAt(0);
aryTmp.SetAll(dDist);
int nLen1 = aryTmp.GetLength(),
nLen2 = m_aryDist.GetLength();
BOOL bFlag = nLen1 == nLen2; // 首先判断长度是否相等
if (bFlag)
{
for (int i=0; i<nLen1; i++)
{
if (fabs(m_aryDist.GetAt(i)-aryTmp.GetAt(i)) > 1.0E-5)
{
bFlag = FALSE; // 再判断内容是否一致
break;
}
}
}
if (bFlag) // 一样,存为“路径曲面”对象
{
XPoly2D polyShape;
GetShapePoly(0, polyShape);
TDbCurveMesh2 *pMesh = new TDbCurveMesh2;
pMesh->CopyPropertiesFrom(this, 0);
pMesh->SetPathPoly(m_polyBase, GetNormal());
pMesh->SetShapePoly(polyShape);
pMesh->SetShapeBase(XPoint());
pMesh->SetHas2D(TRUE);
pMesh->SetHasDivide2D(TRUE);
pMesh->SetHas3D(TRUE);
pMesh->setLayer(layerId());
pMesh->setColorIndex(colorIndex());
entSet.append(pMesh);
if (bErase)
{
*bErase = TRUE;
}
}
else // 不一样,炸开
{
XExplodeStream dc(entSet);
if (!OnExplodeOrDraw(dc)) // sg add 090303,解决导出后,无遮挡关系的BUG
return es;
dc.SetPropertiesFrom(this);
if (nDrawMode == DRAW_2D)
es = ExplodeOrDraw2d(dc);
else
es = ExplodeOrDraw3d(dc);
if (bErase)
*bErase = TRUE;
}
}
else // 导出为T3、T5、T6格式,炸开
{
XExplodeStream dc(entSet);
if (!OnExplodeOrDraw(dc)) // sg add 090303,解决导出后,无遮挡关系的BUG
return es;
dc.SetPropertiesFrom(this);
if (nDrawMode == DRAW_2D)
es = ExplodeOrDraw2d(dc);
else
es = ExplodeOrDraw3d(dc);
if (bErase)
*bErase = TRUE;
}
return es;
}
// 绘制2D的显示,注:目前只考虑是散水对象
Acad::ErrorStatus TDbApron::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
assertReadEnabled();
if (!IsValid()) // sg add 090601,只有一个点时,不绘制
return Acad::eNotApplicable;
// add by whl on 090324,捕捉时加速
// sg modify 090521,解决加速后,散水外侧路径线,无捕捉问题
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 || g_bOsnapExpl)
{
ReleaseEntSet(m_entSet); // sg modify 090521
XPushMemVar<BOOL> bExpl(g_bOsnapExpl, FALSE);
XPushMemVar<BOOL> bFull(XExplodeStream::m_bFullExplode, TRUE);
// AcDbVoidPtrArray entSet; // sg delete 090521
// XExplodeStream dcExp(entSet);
XExplodeStream dcExp(m_entSet);
dcExp.SetPropertiesFrom(this);
//add by xlc on 100430 解决散水移动时速度慢的问题
if (dc.IsDragging())
{
dcExp.SetIsDragging(Adesk::kTrue);
}
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) // add by whl on 090427
OnExplodeOrDraw(dcExp); // add by whl on 090423
ExplodeOrDraw2d(dcExp);
int nGsMarker = 1;
INT_PTR nQuickMarker = GetQuickMarker();
// int nCount = entSet.length(); // sg modify 090521
int nCount = m_entSet.length();
for (int i=0; i<nCount; i++)
{
// AcDbEntity *pEnt = (AcDbEntity *)entSet[i]; // sg modify 090521
AcDbEntity *pEnt = (AcDbEntity *)m_entSet[i];
dc.SetSelectionMarker(nGsMarker);
nGsMarker++;
if (nQuickMarker && (nGsMarker-1)!=nQuickMarker)
continue;
dc.DrawEntity(*pEnt);
if (nQuickMarker && (nGsMarker-1)==nQuickMarker)
break;
}
// ReleaseEntSet(entSet); // sg delete 090521
return Acad::eOk;
}
AcGeVector3d vt;
vt = m_vtNormal;
if (vt == AcGeVector3d(0, 0, 1))
{
XPoly2D polyIn, polyOut;
Get2DInPoly(polyIn);
dc << polyIn; // 内侧线
Array<int> aryIndex, aryShow;
if (!Get2DOutPoly(polyOut, aryIndex, aryShow))
return Acad::eOk;
int nLength = aryShow.GetLength();
if (nLength == polyIn.TotalSegments())
{
for (long i=0; i<nLength; i++) // 外侧线
{
XCurveSegment cv;
int nNum = aryShow.GetAt(i); // polyIn的各段对应polyOut的段编号
polyOut.Nth(nNum, cv);
dc << cv;
}
}
nLength = polyIn.Length();
if (nLength == aryIndex.GetLength()) // 转角线
{
for (long i=0; i<nLength; i++)
{
int nNum = aryIndex.GetAt(i); // polyIn的各顶点对应polyOut的顶点编号
if (nNum != -1)
{
dc << XLine(*polyIn[i], *polyOut[nNum]);
}
}
}
}
else
{
ExplodeOrDraw3d(dc);
}
return Acad::eOk;
}
// 绘制3D的显示,注:有部分内容是根据散水对象做的特殊处理
Acad::ErrorStatus TDbApron::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
assertReadEnabled();
extern int GetCirDivNum(double r, double h);
extern double g_nCirDeviation;
DList<XPoly2D> lstPolys;
DList<Adesk::UInt8> lstColVis;
XPoly2D polyIn2d, polyOut2d;
Array<int> aryIndex, aryShow;
Get2DInPoly(polyIn2d);
if (!Get2DOutPoly(polyOut2d, aryIndex, aryShow))
return Acad::eOk;
lstPolys.Append(new XPoly2D(polyIn2d)); // 路径曲线,基线
lstColVis.Append(new Adesk::UInt8(TRUE));
lstPolys.Append(new XPoly2D(polyOut2d)); // 外侧线
lstColVis.Append(new Adesk::UInt8(TRUE));
XPoly2D polyIn3d = polyIn2d,
polyOut3d = polyOut2d;
polyIn3d.SetElevation(m_dInHeight);
polyOut3d.SetElevation(m_dOutHeight);
lstPolys.Append(new XPoly2D(polyOut3d));
lstColVis.Append(new Adesk::UInt8(TRUE));
lstPolys.Append(new XPoly2D(polyIn3d));
lstColVis.Append(new Adesk::UInt8(TRUE));
lstPolys.Append(new XPoly2D(polyIn2d)); // 注:截面曲线为封闭曲线
lstColVis.Append(new Adesk::UInt8(TRUE));
double dElev = GetElevationAt(0); // 散水各点标高一致
int nPolyNum = lstPolys.Length(); // 截面点数量=5
for (int i=0; i<nPolyNum; i++)
{
XPoly2D &rPoly = *lstPolys[i];
int nPtNum = rPoly.Length(); // 各条路径顶点数量
for (int j=0; j<nPtNum; j++)
{
rPoly[j]->z += dElev; // 调整标高
}
}
int nTotalSeg = m_polyBase.TotalSegments(); // 路径段数
for (int n=0; n<nTotalSeg; n++)
{
DList<XDirectionCurve> lstCurves; // 构成每“段”的五条边
for (int j=0; j<nPolyNum; j++)
{
int nNum = n;
if (j==1 || j==2) // 对散水对象做的特殊处理,绘制外侧边时,找实际绘制的段
{
nNum = aryShow[n];
}
XDirectionCurve *pCurve = new XDirectionCurve;
lstPolys[j]->Nth(nNum, *pCurve);
lstCurves.Append(pCurve);
}
int nDiv = 30;
XDirectionCurve mSeg;
polyIn2d.Nth(n, mSeg);
if (mSeg.Is(CURVE_ARC)) // 将弧线分成若干段直线
{
nDiv = TchExport::GetCirDivNum(mSeg.GetArc().GetRadius(), _AS_SYS_UNIT(TchGeLib::g_nCirDeviation));
}
int nStep = AS_INT(fabs(mSeg.GetBulge())/PI/2.0*nDiv);
if (nStep <= 0)
{
nStep = 1;
}
int nCol = lstCurves.Length(), // =5
nRow = nStep + 1;
XPoint *ptArray = new XPoint[nCol*nRow];
for (int col=0; col<nCol; col++)
{
XDirectionCurve &segThis = *lstCurves[col];
double nDistStep = segThis.GetLength()/nStep;
for (int row=0; row<nRow; row++)
{
XPointDir2d ptDir2d;
segThis.Polar(nDistStep*row, ptDir2d);
ptArray[row*nCol+col] = ptDir2d;
}
}
int nEdgeNum = nRow*(nCol-1) + nCol*(nRow-1);
Adesk::UInt8 *pVisArray = new Adesk::UInt8[nEdgeNum]; // 控制各个边是否可见
for (int k=0; k<nEdgeNum; k++)
{
pVisArray[k] = kAcGiVisible; // 每个边都可见
}
for (k=1; k<nRow-1; k++) // 除首末行外,其余各行的边均不可见
{
for (int j=0; j<nCol-1; j++)
{
pVisArray[k*(nCol-1)+j] = kAcGiInvisible;
}
}
int nIndexBase = nRow*(nCol-1);
for (col=0; col<nCol; col++)
{
Adesk::UInt8 bVis = *lstColVis[col];
for (int row=0; row<nRow-1; row++)
{
pVisArray[nIndexBase+col*(nRow-1)+row] = bVis;
}
}
int nVertexNum = nCol*nRow;
for (k=0; k<nVertexNum; k++)
{
ptArray[k] = Ecs2Wcs(ptArray[k], m_vtNormal);
}
AcGiEdgeData edgeInfo;
edgeInfo.setVisibility(pVisArray);
dc.DrawMesh(nRow, nCol, (AcGePoint3d *)ptArray, &edgeInfo);
if (n==0 && !polyIn2d.IsClosed())
{
XPoly2D polyTemp1(1);
for (col=0; col<nCol-1; col++)
{
polyTemp1.AppendNode(ptArray[col]);
}
dc.DrawShell(polyTemp1, DList<XPoly2D>());
}
if (n==nTotalSeg-1 && !polyIn2d.IsClosed())
{
XPoly2D polyTemp2(1);
for (col=0; col<nCol-1; col++)
{
polyTemp2.AppendNode(ptArray[(nRow-1)*nCol+col]);
}
dc.DrawShell(polyTemp2, DList<XPoly2D>());
}
delete []pVisArray;
delete []ptArray;
}
return Acad::eOk;
}
//////////////////////////////////////////////////////////////////////
void TDbApron::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("散水")));
lstInfo.Append(new TObjInfoUnit(_T("路径长度"), Dist2Str(GetPathLength())));
lstInfo.Append(new TObjInfoUnit(_T("侧面面积"), XString(_T("%.2f"), _AS_SQMETER(GetSideArea()))));
lstInfo.Append(new TObjInfoUnit(_T("体积"), XString(_T("%.3f"), _AS_CUMETER(GetVolume()))));
}
// 取得夹点说明
Acad::ErrorStatus TDbApron::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es = TDbPolyCurveEnt::GetGripText(idx, cs);
if (es == Acad::eOk)
{
return es;
}
int nVertexCount = m_polyBase.Length(),
nTotalEdge = m_polyBase.TotalSegments();
int nIndex = idx - nVertexCount - nTotalEdge;
if (nIndex>=0 && nIndex<nTotalEdge) // 只需要处理用于“改变宽度”的夹点
{
cs.Format(_T("改变第%d条边宽度"), nIndex+1);
}
return Acad::eOk;
}
//////////////////////////////////////////////////////////////////////
void TDbApron::ModifyAllDistByOld(TDbApron *pNewApron) const
{
pNewApron->SetAllDists(_AS_SYS_UNIT(600)); // 保证数组长度与新实体中的路径段数一致
XPoly2D polyOld2D, poly2D;
Get2DInPoly(polyOld2D); // 获取当前的POLY
pNewApron->Get2DInPoly(poly2D); // 获取操作后新产生的POLY
int nSegCount = poly2D.TotalSegments();
for (long j=0; j<nSegCount; j++)
{
XPoint ptNew = *poly2D[j];
int nRet = polyOld2D.HitTestOnCurve(ptNew);
if (nRet != 0) // 命中的是边或顶点
{
nRet = abs(nRet) - 1;
double dDist = GetDistAt(nRet);
if (dDist < -1.0E-5)
{
continue;
}
pNewApron->SetDistAt(j, dDist);
}
}
}
// TRIM调用
Acad::ErrorStatus TDbApron::getSplitCurves(const AcGeDoubleArray& params,
AcDbVoidPtrArray& curveSegments) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyCurveEnt::getSplitCurves(params, curveSegments);
int nLength = curveSegments.length();
for (long i=0; i<nLength; i++)
{
TDbApron *pApron = (TDbApron*)curveSegments[i];
pApron->m_polyBase.SetFlag(0); // 强制修改为不闭合
ModifyAllDistByOld(pApron);
}
return es;
}
// BREAK调用
Acad::ErrorStatus TDbApron::getSplitCurves(const AcGePoint3dArray& points,
AcDbVoidPtrArray& curveSegments) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyCurveEnt::getSplitCurves(points, curveSegments);
int nLength = curveSegments.length();
for (long i=0; i<nLength; i++)
{
TDbApron *pApron = (TDbApron*)curveSegments[i];
pApron->m_polyBase.SetFlag(0); // 强制修改为不闭合
ModifyAllDistByOld(pApron);
}
return es;
}
// OFFSET调用
Acad::ErrorStatus TDbApron::getOffsetCurves(double offsetDist,
AcDbVoidPtrArray& offsetCurves) const
{
XPoly2D polyOld2D;
AcDbPolyline pline;
Get2DInPoly(polyOld2D);
PolyConvert(polyOld2D, pline); // 转化成CAD中的PLINE线
AcDbVoidPtrArray entSet;
Acad::ErrorStatus es = pline.getOffsetCurves(offsetDist, entSet);
if (es == Acad::eOk)
{
int nCount = entSet.length();
double dElev = GetElevationAt(0);
for (int n=0; n<nCount; n++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[n];
if (pEnt->isKindOf(AcDbPolyline::desc()))
{
XPoly2D poly2D;
AcDbPolyline *pCurve = AcDbPolyline::cast(pEnt);
PolyConvert(*pCurve, poly2D); // 再转化为XPoly2D
poly2D.SetElevation(dElev); // 修改标高
TDbApron *pClone = new TDbApron;
pClone->setPropertiesFrom(this);
if (pClone->SetPathPoly(poly2D, GetNormal()) == Acad::eOk)
{
offsetCurves.append(pClone);
}
else
{
delete pClone;
}
}
}
}
ReleaseEntSet(entSet);
return es;
}
#if ADS>14
Acad::ErrorStatus
TDbApron::getOffsetCurvesGivenPlaneNormal(const AcGeVector3d& normal,
double offsetDist,
AcDbVoidPtrArray& offsetCurves) const
{
// 注:散水对象为2D实体,忽略normal
return getOffsetCurves(offsetDist, offsetCurves);
}
#endif
//////////////////////////////////////////////////////////////////////
#if ADS>15
void TDbApron::CreateGrip()
{
TDbPolyCurveEnt::CreateGrip(); // 由基类添加
int nSegNum = m_polyBase.TotalSegments(), // 段的数量
nVertexNum = m_polyBase.Length(); // 点的数量
long lFirset = nSegNum + nVertexNum; // 起始编号
XPoly2D poly2D; // 外侧线
Array<int> aryIndex, aryShow;
if (!Get2DOutPoly(poly2D, aryIndex, aryShow))
return;
if (aryShow.GetLength() != nSegNum)
{
return;
}
for (int i=0; i<nSegNum; i++)
{
long iSeg = i + lFirset;
GetGrip(iSeg)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength)); // 宽度
GetGrip(iSeg)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength, false)); // 偏移量
}
}
Acad::ErrorStatus TDbApron::EntityToDim(long iGrip, long iDim, const AcDbEntity *pEnt)
{
TDbGripDim *pDim = GetGripDim(iGrip, iDim);
if (pDim == NULL)
{
return Acad::eInvalidInput;
}
TDbApron *pApron = TDbApron::cast(pEnt);
if (pApron == NULL)
{
// return Acad::eInvalidInput;
pApron = this; // sg modify 080916,动态输入打开,查看夹点时,也显示标注
}
int nSegNum = m_polyBase.TotalSegments(), // 段的数量
nVertexNum = m_polyBase.Length(); // 点的数量
long lFirset = nSegNum + nVertexNum; // 起始编号
if (lFirset > iGrip) // 与基类处理相同
{
XPoly2D polyPath;
AcGeVector3d normal;
pApron->GetPathPoly(polyPath, normal);
return ::EntityToDim(this, polyPath, iGrip, iDim, 0);
}
XPoly2D polyIn2D, polyOut2D;
Array<int> aryIndex, aryShow;
Get2DInPoly(polyIn2D);
if (!Get2DOutPoly(polyOut2D, aryIndex, aryShow))
return Acad::eOk;
XDirectionCurve cvIn, cvOut;
long lSegNum = iGrip - lFirset;
int nNum = aryShow.GetAt(lSegNum);
polyIn2D.Nth(lSegNum, cvIn);
polyOut2D.Nth(nNum, cvOut);
ASSERT(!!cvIn || !!cvOut);
XPoint ptMidOut = cvOut.MidPoint(),
ptNew, ptMidIn;
cvIn.ProjectToMe(ptMidOut, ptMidIn);
double dAngle = ads_angle(XPoint(), XVector3D(ptMidOut-ptMidIn)),
dDist = pApron->GetDistAt(lSegNum);
ads_polar(ptMidIn, dAngle, dDist, ptNew);
switch(iDim)
{
case 0: // 宽度
{
TDbGripDistDim *pDistDim = (TDbGripDistDim*)pDim;
pDistDim->SetData(ptMidIn, ptNew, _AS_SYS_UNIT(800));
}
break;
case 1: // 位置偏移
{
TDbGripDistDim *pDistDim = (TDbGripDistDim*)pDim;
pDistDim->SetData(ptMidOut, ptNew, _AS_SYS_UNIT(-800));
}
break;
default:
return Acad::eNotImplementedYet;
}
return Acad::eOk;
}
Acad::ErrorStatus TDbApron::DimToEntity(long iGrip, long iDim, double newValue, const AcGeVector3d& offset)
{
assertWriteEnabled();
int nSegNum = m_polyBase.TotalSegments(), // 段的数量
nVertexNum = m_polyBase.Length(); // 点的数量
long lFirset = nSegNum + nVertexNum; // 起始编号
if (lFirset > iGrip) // 与基类处理相同
{
TDbApron apron;
apron.CopyPropertiesFrom(this, 0);
Acad::ErrorStatus es = ::DimToEntity(this, m_polyBase, iGrip, iDim, newValue, offset, 0);
if ((es==Acad::eOk) && !IsValid())
{
CopyPropertiesFrom(&apron, 0);
return Acad::eInvalidInput;
}
return es;
}
double dNewDist(newValue);
long lSegNum = iGrip - lFirset;
switch(iDim)
{
case 1: // 位置偏移
{
XPoly2D polyIn2D, polyOut2D;
Array<int> aryIndex, aryShow;
Get2DInPoly(polyIn2D);
if (!Get2DOutPoly(polyOut2D, aryIndex, aryShow))
return Acad::eOk;
XDirectionCurve cvIn, cvOut;
int nNum = aryShow.GetAt(lSegNum);
polyIn2D.Nth(lSegNum, cvIn);
polyOut2D.Nth(nNum, cvOut);
ASSERT(!!cvIn || !!cvOut);
XPoint ptMidIn,
ptMidOut = cvOut.MidPoint();
cvIn.ProjectToMe(ptMidOut, ptMidIn);
AcGePoint3d ptNew = GetGripPoint(iGrip) + offset; // 输入时,点的位置
AcGeVector3d vtOld = ptMidOut.AsAcGePoint3d() - ptMidIn.AsAcGePoint3d(),
vtNew = ptNew - ptMidOut.AsAcGePoint3d();
if (fabs(vtNew.angleTo(vtOld)) < 1.0E-5) // 同向拖拽
{
dNewDist += GetDistAt(lSegNum);
}
else // 反向拖拽
{
dNewDist = GetDistAt(lSegNum) - dNewDist;
if (dNewDist < -1.0E-5) // 宽度小于0,自动修正
{
dNewDist = 0;
}
}
}
case 0: // 宽度
SetDistAt(lSegNum, dNewDist);
break;
default:
return Acad::eNotImplementedYet;
}
return Acad::eOk;
}
#endif
CString TDbApron::GetXml( const AcGeMatrix3d& mat ) const
{
XPoly2D polyIn, polyOut;
Get2DInPoly(polyIn); // 内侧线
Array<int> aryIndex, aryShow;
if (!Get2DOutPoly(polyOut, aryIndex, aryShow)) // 外侧线
{
return CString();
}
polyIn.TransformBy(mat);
polyOut.TransformBy(mat);
TXmlTree xmlTree;
POSITION posRoot = xmlTree.Insert(_T("ATS_APRON"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("散水"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
}
int nPre = 3; // 精度
POSITION posIn = xmlTree.Insert(_T("PolyIn"), posRoot, NULL);
{
xmlTree.SetAttribute(posIn, _T("name"), _T("内侧线"));
POSITION posTemp = NULL;
int nLen = polyIn.Length();
CString sPt, sX, sY, sZ;
XPoint ptTemp;
for (int i = 0; i < nLen; ++i)
{
ptTemp = *polyIn[i];
sPt.Format(_T("Point_%d"), i + 1);
posTemp = xmlTree.Insert(sPt, posIn, posTemp);
{
sPt.Format(_T("第%d点"), i + 1);
xmlTree.SetAttribute(posTemp, _T("name"), sPt);
sX = DoubleToString(ptTemp.x, nPre);
sY = DoubleToString(ptTemp.y, nPre);
sZ = DoubleToString(ptTemp.z, nPre);
sPt.Format(_T("%s,%s,%s"), sX, sY, sZ);
xmlTree.SetItemText(posTemp, sPt);
}
sPt.Format(_T("Ang_%d"), i + 1);
posTemp = xmlTree.Insert(sPt, posIn, posTemp);
{
sPt.Format(_T("圆心角%d"), i + 1);
xmlTree.SetAttribute(posTemp, _T("name"), sPt);
sPt = DoubleToString(polyIn.GetBulge(i), nPre);
xmlTree.SetItemText(posTemp, sPt);
}
}
}
POSITION posOut = xmlTree.Insert(_T("PolyOut"), posRoot, posIn);
{
xmlTree.SetAttribute(posOut, _T("name"), _T("外侧线"));
POSITION posTemp = NULL;
int nLen = polyOut.Length();
CString sPt, sX, sY, sZ;
XPoint ptTemp;
for (int i = 0; i < nLen; ++i)
{
ptTemp = *polyOut[i];
sPt.Format(_T("Point_%d"), i + 1);
posTemp = xmlTree.Insert(sPt, posOut, posTemp);
{
sPt.Format(_T("第%d点"), i + 1);
xmlTree.SetAttribute(posTemp, _T("name"), sPt);
sX = DoubleToString(ptTemp.x, nPre);
sY = DoubleToString(ptTemp.y, nPre);
sZ = DoubleToString(ptTemp.z, nPre);
sPt.Format(_T("%s,%s,%s"), sX, sY, sZ);
xmlTree.SetItemText(posTemp, sPt);
}
sPt.Format(_T("Ang_%d"), i + 1);
posTemp = xmlTree.Insert(sPt, posOut, posTemp);
{
sPt.Format(_T("圆心角%d"), i + 1);
xmlTree.SetAttribute(posTemp, _T("name"), sPt);
sPt = DoubleToString(polyIn.GetBulge(i), nPre);
xmlTree.SetItemText(posTemp, sPt);
}
}
}
POSITION posInHeight = xmlTree.Insert(_T("InHeight"), posRoot, posOut);
{
xmlTree.SetAttribute(posInHeight, _T("name"), _T("截面内侧高度"));
CString sTemp = DoubleToString(m_dInHeight, nPre);
xmlTree.SetItemText(posInHeight, sTemp);
}
POSITION posOutHeight = xmlTree.Insert(_T("OutHeight"), posRoot, posInHeight);
{
xmlTree.SetAttribute(posOutHeight, _T("name"), _T("截面外侧高度"));
CString sTemp = DoubleToString(m_dInHeight, nPre);
xmlTree.SetItemText(posOutHeight, sTemp);
}
POSITION posItemId = xmlTree.Insert(_T("Object_ID"), posRoot, posOutHeight);
{
xmlTree.SetAttribute(posItemId, _T("name"), _T("ID"));
xmlTree.SetAttribute(posItemId, _T("comment"), _T("散水ID"));
CString sText;
sText.Format(_T("%ld"), objectId().asOldId());
xmlTree.SetItemText(posItemId, sText);
}
CString sXml = xmlTree.GetXml();
int nIdex = -1;
nIdex = sXml.Find(_T("</ATS_APRON>"));
if (nIdex != -1)
{
CString sTemp = TDbPolyCurveEnt::GetXml(mat);
sXml.Insert(nIdex, sTemp);
}
return sXml;
}
void InitDbApron(BOOL bTrue)
{
if (bTrue)
{
TDbApron::rxInit();
acrxBuildClassHierarchy();
TDbApron::InitMatchProtocol(TRUE);
}
else
{
TDbApron::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbApron::desc());
}
}