Files
envi-code/SourceCode/Code2026/Dimension/AecDbSymbArrow.cpp
T

1519 lines
42 KiB
C++
Raw Normal View History

2026-10-04 00:04:20 +08:00
#include "StdAfx.h"
2026-09-28 15:28:50 +08:00
#include "AecDbSymbArrow.h"
#include "ADSGePointDir2d.h"
#include "aECdBtEXT.h"
#include "PushProperty.h"
#include "DimOptionData.h"
const Adesk::UInt8 AecXDbSymbArrow::g_nVersion = 5;
ACRX_DXF_DEFINE_MEMBERS(AecXDbSymbArrow, AecXDbSymbWithText, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
2026-10-04 00:04:20 +08:00
1, AEC_JIANTOUYINZHU, "AEC_JIANTOUYINZHU|缺乏上华解释器, 请下载上华软件|网址: www.shanghuasoft.com");
2026-09-28 15:28:50 +08:00
AecXDbSymbArrow::AecXDbSymbArrow()
{
m_nTextHeight = 3.5;
m_nFlag = kAtSide;
m_nArrowSize = g_Option::instance().g_nArrowLen;
m_nType = kArrow;
2026-10-04 00:04:20 +08:00
m_dText2BaseRatio = -1000; // 使用GlobalFunc::DocGetText2BaseRatio,sg add 081111
2026-09-28 15:28:50 +08:00
m_bShowText2 = FALSE; // sg add 090106
}
AecXDbSymbArrow::~AecXDbSymbArrow()
{
}
BOOL AecXDbSymbArrow::IsValid() const
{
//BOOL bRet = AecXDbSymbWithText::IsValid();
//if (!bRet)
// return bRet;
BOOL bRet = (m_poly.Length() > 1 && !m_poly.IsClosed());
return bRet;
}
2026-10-04 00:04:20 +08:00
// 提供对格式刷的支持
2026-09-28 15:28:50 +08:00
void AecXDbSymbArrow::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
AssertWriteEnabled();
AecXDbSymbWithText::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
AecXDbSymbArrow *pSrc = AecXDbSymbArrow::cast(pSrcEntity);
if (pSrc != NULL)
{
2026-10-04 00:04:20 +08:00
m_nFlag = pSrc->m_nFlag; // 控制标记
2026-09-28 15:28:50 +08:00
m_nArrowSize = pSrc->m_nArrowSize;
m_nType = pSrc->m_nType;
2026-10-04 00:04:20 +08:00
m_dText2BaseRatio = pSrc->m_dText2BaseRatio; // 文字距基线系数,sg add 081111
2026-09-28 15:28:50 +08:00
}
}
2026-10-04 00:04:20 +08:00
// 从DWG读入数据:
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus AecXDbSymbArrow::dwgInFields(AcDbDwgFiler* pFiler)
{
AssertWriteEnabled();
Acad::ErrorStatus es = AecXDbSymbWithText::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;
}
Adesk::UInt8 nTemp;
pFiler->readItem(&nTemp);
m_nFlag = (TArTextAlign)nTemp;
GlobalFunc::ReadString(pFiler, m_sText);
2026-10-04 00:04:20 +08:00
// modify by lgy 20111227,根据9.0需求,将文字夹点转换为实体坐标
2026-09-28 15:28:50 +08:00
// pFiler->readItem((AcGePoint3d *)&m_ptText);
ADSGePoint3d ptText;
pFiler->readItem((AcGePoint3d *)&ptText);
m_poly.Reset();
GlobalFunc::ReadPoly2D(pFiler, m_poly);
if (nVer > 1)
pFiler->readItem(&m_nArrowSize);
if (nVer > 2)
{
pFiler->readItem(&nTemp);
m_nType = (TArrowType)nTemp;
}
2026-10-04 00:04:20 +08:00
if (nVer > 3) // sg add 081111,sg add090106,8.0版本为4
2026-09-28 15:28:50 +08:00
{
pFiler->readItem(&m_dText2BaseRatio);
pFiler->readItem(&m_bShowText2);
GlobalFunc::ReadString(pFiler, m_sText2);
2026-10-04 00:04:20 +08:00
// modify by lgy 20111230 读取文字2的位置点时要根据版本号判断是否要转换成ECS坐标
2026-09-28 15:28:50 +08:00
// pFiler->readItem((AcGePoint3d *)&m_ptText2);
ADSGePoint3d ptText2;
pFiler->readItem((AcGePoint3d *)&ptText2);
2026-10-04 00:04:20 +08:00
if (nVer > 4) // 9.0版本
2026-09-28 15:28:50 +08:00
{
m_ptText2 = ptText2;
}
2026-10-04 00:04:20 +08:00
else // 如果是9.0以前版本需要转换成ECS坐标
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
SetText2Location(ptText2); // 转换为ECS
2026-09-28 15:28:50 +08:00
}
}
else
{
m_dText2BaseRatio = -1000;
m_bShowText2 = FALSE;
}
2026-10-04 00:04:20 +08:00
if (nVer > 4) // 9.0版本
2026-09-28 15:28:50 +08:00
{
m_ptText = ptText;
}
2026-10-04 00:04:20 +08:00
else // 如果是9.0以前版本需要转换成ECS坐标
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
SetTextLocation(ptText); // 转换为ECS
2026-09-28 15:28:50 +08:00
}
return pFiler->filerStatus();
}
Acad::ErrorStatus AecXDbSymbArrow::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = AecXDbSymbWithText::dwgOutFields(pFiler);
if (es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem((Adesk::UInt8)m_nFlag);
pFiler->writeString(m_sText);
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,低于9.0版本的时候要保持为wcs坐标
2026-09-28 15:28:50 +08:00
// pFiler->writeItem((const AcGePoint3d &)m_ptText);
//if (g_nSaveTArchVer > 8)
//{
pFiler->writeItem((const AcGePoint3d &)m_ptText);
//}
//else
//{
// ADSGePoint3d pt = GetTextLocation();
// pFiler->writeItem((const AcGePoint3d &)pt);
//}
GlobalFunc::WritePoly2D(pFiler, m_poly);
pFiler->writeItem(m_nArrowSize);
//if (g_nSaveTArchVer > 6)
pFiler->writeItem((Adesk::UInt8)m_nType);
2026-10-04 00:04:20 +08:00
//if (g_nSaveTArchVer > 7) // sg add 081111,sg add090106,8.0版本
2026-09-28 15:28:50 +08:00
//{
pFiler->writeItem(m_dText2BaseRatio);
pFiler->writeItem(m_bShowText2);
pFiler->writeItem(m_sText2);
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,低于9.0版本的时候要保持为wcs坐标
2026-09-28 15:28:50 +08:00
// pFiler->writeItem((const AcGePoint3d &)m_ptText2);
//if (g_nSaveTArchVer > 8)
//{
pFiler->writeItem((const AcGePoint3d &)m_ptText2);
//}
//else
//{
// ADSGePoint3d pt = GetText2Location();
// pFiler->writeItem((const AcGePoint3d &)pt);
//}
//}
return pFiler->filerStatus();
}
Acad::ErrorStatus AecXDbSymbArrow::dxfInFields(AcDbDxfFiler* pFiler)
{
AssertWriteEnabled();
Acad::ErrorStatus es = AecXDbSymbWithText::dxfInFields(pFiler);
if (es != Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("AecXDbSymbArrow"))) {
return Acad::eBadDxfSequence;
}
double nArSize = m_nArrowSize;
TCHAR * pName = NULL;
Adesk::Int16 nFlag = m_nFlag;
Adesk::Int16 nType = m_nType;
ADSGePoint3d ptText;
Adesk::UInt32 fieldsFlags = 0;
PtrList<ADSGePoint3d> lstVertexes;
PtrList<double> lstAngles;
resbuf rb;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfInt16:
nFlag = rb.resval.rint;
fieldsFlags |= 0x1;
break;
case AcDb::kDxfInt16 + 1:
nType = rb.resval.rint;
fieldsFlags |= 0x10;
break;
case AcDb::kDxfXCoord:
lstVertexes.Append(new ADSGePoint3d(rb.resval.rpoint));
break;
case AcDb::kDxfXCoord + 1:
ptText = rb.resval.rpoint;
fieldsFlags |= 0x2;
break;
case AcDb::kDxfText:
acutUpdString(rb.resval.rstring, pName);
fieldsFlags |= 0x04;
free(rb.resval.rstring);
break;
case AcDb::kDxfReal:
fieldsFlags |= 0x08;
nArSize = rb.resval.rreal;
break;
case AcDb::kDxfAngle:
lstAngles.Append(new double(rb.resval.rreal));
break;
//fall through intentional
default:
// An unrecognized group. Push it back so that
// the subclass can read it again.
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
// At this point the es variable must contain eEndOfFile
// - either from readResBuf() or from pushback. If not,
// it indicates that an error happened and we should
// return immediately.
//
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
if (!(fieldsFlags & 0x02)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: %d"), 10);
return Acad::eMissingDxfField;
}
if (lstVertexes.Length() < 2) {
2026-10-04 00:04:20 +08:00
pFiler->setError(_T("\n顶点个数%d太少了!"), lstVertexes.Length());
2026-09-28 15:28:50 +08:00
return Acad::eMissingDxfField;
}
if (lstVertexes.Length() != lstAngles.Length()) {
2026-10-04 00:04:20 +08:00
pFiler->setError(_T("\n顶点个数%d和角度个数%d不匹配!"), lstVertexes.Length(),
2026-09-28 15:28:50 +08:00
lstAngles.Length());
return Acad::eMissingDxfField;
}
if (fieldsFlags & 0x01)
m_nFlag = (TArTextAlign)nFlag;
m_ptText = ptText;
if (fieldsFlags & 0x04) {
m_sText = pName;
acutDelString(pName);
}
if (fieldsFlags & 0x08)
m_nArrowSize = nArSize;
if (fieldsFlags & 0x10)
m_nType = (TArrowType)nType;
m_poly.Reset();
for (int i = 0; i < lstVertexes.Length(); i++) {
m_poly.AppendNode(*lstVertexes[i], *lstAngles[i]);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus AecXDbSymbArrow::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = AecXDbSymbWithText::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("AecXDbSymbArrow"));
assert(es == Acad::eOk);
pFiler->writeInt16(AcDb::kDxfInt16, (Adesk::UInt16)m_nFlag);
pFiler->writePoint2d(AcDb::kDxfXCoord + 1, m_ptText.AsAcGePoint2d());
pFiler->writeString(AcDb::kDxfText, m_sText);
pFiler->writeDouble(AcDb::kDxfReal + 1, m_nArrowSize);
for (int i = 0; i < m_poly.Length(); i++) {
double nAng = m_poly.GetBulge(i);
ADSGePoint3d pt = m_poly[i];
pFiler->writePoint2d(AcDb::kDxfXCoord, pt.AsAcGePoint2d());
pFiler->writeDouble(AcDb::kDxfAngle, nAng);
}
pFiler->writeInt16(AcDb::kDxfInt16 + 1, (Adesk::UInt16)m_nType);
return pFiler->filerStatus();
}
// -----------------------------------------------------------------------
// Overriden functions for edit
// to do:
2026-10-04 00:04:20 +08:00
// 允许通过夹点改变边界
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus AecXDbSymbArrow::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
int nVertexCount = m_poly.Length();
for (int i = 0; i < nVertexCount; i++)
{
gripPoints.append(m_poly[i]);
}
int nEdgeNum = m_poly.TotalSegments();
for (i = 0; i < nEdgeNum; i++)
{
GeCurveSegment seg;
m_poly.Nth(i, seg);
ADSGePoint3d ptMid = seg.MidPoint();
2026-10-04 00:04:20 +08:00
gripPoints.append(ptMid); // 边上的夹点
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
// moidfy by lgy 20111227 基线上方文字位置点,WCS
2026-09-28 15:28:50 +08:00
// gripPoints.append(m_ptText);
ADSGePoint3d ptText = GetTextLocation();
gripPoints.append(ptText);
2026-10-04 00:04:20 +08:00
if (m_nFlag != kAtSide && m_bShowText2) // 不在线端,且显示文字2
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
// modify by lgy 20111227 基线下方位置点, WCS
// gripPoints.append(m_ptText2); // sg add 090106,增加文字2的夹点
2026-09-28 15:28:50 +08:00
ptText = GetText2Location();
gripPoints.append(ptText);
}
return Acad::eOk;
}
Acad::ErrorStatus AecXDbSymbArrow::subGetGripPoints(AcDbGripDataPtrArray & grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d & curViewDir, const int bitflags) const
{
return Acad::eNotImplementedYet;
}
// stretch points is diffrent from grep points, with no midpoint included
Acad::ErrorStatus
AecXDbSymbArrow::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
int nVertexCount = m_poly.Length();
for (int i = 0; i < nVertexCount; i++)
{
ADSGePoint3d pt = m_poly[i];
stretchPoints.append(pt);
}
2026-10-04 00:04:20 +08:00
// moidfy by lgy 20111227 基线上方文字位置点,WCS
2026-09-28 15:28:50 +08:00
// stretchPoints.append(m_ptText);
ADSGePoint3d ptText = GetTextLocation();
stretchPoints.append(ptText);
2026-10-04 00:04:20 +08:00
if (m_nFlag != kAtSide && m_bShowText2) // 不在线端,且显示文字2
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
// modify by lgy 20111227 基线下方位置点, WCS
// stretchPoints.append(m_ptText2); // sg add 090106,增加文字2的夹点
2026-09-28 15:28:50 +08:00
ptText = GetText2Location();
stretchPoints.append(ptText);
}
return Acad::eOk;
}
// Active when being rotated, scaled, moved, etc.
// Scale is disabled here
Acad::ErrorStatus AecXDbSymbArrow::subTransformBy(const AcGeMatrix3d& xform)
{
AssertWriteEnabled();
2026-10-04 00:04:20 +08:00
// delete by lgy 20111229,转换为ECS坐标系后,文字位置点就不需要变换了
2026-09-28 15:28:50 +08:00
// ADSGePoint3d ptDefault = GetDefaultTextLocation();
// BOOL bIsDefault = (m_ptText.Distance2d(ptDefault)<g_Option::instance()._DIST_SNAP);
// ADSGePoint3d ptDefault2 = GetDefaultText2Location(); // sg add 090106
// BOOL bIsDefault2 = (m_ptText2.Distance(ptDefault2) < g_Option::instance()._DIST_SNAP);
2026-10-04 00:04:20 +08:00
// sg modify 120209,考虑到如果是镜像变化,就要修改文字位置点
// 首先得到WCS点,然后进行坐标变化,然后再转换为ECS点存储
2026-09-28 15:28:50 +08:00
ADSGePoint3d ptUpText = GetTextLocation(),
ptDownText;
if (m_nFlag != kAtSide && m_bShowText2)
{
ptDownText = GetText2Location();
}
AecXDbSymbWithText::subTransformBy(xform);
ads_matrix mat;
GlobalFunc::AsAdsMatrix(xform, mat);
for (int i = 0; i < m_poly.Length(); i++)
m_poly[i]->TransformBy(mat);
2026-10-04 00:04:20 +08:00
if (GlobalFunc::IsMirrorMatrix(mat)) // 镜像
2026-09-28 15:28:50 +08:00
{
for (int m = 0; m < m_poly.Length(); m++)
{
m_poly.SetBulge(m, -m_poly.GetBulge(m));
}
2026-10-04 00:04:20 +08:00
// 标记是否发生了Y方向的镜像
2026-09-28 15:28:50 +08:00
BOOL bMirrorByY = FALSE;
{
ADSGePoint3d ptOrg(0, 0), ptY1(0, 2000), ptY2(0, -2000), ptY3(0, 0);
ptOrg.TransformBy(mat);
ptY1.TransformBy(mat); // (0, -2000)
ptY2.TransformBy(mat); // (0, 2000)
ptOrg.Mirror(ptY1, ptY3); // (0, 2000)
bMirrorByY = ptY2 == ptY3;
}
2026-10-04 00:04:20 +08:00
// 如果是Y方向的镜像,并且是齐线中或者是齐线端,不修改文字位置
2026-09-28 15:28:50 +08:00
if (m_nFlag != kAtSide && bMirrorByY)
return Acad::eOk;
2026-10-04 00:04:20 +08:00
// 修改文字位置
2026-09-28 15:28:50 +08:00
ptUpText.TransformBy(mat);
SetTextLocation(ptUpText);
if (m_nFlag != kAtSide && m_bShowText2)
{
ptDownText.TransformBy(mat);
SetText2Location(ptDownText);
}
}
2026-10-04 00:04:20 +08:00
// delete by lgy 20111229,转换为ECS坐标系后,文字位置点就不需要变换了
2026-09-28 15:28:50 +08:00
// if (bIsDefault)
// m_ptText = GetDefaultTextLocation();
// else
// m_ptText.TransformBy(mat);
//
// if (bIsDefault2) // sg add 090106
// m_ptText2 = GetDefaultText2Location();
// else
// m_ptText2.TransformBy(mat);
return Acad::eOk;
}
2026-10-04 00:04:20 +08:00
// 功能: 夹点操作
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus AecXDbSymbArrow::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
AssertWriteEnabled();
2026-10-04 00:04:20 +08:00
// delete by lgy 20111229,转换为ECS坐标系后,文字位置点就不需要变换了
2026-09-28 15:28:50 +08:00
// BOOL bMoveText = FALSE,
// bMoveText2 = FALSE; // sg add 090106
// BOOL bAtDefault = (m_ptText.Distance2d(GetDefaultTextLocation()) < g_Option::instance()._DIST_SNAP),
// bAtDefault2 = (m_ptText2.Distance2d(GetDefaultText2Location()) < g_Option::instance()._DIST_SNAP); // sg add 090106
ADSGePoint3d vtOffset(offset[0], offset[1]);
int nVertexCount = m_poly.Length(),
nTotalEdge = nVertexCount - 1;
for (int i = 0; i < indices.length(); i++)
{
int idx = indices[i];
if (idx < nVertexCount) // Move vertex
{
*m_poly[idx] += vtOffset;
2026-10-04 00:04:20 +08:00
// delete by lgy 20111229,转换为ECS坐标系后,文字位置点就不需要变换了
2026-09-28 15:28:50 +08:00
// if (idx == 0)
//{
// m_ptText += vtOffset;
// m_ptText2 += vtOffset; // sg add 090106
//}
}
2026-10-04 00:04:20 +08:00
else if (idx - nVertexCount < nTotalEdge) // 移动边
2026-09-28 15:28:50 +08:00
{
int nEdgeIndex = idx - nVertexCount;
int nTotalEdge = m_poly.TotalSegments();
GeDirectionCurve cv;
m_poly.Nth(nEdgeIndex, cv);
ASSERT(!!cv);
if (cv.Is(CURVE_LINE)) // Move
{
GeLine ln = cv.GetLine();
ln.StartPoint() += vtOffset;
ln.EndPoint() += vtOffset;
ln.SetLineFlag(LS_INFINITE);
GeDirectionCurve prevSeg, nextSeg;
int nPrev = nEdgeIndex - 1,
nNext = nEdgeIndex + 1;
ADSGePoint3d ptStart, ptEnd;
BOOL bUpdateIt = TRUE;
2026-10-04 00:04:20 +08:00
if (nPrev >= 0 && nPrev < nTotalEdge) // 更新起点
2026-09-28 15:28:50 +08:00
{
m_poly.Nth(nPrev, prevSeg);
prevSeg.SetLineFlag(LS_INFINITE);
ADSGePoint3d ptInt[2];
int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
if (nIntNum == 1)
ptStart = ptInt[0];
else if (nIntNum == 2)
{
ptStart = GeLine(ptInt[0], ptInt[1]).NearPoint(ln.StartPoint());
}
else
bUpdateIt = FALSE;
}
else
{
ptStart = *m_poly[nEdgeIndex] + vtOffset;
2026-10-04 00:04:20 +08:00
// delete by lgy 20111229,转换为ECS坐标系后,文字位置点就不需要变换了
2026-09-28 15:28:50 +08:00
// m_ptText += vtOffset;
// m_ptText2 += vtOffset; // sg add 090106
}
2026-10-04 00:04:20 +08:00
if (nNext >= 0 && nNext < nTotalEdge) // 更新下一点
2026-09-28 15:28:50 +08:00
{
m_poly.Nth(nNext, nextSeg);
nextSeg.SetLineFlag(LS_INFINITE);
ADSGePoint3d ptInt[2];
int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
if (nIntNum == 1)
ptEnd = ptInt[0];
else if (nIntNum == 2)
ptEnd = GeLine(ptInt[0], ptInt[1]).NearPoint(ln.EndPoint());
else
bUpdateIt = FALSE;
}
else
{
ptEnd = *m_poly[nEdgeIndex + 1] + vtOffset;
}
if (bUpdateIt)
{
double nPrevBulge = 0.0,
nNextBulge = 0.0;
if (fabs(prevSeg.GetBulge()) > 1.0E-5)
{
GeArc prevArc = prevSeg.GetArc();
double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.StartPoint());
double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart);
if (prevSeg.IsMinusArc())
nPrevBulge = -GlobalFunc::AngleRangeTo2PI(nAngBeg - nAngEnd);
else
nPrevBulge = GlobalFunc::AngleRangeTo2PI(nAngEnd - nAngBeg);
}
if (fabs(nextSeg.GetBulge()) > 1.0E-5)
{
GeArc nextArc = nextSeg.GetArc();
double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd);
double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.EndPoint());
if (nextSeg.IsMinusArc())
nNextBulge = -GlobalFunc::AngleRangeTo2PI(nAngBeg - nAngEnd);
else
nNextBulge = GlobalFunc::AngleRangeTo2PI(nAngEnd - nAngBeg);
}
*m_poly[nEdgeIndex] = ptStart;
if (nNext >= 0 && nNext < m_poly.Length())
{
*m_poly[nNext] = ptEnd;
m_poly.SetBulge(nNext, nNextBulge);
}
if (nPrev >= 0 && nPrev < m_poly.Length())
m_poly.SetBulge(nPrev, nPrevBulge);
}
}
else // Change Arc Segment--bulge
{
ADSGePoint3d ptMid = cv.MidPoint();
ADSGePoint3d ptMidNew = ptMid + vtOffset;
GeArc arNew(cv.StartPoint(), ptMidNew, cv.EndPoint());
2026-10-04 00:04:20 +08:00
if (!!arNew) // 新的弧有效
2026-09-28 15:28:50 +08:00
{
GeCurveSegment cvLine(cv.StartPoint(), cv.EndPoint(), 0.0);
int nSideOld = cvLine.OnWhichSide(ptMid);
int nSideNew = cvLine.OnWhichSide(ptMidNew);
double nSignal = cv.GetBulge() / fabs(cv.GetBulge());
if (nSideOld == nSideNew)
m_poly.SetBulge(nEdgeIndex, nSignal * arNew.Bulge());
else
m_poly.SetBulge(nEdgeIndex, -nSignal * arNew.Bulge());
}
}
}
2026-10-04 00:04:20 +08:00
else if (idx - nVertexCount == nTotalEdge) // 移动文字
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
// modify by lgy 20111229 移动文字时要将ecs转换为wcs
2026-09-28 15:28:50 +08:00
// m_ptText += vtOffset;
//bMoveText = TRUE;
ADSGePoint3d ptWcsText = GetTextLocation();
ptWcsText += vtOffset;
SetTextLocation(ptWcsText);
}
else if (m_nFlag != kAtSide && m_bShowText2 && idx == nVertexCount + nTotalEdge + 1)
{
2026-10-04 00:04:20 +08:00
// modify by lgy 20111229 移动文字时要将ecs转换为wcs
// m_ptText2 += vtOffset; // 移动文字位置2,sg add 090106
2026-09-28 15:28:50 +08:00
//bMoveText2 = TRUE;
ADSGePoint3d ptWcsText = GetText2Location();
ptWcsText += vtOffset;
SetText2Location(ptWcsText);
}
}
2026-10-04 00:04:20 +08:00
// delete by lgy 20111229,转换为ECS坐标系后,文字位置点就不需要变换了
2026-09-28 15:28:50 +08:00
// if (bAtDefault && !bMoveText)
// m_ptText = GetDefaultTextLocation();
// if (bAtDefault2 && !bMoveText2)
// m_ptText2 = GetDefaultText2Location();
return Acad::eOk;
}
2026-10-04 00:04:20 +08:00
// 功能: 夹点操作
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus AecXDbSymbArrow::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
AssertWriteEnabled();
ADSGePoint3d vtOffset(offset[0], offset[1]);
2026-10-04 00:04:20 +08:00
// add by lgy 111231,增加bTextPtStrech,控制是否是单独移动文字,false时表示跟poly一起拉伸
2026-09-28 15:28:50 +08:00
bool bTextPtStrech = true;
int nVertexCount = m_poly.Length();
for (int i = 0; i < indices.length(); i++)
{
int idx = indices[i];
if (idx < nVertexCount) // Move vertex
{
*m_poly[idx] += vtOffset;
2026-10-04 00:04:20 +08:00
// modify by lgy 111231,判断是否偏移文字位置基点
2026-09-28 15:28:50 +08:00
if (nVertexCount > 1 && (idx == 0 || idx == 1))
bTextPtStrech = false;
continue;
}
// else if (idx == nVertexCount)
// m_ptText += vtOffset;
// else if (m_nFlag!=kAtSide && m_bShowText2 && idx==nVertexCount+1) // sg add 090106
// m_ptText2 += vtOffset;
2026-10-04 00:04:20 +08:00
if (bTextPtStrech) // 单独拉伸文字夹点
2026-09-28 15:28:50 +08:00
{
if (idx == nVertexCount)
{
ADSGePoint3d pt = GetTextLocation();
pt += vtOffset;
SetTextLocation(pt);
}
else if (m_nFlag != kAtSide && m_bShowText2 && idx == nVertexCount + 1)
{
ADSGePoint3d pt = GetText2Location();
pt += vtOffset;
SetText2Location(pt);
}
}
}
return Acad::eOk;
}
2026-10-04 00:04:20 +08:00
// 取得夹点说明
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus AecXDbSymbArrow::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es = Acad::eOk;
int nVertexCount = m_poly.Length();
if (i < nVertexCount) // Move vertex
{
2026-10-04 00:04:20 +08:00
cs.Format(_T("移动第%d个顶点"), i + 1);
2026-09-28 15:28:50 +08:00
}
else // Move Edge or Shape
{
int nEdgeIndex = i - nVertexCount,
nTotalEdge = m_poly.TotalSegments();
2026-10-04 00:04:20 +08:00
if (nEdgeIndex < nTotalEdge) // 移动边
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
cs.Format(_T("移动第%d条边"), nEdgeIndex + 1);
2026-09-28 15:28:50 +08:00
}
else if (nEdgeIndex == nTotalEdge)
2026-10-04 00:04:20 +08:00
cs = _T("移动文字");
2026-09-28 15:28:50 +08:00
else if (m_nFlag != kAtSide && m_bShowText2 && nEdgeIndex == nTotalEdge + 1) // sg add 090106
{
2026-10-04 00:04:20 +08:00
cs = _T("移动文字2");
2026-09-28 15:28:50 +08:00
}
}
return es;
}
Acad::ErrorStatus
AecXDbSymbArrow::Draw2d(AcGiDraw &dc) const
{
assertReadEnabled();
if (!IsValid())
return Acad::eInvalidInput;
GlobalFunc::_LoadConfig();
if (Has2DBuffer() && !dc.IsDragging())
{
dc.SetColor(colorIndex());
dc.SetLayer(layerId());
BaseEx::_Draw2DBuffers(dc, true);
return Acad::eOk;
}
double nTextRot = 0;
Acad::ErrorStatus es = Acad::eOk;
if (!!m_sText || g_Option::instance().g_bExplodeSubText)
{
AecXDbText text;
text.setPropertiesFrom(this);
text.SetHeight(m_nTextHeight);
text.SetPScale(GetPScale());
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
2026-09-28 15:28:50 +08:00
// text.SetLocation(m_ptText);
2026-10-04 00:04:20 +08:00
text.SetLocation(GetTextLocation()); //文字夹点位置 WCS
2026-09-28 15:28:50 +08:00
text.SetText(m_sText);
text.SetStyleId(m_idTextStyle);
2026-10-04 00:04:20 +08:00
//if (dc.IsExportTch4()) // sg modify 090608,sg modify 090728
2026-09-28 15:28:50 +08:00
//{
2026-10-04 00:04:20 +08:00
// // sg add 120313,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理
2026-09-28 15:28:50 +08:00
// // if (!!m_idTextLayer)
// if (g_nSymbTextT3Layer == 1 && !!m_idTextLayer)
2026-10-04 00:04:20 +08:00
// text.setLayer(m_idTextLayer); // 文字层
2026-09-28 15:28:50 +08:00
// else
2026-10-04 00:04:20 +08:00
// text.setColorIndex(m_colorText); // 文字和标注放在同一层,文字的颜色为白色
2026-09-28 15:28:50 +08:00
//}
//else
2026-10-04 00:04:20 +08:00
text.setColorIndex(m_colorText); // sg add 090608,文字和标注放在同一层,文字的颜色为白色
2026-09-28 15:28:50 +08:00
text.SetAlignment(GetTextAlignment());
// text.SetRotation(m_nLayoutRotation);
if (m_nFlag != kAtSide)
{
2026-10-04 00:04:20 +08:00
// sg add 090624,解决线上、下文字距离文字基线距离相等的问题
2026-09-28 15:28:50 +08:00
if (m_bShowText2)
{
ADSGePoint3d ptMin, ptMax;
2026-10-04 00:04:20 +08:00
text.SetLayoutRotation(0.0); // 获得外包框的时候,一定要不考虑布局转角、文字转角
2026-09-28 15:28:50 +08:00
text.GetExtents2d(ptMin, ptMax);
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
2026-09-28 15:28:50 +08:00
// ADSGePoint3d ptDraw = m_ptText;
ADSGePoint3d ptDraw = GetTextLocation();
2026-10-04 00:04:20 +08:00
// sg add 090819,防止批量转旧时,无法得到文字外包围框
2026-09-28 15:28:50 +08:00
if (ptMin != ADSGePoint3d() || ptMax != ADSGePoint3d())
{
double dTmp = ptDraw.y - ptMin.y,
dRotation = GlobalFunc::ChangeAngleTo1_4(Wcs2Layout(GetTextBaseDir()));
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
2026-09-28 15:28:50 +08:00
// ads_polar(m_ptText, dRotation+PI/2, dTmp, ptDraw);
ads_polar(ptDraw, dRotation + PI / 2, dTmp, ptDraw);
}
text.SetLocation(ptDraw);
text.SetLayoutRotation(m_nLayoutRotation);
}
// double nTextRot=GlobalFunc::ChangeAngleTo1_4(GetTextBaseDir()-m_nLayoutRotation);
// text.SetRotation(GlobalFunc::AngleRangeTo2PI(nTextRot+m_nLayoutRotation));
text.SetRotation(GlobalFunc::ChangeAngleTo1_4(Wcs2Layout(GetTextBaseDir())));
}
nTextRot = text.GetLayoutRotation() + text.GetRotation();
PushProperty vProp(&text, dc);
//if (dc.IsFullExplode())
// text.ExplodeOrDraw2d(dc);
//else
// dc.DrawEntity(text);
DrawBaseEx(dc, text);
}
2026-10-04 00:04:20 +08:00
if (m_nFlag != kAtSide && m_bShowText2) // 显示文字2,sg add 090106
2026-09-28 15:28:50 +08:00
{
AecXDbText text;
text.setPropertiesFrom(this);
text.SetHeight(m_nTextHeight);
text.SetPScale(GetPScale());
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
// text.SetLocation(m_ptText2); //文字夹点位置 WCS
2026-09-28 15:28:50 +08:00
text.SetLocation(GetText2Location());
text.SetText(m_sText2);
text.SetStyleId(m_idTextStyle);
//if (dc.IsExportTch4()) // sg modify 090608
//{
2026-10-04 00:04:20 +08:00
// // sg add 120313,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理
2026-09-28 15:28:50 +08:00
// // if (!!m_idTextLayer)
// if (g_nSymbTextT3Layer == 1 && !!m_idTextLayer)
2026-10-04 00:04:20 +08:00
// text.setLayer(m_idTextLayer); // 文字层
2026-09-28 15:28:50 +08:00
// else
2026-10-04 00:04:20 +08:00
// text.setColorIndex(m_colorText); // 文字和标注放在同一层,文字的颜色为白色
2026-09-28 15:28:50 +08:00
//}
//else
2026-10-04 00:04:20 +08:00
text.setColorIndex(m_colorText); // sg add 090608,文字和标注放在同一层,文字的颜色为白色
2026-09-28 15:28:50 +08:00
text.SetAlignment(GetText2Alignment());
2026-10-04 00:04:20 +08:00
// sg modify 090623,解决线下文字距离文字基线较远的问题
2026-09-28 15:28:50 +08:00
ADSGePoint3d ptMin, ptMax;
2026-10-04 00:04:20 +08:00
text.SetLayoutRotation(0.0); // 获得外包框的时候,一定要不考虑布局转角、文字转角
2026-09-28 15:28:50 +08:00
text.GetExtents2d(ptMin, ptMax);
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
2026-09-28 15:28:50 +08:00
// ADSGePoint3d ptDraw = m_ptText2;
ADSGePoint3d ptDraw = GetText2Location();
double dRotation = GlobalFunc::ChangeAngleTo1_4(Wcs2Layout(GetTextBaseDir()));
2026-10-04 00:04:20 +08:00
// sg add 090819,防止批量转旧时,无法得到文字外包围框
2026-09-28 15:28:50 +08:00
if (ptMin != ADSGePoint3d() || ptMax != ADSGePoint3d())
{
double dTmp = ptDraw.y - ptMax.y;
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
2026-09-28 15:28:50 +08:00
// ads_polar(m_ptText2, dRotation+PI/2, dTmp, ptDraw);
ads_polar(ptDraw, dRotation + PI / 2, dTmp, ptDraw);
}
text.SetLocation(ptDraw);
text.SetLayoutRotation(m_nLayoutRotation);
text.SetRotation(dRotation);
PushProperty vProp(&text, dc);
//if (dc.IsFullExplode())
// text.ExplodeOrDraw2d(dc);
//else
// dc.DrawEntity(text);
DrawBaseEx(dc, text);
}
2026-10-04 00:04:20 +08:00
TArrowType nType = GetArrowType(); // sg modify 090105,箭头样式
2026-09-28 15:28:50 +08:00
// if (GetArrowType() == kArrow)
2026-10-04 00:04:20 +08:00
if (nType == kArrow) // 箭头
2026-09-28 15:28:50 +08:00
{
AcDbPolyline pline;
GlobalFunc::PolyConvert(m_poly, pline);
int nSegNum = m_poly.TotalSegments();
GeDirectionCurve cv;
m_poly.Nth(nSegNum - 1, cv);
ADSGePointDir2d ptDir2d;
cv.Polar(m_nArrowSize * GetPScale(), ptDir2d, FALSE);
pline.addVertexAt(m_poly.Length(), ptDir2d);
pline.setWidthsAt(m_poly.Length() - 1, 0.0, m_nArrowSize * g_Option::instance().g_nArrowWidth / g_Option::instance().g_nArrowLen * GetPScale());
pline.setPropertiesFrom(this);
//dc.Polyline(pline);
DrawPline(dc, pline);
}
// else // sg modify 090105
2026-10-04 00:04:20 +08:00
else if (nType == kHalfArrow) // 半箭头
2026-09-28 15:28:50 +08:00
{
int nSegNum = m_poly.TotalSegments();
GeDirectionCurve cv;
m_poly.Nth(nSegNum - 1, cv);
ADSGePointDir2d ptDir2d;
cv.Polar(m_nArrowSize * GetPScale(), ptDir2d, FALSE);
GePoly2D poly(1);
poly.AppendNode(*m_poly.Tail());
poly.AppendNode(ptDir2d);
ADSGePoint3d vt1(ADSGePoint3d(), nTextRot + PI / 2, 1),
vt2(ADSGePoint3d(), ptDir2d.nDirection + PI / 2, 1);
using namespace GlobalFunc;
if ((vt1 & vt2) > 0)
ptDir2d.nDirection += PI / 2;
else
ptDir2d.nDirection -= PI / 2;
poly.AppendNode(ptDir2d.Polar(m_nArrowSize * g_Option::instance().g_nArrowWidth / g_Option::instance().g_nArrowLen * GetPScale() * 0.5));
//dc << XSolid(poly);
//dc << m_poly;
DrawPoly2D(dc, poly);
DrawPoly2D(dc, m_poly);
}
2026-10-04 00:04:20 +08:00
else if (nType == kDote) // 点
2026-09-28 15:28:50 +08:00
{
int nSegNum = m_poly.TotalSegments();
GeDirectionCurve cv;
m_poly.Nth(nSegNum - 1, cv);
ADSGePointDir2d ptDir2d1, ptDir2d2;
double dArrowLen = m_nArrowSize * g_Option::instance().g_nArrowWidth / g_Option::instance().g_nArrowLen * GetPScale() * 0.25;
cv.Polar(dArrowLen, ptDir2d1, FALSE);
cv.Polar(-dArrowLen, ptDir2d2, FALSE);
AcDbPolyline pline;
pline.addVertexAt(0, ptDir2d1, 1.0);
pline.addVertexAt(1, ptDir2d2, 1.0);
//if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0 && !objectId())
// ;
//else
// pline.setConstantWidth(dArrowLen * 2);
pline.setClosed(Adesk::kTrue);
pline.setPropertiesFrom(this);
//dc.Polyline(pline);
//dc << m_poly;
DrawPline(dc, pline);
DrawPoly2D(dc, m_poly);
}
2026-10-04 00:04:20 +08:00
else if (nType == kCrossing) // 十字
2026-09-28 15:28:50 +08:00
{
GeLine line1, line2;
ADSGePoint3d ptCenter = *m_poly.Tail();
double dArrowLen = m_nArrowSize * GetPScale() * 0.5;
line1.StartPoint() = ptCenter - ADSGePoint3d(dArrowLen, 0);
line1.EndPoint() = ptCenter + ADSGePoint3d(dArrowLen, 0);
line2.StartPoint() = ptCenter - ADSGePoint3d(0, dArrowLen);
line2.EndPoint() = ptCenter + ADSGePoint3d(0, dArrowLen);
ads_matrix mat;
ptCenter.GetRotationMatrix(m_nLayoutRotation, mat);
line1.TransformBy(mat);
line2.TransformBy(mat);
//dc << line1 << line2;
//dc << m_poly;
DrawLine(dc, line1);
DrawLine(dc, line2);
DrawPoly2D(dc, m_poly);
}
2026-10-04 00:04:20 +08:00
else // 无
2026-09-28 15:28:50 +08:00
{
//dc << m_poly;
DrawPoly2D(dc, m_poly);
}
return es;
}
int AecXDbSymbArrow::ConvertText(TConvertTextPtr ptr, void *pData)
{
AssertWriteEnabled();
TCString sText;
int nRet = ptr(m_sText, sText, pData);
if (nRet == RTNORM)
{
m_sText = sText;
}
if (m_nFlag != kAtSide && m_bShowText2) // sg add 090106
{
int nRet2 = ptr(m_sText2, sText, pData);
if (nRet2 == RTNORM)
{
m_sText2 = sText;
}
else if (nRet2 == RTERROR)
{
nRet = nRet2;
}
}
return nRet;
}
BOOL AecXDbSymbArrow::GetText(AecXDbText &text, Adesk::UInt32 cookies) const
{
if (m_nFlag == kAtSide && cookies != 0)
return FALSE;
if (m_nFlag != kAtSide)
{
if (m_bShowText2 && cookies > 1)
return FALSE;
if (!m_bShowText2 && cookies != 0)
return FALSE;
}
text.setPropertiesFrom(this);
text.SetHeight(m_nTextHeight);
text.SetStyleId(m_idTextStyle);
if (m_nFlag != kAtSide)
{
// text.SetRotation(Wcs2Layout(GetTextBaseDir()));
2026-10-04 00:04:20 +08:00
// sg modify 090624,解决UCS下,红框位置不准确的问题
2026-09-28 15:28:50 +08:00
double dAngle = GlobalFunc::ChangeAngleTo1_4(Wcs2Layout(GetTextBaseDir()));
text.SetRotation(dAngle);
}
// text.SetLocation(m_ptText); // sg delete 090106
// text.SetText(m_sText);
// text.SetAlignment(GetTextAlignment());
2026-10-04 00:04:20 +08:00
if (cookies == 0) // 文字
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
2026-09-28 15:28:50 +08:00
// text.SetLocation(m_ptText);
text.SetLocation(GetTextLocation());
text.SetText(m_sText);
text.SetAlignment(GetTextAlignment());
}
2026-10-04 00:04:20 +08:00
else // 新增加的文字2
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点的时候要转换成WCS下的坐标
2026-09-28 15:28:50 +08:00
// text.SetLocation(m_ptText2);
text.SetLocation(GetText2Location());
text.SetText(m_sText2);
text.SetAlignment(GetText2Alignment());
}
return TRUE;
}
2026-10-04 00:04:20 +08:00
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
2026-09-28 15:28:50 +08:00
TextPosition
AecXDbSymbArrow::FindSubText(const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange) const
{
assertReadEnabled();
// AecXDbText text; // sg modify 090106
// GetText(text);
// TextPosition pos = text.FindSubText(sSubText, posStart, pRange);
TextPosition pos;
if (!sSubText || !sSubText[0])
return pos;
TextPosition posNext = posStart;
while (1)
{
AecXDbText text;
text.SetPScale(GetPScale());
if (!GetText(text, posNext.m_nCookies))
break;
TextPosition posFind = text.FindSubText(sSubText, posNext, pRange);
if (!posFind)
{
posNext.m_nCookies++;
posNext.m_nTextPos = 0;
}
else
{
posStart = posNext;
if (!posStart)
{
posStart.m_nCookies++;
posStart.m_nTextPos = 0;
}
posFind.m_nCookies = posNext.m_nCookies;
pos = posFind;
break;
}
}
return pos;
}
2026-10-04 00:04:20 +08:00
// 返回下一次查找的开始位置
2026-09-28 15:28:50 +08:00
TextPosition
AecXDbSymbArrow::ReplaceSubText(const TextPosition &posRep, const TCHAR *sRepText, TextRange *pRange)
{
AssertWriteEnabled();
// AecXDbText text; // sg delete 090106
// GetText(text);
// TextPosition pos = text.ReplaceSubText(posRep, sRepText, pRange);
// SetText(text.GetText());
// return pos;
TextPosition posNext;
AecXDbText text;
text.SetPScale(GetPScale());
if (!GetText(text, posRep.m_nCookies))
return posNext;
posNext = text.ReplaceSubText(posRep, sRepText, pRange);
int cookies = posRep.m_nCookies;
if (cookies == 0)
{
SetText(text.GetText());
}
else if (cookies == 1)
{
SetText2(text.GetText());
}
if (!posNext)
{
posNext.m_nCookies = posRep.m_nCookies + 1;
posNext.m_nTextPos = 0;
}
return posNext;
}
2026-10-04 00:04:20 +08:00
// sg add 090106,AOL中有同名函数的实现,因此在暂时将该函数定义为内联
2026-09-28 15:28:50 +08:00
void AecXDbSymbArrow::SetSubText(long i, CString sText)
{
AssertWriteEnabled();
if (i == 0)
{
m_sText = sText;
}
else if (m_nFlag != kAtSide && m_bShowText2)
{
m_sText2 = sText;
}
}
2026-10-04 00:04:20 +08:00
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
2026-09-28 15:28:50 +08:00
void AecXDbSymbArrow::GetTips(PtrList<ObjInfoUnit> &lstInfo) const
{
2026-10-04 00:04:20 +08:00
lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("箭头标注")));
lstInfo.Append(new ObjInfoUnit(_T("文字内容"), m_sText));
2026-09-28 15:28:50 +08:00
if (m_nFlag != kAtSide && m_bShowText2)
{
2026-10-04 00:04:20 +08:00
lstInfo.Append(new ObjInfoUnit(_T("文字内容2"), m_sText2));
2026-09-28 15:28:50 +08:00
}
TCString sTextStyle = GlobalFunc::GetSymbolName(m_idTextStyle);
2026-10-04 00:04:20 +08:00
lstInfo.Append(new ObjInfoUnit(_T("文字样式"), sTextStyle));
2026-09-28 15:28:50 +08:00
TCString sHeight;
GlobalFunc::ftoa(m_nTextHeight, 1, sHeight);
sHeight << _T("P");
2026-10-04 00:04:20 +08:00
lstInfo.Append(new ObjInfoUnit(_T("文字高度"), sHeight));
2026-09-28 15:28:50 +08:00
GlobalFunc::ftoa(m_nArrowSize, 1, sHeight);
sHeight << _T("P");
2026-10-04 00:04:20 +08:00
lstInfo.Append(new ObjInfoUnit(_T("箭头大小"), sHeight));
2026-09-28 15:28:50 +08:00
}
AcGiDraw::TextAlignment AecXDbSymbArrow::GetTextAlignment() const
{
AcGiDraw::TextAlignment align;
2026-10-04 00:04:20 +08:00
if (m_nFlag == kAtSide) // 在线端
2026-09-28 15:28:50 +08:00
{
double nDir = Wcs2Layout(GetTextBaseDir());
if (nDir >= PI * 1.75 || nDir < PI * 0.25)
align = AcGiDraw::kMiddleRight;
else if (/*nDir>=PI*0.25 && */nDir < PI * 0.75)
align = AcGiDraw::kTopCenter;
else if (/*nDir>=PI*0.75 && */nDir < PI * 1.25)
align = AcGiDraw::kMiddleLeft;
else
align = AcGiDraw::kBottomCenter;
}
else if (m_nFlag == kAlignMid)
{
align = AcGiDraw::kBottomCenter;
}
else if (m_nFlag == kAlignEnd)
{
double nDir = Wcs2Layout(GetTextBaseDir());
double nRot = GlobalFunc::ChangeAngleTo1_4(nDir);
if (IsExactSameDrt(nRot, nDir, g_DimOption::instance()._angSnap))
align = AcGiDraw::kBottomLeft;
else
align = AcGiDraw::kBottomRight;
}
return align;
}
AcGiDraw::TextAlignment AecXDbSymbArrow::GetText2Alignment() const // sg add 090106
{
AcGiDraw::TextAlignment align;
if (m_nFlag == kAlignMid)
{
align = AcGiDraw::kTopCenter;
}
else
{
double dDir = Wcs2Layout(GetTextBaseDir()),
dRot = GlobalFunc::ChangeAngleTo1_4(dDir);
if (IsExactSameDrt(dRot, dDir, g_DimOption::instance()._angSnap))
align = AcGiDraw::kTopLeft;
else
align = AcGiDraw::kTopRight;
}
return align;
}
double AecXDbSymbArrow::GetTextBaseDir() const
{
ASSERT(IsValid());
GeCurveSegment segFirst;
m_poly.Nth(0, segFirst);
double nDir = 0.0;
if (m_nFlag == kAtSide || m_nFlag == kAlignEnd)
{
nDir = segFirst.IDirection(0);
}
else
{
2026-10-04 00:04:20 +08:00
// sg modify 120209,解决9.0升级为ECS坐标以后的问题
2026-09-28 15:28:50 +08:00
ADSGePoint3d ptTemp;
ADSGePoint3d ptText = GetTextLocation();
//segFirst.ProjectToMe(m_ptText, ptTemp);
segFirst.ProjectToMe(ptText, ptTemp);
double nDist = segFirst.PathDistance(ptTemp);
ADSGePointDir2d ptTempDir;
segFirst.Polar(nDist, ptTempDir);
if (nDist < 0.0 &&
ptTemp.Distance2d(segFirst.StartPoint()) < ptTemp.Distance2d(segFirst.EndPoint()))
{
nDir = GlobalFunc::AngleRangeTo2PI(ptTempDir.nDirection + PI);
}
else
{
nDir = ptTempDir.nDirection;
}
}
return nDir;
}
ADSGePoint3d AecXDbSymbArrow::GetDefaultTextLocation()
{
2026-10-04 00:04:20 +08:00
// sg modify 120104,主要是为了方便代码维护,直接调用GetEcsOriginPt函数
2026-09-28 15:28:50 +08:00
ADSGePoint3d ptRet;
ptRet = GetEcsOriginPt(TRUE);
return ptRet;
}
ADSGePoint3d AecXDbSymbArrow::GetDefaultText2Location() // sg add 090106
{
2026-10-04 00:04:20 +08:00
// sg modify 120104,主要是为了方便代码维护,直接调用GetEcsOriginPt函数
2026-09-28 15:28:50 +08:00
ADSGePoint3d ptRet;
ptRet = GetEcsOriginPt(FALSE);
return ptRet;
}
void AecXDbSymbArrow::GetPoly2D(GePoly2D &poly) const
{
poly = m_poly;
}
void AecXDbSymbArrow::SetPoly2D(const GePoly2D &poly)
{
AssertWriteEnabled();
m_poly = poly;
}
2026-10-04 00:04:20 +08:00
// sg modify 120104,既可返回ECS点,又可以返回WCS点
2026-09-28 15:28:50 +08:00
// ADSGePoint3d AecXDbSymbArrow::GetTextLocation() const
ADSGePoint3d AecXDbSymbArrow::GetTextLocation(BOOL bEcsPoint) const
{
// return m_ptText;
2026-10-04 00:04:20 +08:00
ADSGePoint3d ptResult = m_ptText; // ECS点
2026-09-28 15:28:50 +08:00
if (!bEcsPoint)
2026-10-04 00:04:20 +08:00
ptResult = GetWcsTextPt(TRUE); // WCS点
2026-09-28 15:28:50 +08:00
return ptResult;
}
void AecXDbSymbArrow::SetTextLocation(ADSGePoint3d pt)
{
AssertWriteEnabled();
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点,该位置点由原来的wcs转换为ecs
2026-09-28 15:28:50 +08:00
// m_ptText = pt;
2026-10-04 00:04:20 +08:00
AcGePoint2d ptOrigin = GetEcsOriginPt(TRUE); // 获得ECS原点
2026-09-28 15:28:50 +08:00
AcGeVector2d xAxis, yAxis;
2026-10-04 00:04:20 +08:00
GetEcsAxisVector(xAxis, yAxis); // 获得ECS坐标轴方向
2026-09-28 15:28:50 +08:00
AcGeMatrix2d mat2d;
mat2d = mat2d.alignCoordSys(ptOrigin, xAxis, yAxis,
AcGePoint2d(0, 0), AcGeVector2d(1, 0), AcGeVector2d(0, 1));
AcGePoint2d ptResult(pt.x, pt.y);
ptResult.transformBy(mat2d); // WCS2ECS
m_ptText.x = ptResult.x / GetPScale();
2026-10-04 00:04:20 +08:00
m_ptText.y = ptResult.y / GetPScale(); // 用图纸比例保存
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
// sg modify 120104,既可返回ECS点,又可以返回WCS点
2026-09-28 15:28:50 +08:00
// ADSGePoint3d AecXDbSymbArrow::GetText2Location() const
ADSGePoint3d AecXDbSymbArrow::GetText2Location(BOOL bEcsPoint) const
{
// return m_ptText2;
2026-10-04 00:04:20 +08:00
ADSGePoint3d ptResult = m_ptText2; // ECS点
2026-09-28 15:28:50 +08:00
if (!bEcsPoint)
2026-10-04 00:04:20 +08:00
ptResult = GetWcsTextPt(FALSE); // WCS点
2026-09-28 15:28:50 +08:00
return ptResult;
}
2026-10-04 00:04:20 +08:00
// 由WCS转换为ECS保存
2026-09-28 15:28:50 +08:00
void AecXDbSymbArrow::SetText2Location(ADSGePoint3d ptLoc)
{
AssertWriteEnabled();
2026-10-04 00:04:20 +08:00
// modify by lgy 111230,设置文字位置点,该位置点由原来的wcs转换为ecs
2026-09-28 15:28:50 +08:00
// m_ptText2 = ptLoc;
2026-10-04 00:04:20 +08:00
AcGePoint2d ptOrigin = GetEcsOriginPt(FALSE); //获得ECS原点
2026-09-28 15:28:50 +08:00
AcGeVector2d xAxis, yAxis;
2026-10-04 00:04:20 +08:00
GetEcsAxisVector(xAxis, yAxis); // 获得ECS坐标轴方向
2026-09-28 15:28:50 +08:00
AcGeMatrix2d mat2d;
mat2d = mat2d.alignCoordSys(ptOrigin, xAxis, yAxis,
AcGePoint2d(0, 0), AcGeVector2d(1, 0), AcGeVector2d(0, 1));
AcGePoint2d ptResult(ptLoc.x, ptLoc.y);
ptResult.transformBy(mat2d); // WCS2ECS
m_ptText2.x = ptResult.x / GetPScale();
2026-10-04 00:04:20 +08:00
m_ptText2.y = ptResult.y / GetPScale(); // 用图纸比例保存
2026-09-28 15:28:50 +08:00
}
const TCHAR * AecXDbSymbArrow::GetText() const
{
return (const TCHAR *)m_sText;
}
void AecXDbSymbArrow::SetText(const TCHAR *pszText)
{
AssertWriteEnabled();
m_sText = pszText;
}
AecXDbSymbArrow::TArTextAlign
AecXDbSymbArrow::GetTextAlign() const
{
return m_nFlag;
}
void AecXDbSymbArrow::SetTextAlign(AecXDbSymbArrow::TArTextAlign align)
{
AssertWriteEnabled();
m_nFlag = align;
}
double AecXDbSymbArrow::GetArrowSize(BOOL bAsPaperUnit) const
{
double nSize = m_nArrowSize;
if (!bAsPaperUnit)
nSize *= GetPScale();
return nSize;
}
void AecXDbSymbArrow::SetArrowSize(double nSize, BOOL bAsPaperUnit)
{
AssertWriteEnabled();
m_nArrowSize = nSize;
if (!bAsPaperUnit)
m_nArrowSize /= GetPScale();
}
double AecXDbSymbArrow::GetText2BaseRatio(BOOL bAsPaperUnit, BOOL bRealDist) const
{
2026-10-04 00:04:20 +08:00
double dVal = m_dText2BaseRatio; // 系数
2026-09-28 15:28:50 +08:00
if (fabs(dVal + 1000) < 1.0E-5)
{
2026-10-04 00:04:20 +08:00
dVal = GlobalFunc::DocGetText2BaseRatio(); // 使用全局变量GlobalFunc::DocGetText2BaseRatio的值
2026-09-28 15:28:50 +08:00
}
if (bRealDist)
{
2026-10-04 00:04:20 +08:00
dVal *= m_nTextHeight; // 将“系数”转为“实际值”
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
if (!bAsPaperUnit) // 处理出图比例
2026-09-28 15:28:50 +08:00
{
dVal *= GetPScale();
}
return dVal;
}
void AecXDbSymbArrow::SetText2BaseRatio(double dVal, BOOL bAsPaperUnit)
{
AssertWriteEnabled();
2026-10-04 00:04:20 +08:00
m_dText2BaseRatio = dVal; // 系数
2026-09-28 15:28:50 +08:00
if (!bAsPaperUnit)
{
m_dText2BaseRatio /= GetPScale();
}
}
// sg add 090106
BOOL AecXDbSymbArrow::GetShowText2() const
{
return m_bShowText2;
}
void AecXDbSymbArrow::SetShowText2(BOOL bShow)
{
AssertWriteEnabled();
m_bShowText2 = bShow;
}
const TCHAR* AecXDbSymbArrow::GetText2() const
{
return m_sText2;
}
void AecXDbSymbArrow::SetText2(const TCHAR *pszText)
{
AssertWriteEnabled();
m_sText2 = pszText;
}
2026-10-04 00:04:20 +08:00
// sg add 110211,支持统一标高
2026-09-28 15:28:50 +08:00
bool AecXDbSymbArrow::UnifyElevation(double dElevation)
{
AssertWriteEnabled();
m_poly.SetElevation(dElevation);
m_ptText.z = dElevation;
m_ptText2.z = dElevation;
return true;
}
2026-10-04 00:04:20 +08:00
// sg add 090623,标注角度
2026-09-28 15:28:50 +08:00
double AecXDbSymbArrow::GetDimAngle(double dAngle) const
{
2026-10-04 00:04:20 +08:00
double dSnap = PI / 180, // 1度
2026-09-28 15:28:50 +08:00
dAng = GlobalFunc::AngleRangeTo2PI(dAngle),
dRet = dAng;
dAng = Wcs2Layout(dAng);
if (GlobalFunc::GreatThan(dAng, PI / 2.0, dSnap) && GlobalFunc::LessThan(dAng, PI, dSnap))
dRet += PI;
else if (GlobalFunc::GreatEqual(dAng, PI, dSnap) && GlobalFunc::LessEqual(dAng, PI * 1.5, dSnap))
dRet -= PI;
return dRet;
}
2026-10-04 00:04:20 +08:00
// 获取ECS原点,文字位置参考点
2026-09-28 15:28:50 +08:00
AcGePoint2d AecXDbSymbArrow::GetEcsOriginPt(BOOL bUp) const
{
ADSGePoint3d ptOrigin;
if (!IsValid())
return ptOrigin.AsAcGePoint2d();
GeDirectionCurve cvFirst;
m_poly.Nth(0, cvFirst);
2026-10-04 00:04:20 +08:00
ptOrigin = cvFirst.StartPoint(); // 坐标系原点
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
double dRotation = cvFirst.IDirection(0), // 方向
dGap = GetText2BaseRatio(FALSE, TRUE); // 距基线距离,乘过比例, 字高
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
if (m_nFlag == kAtSide) // 用于计算在线端的ecs的坐标
2026-09-28 15:28:50 +08:00
{
dRotation += PI;
}
2026-10-04 00:04:20 +08:00
else if (m_nFlag == kAlignMid) // 齐线中
2026-09-28 15:28:50 +08:00
{
ADSGePointDir2d ptMidDir2d;
cvFirst.Polar(cvFirst.GetLength() / 2, ptMidDir2d);
ptOrigin = ptMidDir2d;
if (bUp)
dRotation = GetDimAngle(ptMidDir2d.nDirection) + PI / 2;
else
dRotation = GetDimAngle(ptMidDir2d.nDirection) - PI / 2;
}
2026-10-04 00:04:20 +08:00
else if (m_nFlag == kAlignEnd) // 齐线端
2026-09-28 15:28:50 +08:00
{
if (bUp)
dRotation = GetDimAngle(dRotation) + PI / 2;
else
dRotation = GetDimAngle(dRotation) - PI / 2;
}
ads_polar(ptOrigin, dRotation, dGap, ptOrigin);
return ptOrigin.AsAcGePoint2d();
}
void AecXDbSymbArrow::GetEcsAxisVector(AcGeVector2d &xAxis, AcGeVector2d &yAxis) const
{
if (m_poly.TotalSegments() < 1)
{
return;
}
GeDirectionCurve cvFirst;
m_poly.Nth(0, cvFirst);
double dRotation = cvFirst.IDirection(0),
2026-10-04 00:04:20 +08:00
dXDir(0), dYDir(0); // 方向
2026-09-28 15:28:50 +08:00
if (m_nFlag == kAtSide)
{
dXDir = dRotation + PI;
xAxis = AcGeVector2d(cos(dXDir), sin(dXDir));
dYDir = dRotation + PI / 2;
yAxis = AcGeVector2d(cos(dYDir), sin(dYDir));
}
2026-10-04 00:04:20 +08:00
else if (m_nFlag == kAlignMid) // 齐线中
2026-09-28 15:28:50 +08:00
{
xAxis = m_poly[0] - m_poly[1];
ADSGePointDir2d ptMidDir2d;
cvFirst.Polar(cvFirst.GetLength() / 2, ptMidDir2d);
dYDir = GetDimAngle(ptMidDir2d.nDirection) + PI / 2;
yAxis = AcGeVector2d(cos(dYDir), sin(dYDir));
}
2026-10-04 00:04:20 +08:00
else if (m_nFlag == kAlignEnd) // 齐线端
2026-09-28 15:28:50 +08:00
{
dXDir = dRotation;
xAxis = AcGeVector2d(cos(dXDir), sin(dXDir));
dYDir = GetDimAngle(dXDir) + PI / 2;
yAxis = AcGeVector2d(cos(dYDir), sin(dYDir));
}
xAxis.normalize();
yAxis.normalize();
}
ADSGePoint3d AecXDbSymbArrow::GetWcsTextPt(BOOL bUp) const
{
AcGePoint2d ptResult, ptOrigin;
2026-10-04 00:04:20 +08:00
if (bUp) // m_sText,文字
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
ptOrigin = GetEcsOriginPt(TRUE); // 获得ECS原点
2026-09-28 15:28:50 +08:00
ptResult.x = m_ptText.x * GetPScale();
ptResult.y = m_ptText.y * GetPScale();
}
2026-10-04 00:04:20 +08:00
else // m_sText2,文字2
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
ptOrigin = GetEcsOriginPt(FALSE); // 获得ECS原点
2026-09-28 15:28:50 +08:00
ptResult.x = m_ptText2.x * GetPScale();
ptResult.y = m_ptText2.y * GetPScale();
}
AcGeVector2d xAxis, yAxis;
2026-10-04 00:04:20 +08:00
GetEcsAxisVector(xAxis, yAxis); // 获得ECS坐标轴方向
2026-09-28 15:28:50 +08:00
AcGeMatrix2d mat2d;
mat2d = mat2d.alignCoordSys(AcGePoint2d(0, 0), AcGeVector2d(1, 0),
2026-10-04 00:04:20 +08:00
AcGeVector2d(0, 1), ptOrigin, xAxis, yAxis); //构造转换矩阵
2026-09-28 15:28:50 +08:00
ptResult.transformBy(mat2d); //ECS2WCS
return ADSGePoint3d(ptResult.x, ptResult.y);
}