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

623 lines
15 KiB
C++

#include "stdafx.h"
#include "TDbInSight.h"
#include "symdef.h"
#include "dbtext.h"
#include "dbhatch.h"
// lgd add 140424,增加符号文字导出所在图层设置
extern int g_nSymbTextT3Layer;
void InitInSight(BOOL bInit)
{
if(bInit)
{
TDbInSight::rxInit();
acrxBuildClassHierarchy();
TDbInSight::InitMatchProtocol(TRUE);
}
else
{
TDbInSight::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbInSight::desc());
}
}
ACRX_DXF_DEFINE_MEMBERS(ATSInSight, ATSCurveEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_TDBINSIGHT, "ATS_TDBINSIGHT图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbInSight);
TDbInSight::TDbInSight():m_ptIns(AcGePoint3d(0.0,0.0,0.0)),m_dRotation(0),m_InSightStyle(0),m_strTH(_T("")),m_strBH(_T("")),
m_dRadius(10), m_dTextRatio(0.0), m_bOldStyle(2)
{
m_idTextStyle = InitTextStyle(TS_DIM);
}
TDbInSight::~TDbInSight() {}
Acad::ErrorStatus TDbInSight::subTransformBy( const AcGeMatrix3d& xform )
{
assertWriteEnabled();
m_ptIns.TransformBy(xform);
XVector3D vtRot(cos(m_dRotation), sin(m_dRotation));
((AcGeVector3d &)vtRot).transformBy(xform);
m_dRotation=ads_angle(XPoint(), vtRot);
return Acad::eOk;
}
TSubText* TDbInSight::HitTestText(XPoint pt)const
{
// sg modify 110209,支持圆圈文字出圈样式
int nTrueStyle = GetTrueTextStyle();
double dScale = (nTrueStyle==1)?0.75:(GetTextRatio()-0.05);
XPoint ptCenter(m_ptIns);
XPoint ptHit(pt);
if (pt.Distance2d(m_ptIns) < m_dRadius *dScale * GetPScale()) // sg modify 081223,字的大小占圆圈的%
{
if (GetSubTextNum() == 1)
return GetSubText(0);
XLine line;
ads_polar(m_ptIns, m_dRotation, m_dRadius * GetPScale(), line.EndPoint());
ads_polar(m_ptIns, PI+ m_dRotation, m_dRadius * GetPScale(), line.StartPoint());
if (line.HitTest2d(pt) == 2)
return GetSubText(1);
else
return GetSubText(0);
}
return NULL;
}
void TDbInSight::SetSubText(long i, CString sText)
{
assertWriteEnabled();
if (i == 0)
{
SetNumberText(sText);
}
// else // sg modify 081218
// SetDrawingLabel(sText);
else if (i == 1)
{
SetMapNoText(sText);
}
}
// sg add 110209,获得圆圈文字样式,考虑了随基本设定的情况
int TDbInSight::GetTrueTextStyle() const
{
int nOldStyle = m_bOldStyle;
if (nOldStyle == 2) // 随基本设定
{
nOldStyle = DocGetDrawingIndexStyle();
}
return nOldStyle;
}
// sg add 081222,计算最大的文字宽度、高度
void TDbInSight::GetTextExtends(const TCHAR *sText, double &dX, double &dY,
BOOL bDrawingLabel) const
{
double dWidthFactor(1.0); // 中文字体宽高比
OPENOBJ_BEGIN(m_idTextStyle, AcDb::kForRead, AcDbTextStyleTableRecord, pStyle);
if (pStyle != NULL)
{
dWidthFactor = pStyle->xScale();
}
OPENOBJ_END();
CString csTmpText = sText;
csTmpText.TrimLeft();
csTmpText.TrimRight();
if (csTmpText.IsEmpty() || _tcscmp(sText, _T("-"))==0)
{
csTmpText = _T("2");
}
// sg add 110209,获得文字高度
double dHeigh = m_nTextHeight * GetPScale(),
dRadius = m_dRadius*GetPScale() * GetTextRatio();
int nTrueStyle = GetTrueTextStyle();
if (nTrueStyle != 0) // 出圈样式
{
dHeigh = dRadius * 2.0;
if (m_InSightStyle != ENormalInsight)
{
dHeigh *= 0.5;
}
}
AcDbText text;
text.setPosition(XPoint(0, 0));
text.setTextStyle(m_idTextStyle);
text.setTextString(csTmpText);
// text.setHeight(m_nTextHeight*GetPScale());
text.setHeight(dHeigh);
text.setRotation(0);
text.setWidthFactor(dWidthFactor);
AcDbExtents extents;
XPoint ptMax, ptMin;
if (text.getGeomExtents(extents) == Acad::eOk) // 外包矩形,一般情况下都是eOk
{
ptMax = extents.maxPoint();
ptMin = extents.minPoint();
}
else // sg add 110802,批量转旧时候,获得外包围盒有时候会不成功
{
AcGiTextStyle style;
fromAcDbTextStyle(style, m_idTextStyle);
style.extentsBox(csTmpText, FALSE, csTmpText.GetLength(), FALSE, ptMin, ptMax);
}
if (nTrueStyle != 0) // sg add 110209,出圈样式
{
dX = ptMax.x - ptMin.x;
dY = dHeigh;
if (m_InSightStyle == ENormalInsight)
{
dX *= 0.5;
dY *= 0.5;
}
return;
}
// 8.0起,文字最大不超过圆的比例可设置
double dFactor = (ptMax.x - ptMin.x) / (ptMax.y - ptMin.y); // 宽高比例
dY = dRadius/sqrt(1 + dFactor*dFactor); // 调整大小,圈内只有一行文字时
if (m_InSightStyle != ENormalInsight)
{
dY = dRadius/sqrt(1.21 + 0.25*dFactor*dFactor); // 圈内有两行文字时
}
dX = dY * dFactor;
}
Acad::ErrorStatus TDbInSight::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet,BOOL *bErase)
{
// sg add 110621,如果是出圈样式,导出为T3-T8时,全部分解
BOOL bExplode = GetTrueTextStyle()==3;
Acad::ErrorStatus es = Acad::eOk;
if (bExplode) // sg add 110621,出圈样式,需要分解
{
//XPushMemVar<BOOL> vTemp(XExplodeStream::m_bFullExplode, TRUE); // 完全分解
XPushMemVar<BOOL> vTemp2(XExplodeStream::m_bExportTch4, TRUE);
XExplodeStream dc(entSet);
if (!OnExplodeOrDraw(dc))
return es;
dc.SetPropertiesFrom(this);
if (nDrawMode == DRAW_2D)
es = ExplodeOrDraw2d(dc);
else
es = ExplodeOrDraw3d(dc);
if (bErase)
*bErase = TRUE;
return es;
}
return TDbSymbWithText::DownGradeSave(nDrawMode, entSet, bErase); // 其他情况,基类处理
}
Acad::ErrorStatus TDbInSight::ExplodeOrDraw2d( TGGiExplodeDrawBase &dc ) const
{
AcDbObjectId idLayer = dc.GetLayerId();
double dRotation = m_dRotation + GetLayoutRotation();
AcGePoint2d tmpPt, ptCircleLeft, ptCircleRight,ptLineLeft,ptLineRight/*中间的线段*/;
AcGeVector2d vtx = AcGeVector2d::kXAxis;
AcGeVector2d vty = AcGeVector2d::kYAxis;
vtx.rotateBy(dRotation);
vtx.normalize();
vty.rotateBy(dRotation);
vtx.normalize();
AcGeVector2d vtLX = AcGeVector2d::kXAxis;
vtLX.rotateBy(GetLayoutRotation());
vtLX.normalize();
double dRadius = GetPScale() * m_dRadius;
//三角形底边长度
double dTransWidth = 2 *dRadius*cos(45*PI/180);
AcDbPolyline pline;
pline.setConstantWidth(0);
tmpPt = m_ptIns - dRadius * vtx;
pline.addVertexAt(0, tmpPt, -1.0);
tmpPt = m_ptIns + dRadius*vtx;
pline.addVertexAt(1, tmpPt, 0);
tmpPt = m_ptIns + vtx * dTransWidth;
pline.addVertexAt(2, tmpPt, 0);
tmpPt = m_ptIns + vty * dTransWidth;
pline.addVertexAt(3, tmpPt, 0);
tmpPt = m_ptIns - vtx * dTransWidth;
pline.addVertexAt(4, tmpPt, 0);
pline.setClosed(Adesk::kTrue);
pline.setLayer(idLayer);
dc.Polyline(pline);
//填充
TGGePoly2D poly;
poly.SetAcDbCurve(&pline);
//判断版本
#if ADS <= 17
dc.DrawSolid(poly);
#else
AcDbHatch *pHatch = NewHatchFromPoly2D(poly);
pHatch->setColorIndex(pline.colorIndex());
pHatch->setLayer(idLayer);
dc.DrawEntity(*pHatch);
if (pHatch){delete pHatch;}
#endif
ptCircleLeft = m_ptIns - dRadius*vtx;
ptCircleRight = m_ptIns + dRadius*vtx;
ptLineLeft = m_ptIns - dRadius*vtLX;
ptLineRight = m_ptIns + dRadius*vtLX;
pline.reset(Adesk::kFalse, 0);
pline.addVertexAt(0, ptCircleLeft, 1.0);
pline.addVertexAt(1, ptCircleRight, 1.0);
pline.addVertexAt(2, ptCircleLeft, 0);
pline.setClosed(Adesk::kFalse);
pline.setConstantWidth(0);
pline.setLayer(idLayer);
dc.Polyline(pline);
ads_matrix matRot;
m_ptIns.GetRotationMatrix(m_nLayoutRotation, matRot);
dc.SetStyle(m_idTextStyle);
dc.SetRotation(m_nLayoutRotation);
// sg modify 110209,支持圆圈文字出圈样式
// BOOL bOldStyle = IsOldStyle();
int nTrueStyle = GetTrueTextStyle();
if (m_InSightStyle == ENormalInsight) // 圆圈文字内只有一个单行文字的情况
{
XPoint pt1, pt2;
double nTextHeight(0);
// if (bOldStyle)
if (nTrueStyle == 1) // 8.0以前样式
{
nTextHeight = dRadius/sin(PI/4.0);
pt1 = m_ptIns - XPoint(0.8*nTextHeight/2.0, 0.8*nTextHeight/2.0);
pt2 = m_ptIns + XPoint(0.8*nTextHeight/2.0, -0.8*nTextHeight/2.0);
}
else // 8.0新样式,8.5出圈文字样式
{
double dX(0);
GetTextExtends(m_strBH, dX, nTextHeight, FALSE); // 获取指定文字的最大尺寸
pt1 = m_ptIns - XPoint(dX, nTextHeight);
pt2 = m_ptIns + XPoint(dX, -nTextHeight);
}
if (!m_strBH.IsEmpty() || g_bExplodeSubText)
{
int nColorOld = dc.GetColor();
if (dc.IsExportTch4()) // 炸开
{
// lgd add 140424,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理
if (g_nSymbTextT3Layer==1 && !!m_idTextLayer)
{
dc.SetLayer(m_idTextLayer); // 文字层
dc.SetColor(256); //颜色随层
}
else
{
dc.SetLayer(idLayer); // 文字和标注放在同一
dc.SetColor(m_colorText);
}
}
else // 绘制
{
dc.SetLayer(idLayer); // 文字和标注放在同一
dc.SetColor(m_colorText);//颜色随层
}
if (IsLayoutRotated())
{
pt1.TransformBy(matRot);
pt2.TransformBy(matRot);
}
if (nTrueStyle == 1) // 旧样式
dc.DrawTextFit(m_strBH, pt1, pt2, nTextHeight*0.8);
else // 新样式,出圈文字样式样式
dc.DrawTextFit(m_strBH, pt1, pt2, nTextHeight*2); // 字高为dY的2倍
}
}
else // 上、下都有文字的情况
{
/*绘中间线*/
pline.reset(Adesk::kFalse, 0);
pline.addVertexAt(0, ptLineLeft);
pline.addVertexAt(1, ptLineRight);
pline.setClosed(Adesk::kFalse);
pline.setLayer(idLayer);
dc.SetLayer(idLayer);
dc.Polyline(pline);
double nTextHeight(0), dY(0);
if (nTrueStyle == 1) // 旧样式
{
double nAng = atan(2.0);
nTextHeight = dRadius*sin(nAng)*0.9;
}
else // 新样式,出圈样式
{
GetTextExtends(m_strBH, nTextHeight, dY, TRUE);
}
XPoint pt1 = m_ptIns,
pt2 = m_ptIns;
pt1.x -= nTextHeight/2;
pt2.x += nTextHeight/2;
double nSpacer(0);
if (nTrueStyle == 1) // 旧样式
nSpacer = nTextHeight/10.0;
else // 新样式,出圈样式
{
if (GetTextRatio() > 1.0 + 1E-2) // 圆圈文字的系数大于1时
{
nSpacer = dY/5.0;
}
else if (nTrueStyle == 0) // 新样式
{
// sg modify 101119,根据8.5需求,修改新样式,将文字远离基线
nSpacer = (sqrt(dRadius*dRadius - 0.25*nTextHeight*nTextHeight) - dY)*0.4;
}
else // ==3,出圈样式
{
nSpacer = (dRadius - dY) * 0.4;
}
}
pt1.y += nSpacer;
pt2.y += nSpacer;
int nColorOld = dc.GetColor();
if (dc.IsExportTch4()) // 炸开
{
// lgd add 140424,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理
if (g_nSymbTextT3Layer==1 && !!m_idTextLayer)
{
dc.SetLayer(m_idTextLayer); // 文字层
dc.SetColor(256); //颜色随层
}
else
{
dc.SetLayer(idLayer); // 文字和标注放在同一层
dc.SetColor(m_colorText);
}
}
else // 绘制
{
dc.SetLayer(idLayer); // 文字和标注放在同一
dc.SetColor(m_colorText);
}
XPoint ptTextLoc;
ptTextLoc = m_ptIns + vty *GetPScale()* m_dRadius/2;
if (nTrueStyle == 1) // 旧样式
dc.DrawTextFit(m_strBH, pt1.TransformAs(matRot), pt2.TransformAs(matRot), nTextHeight*0.8);
else // 新样式,出圈样式,设置字高为dY
dc.DrawTextFit(m_strBH, pt1.TransformAs(matRot), pt2.TransformAs(matRot), dY);
if (nTrueStyle == 1) // 旧样式
{
pt1.y -= nTextHeight*0.8+2*nSpacer;
pt2.y -= nTextHeight*0.8+2*nSpacer;
}
else // 新样式,出圈样式
{
GetTextExtends(m_strTH, nTextHeight, dY, TRUE);
// sg modify 101119,根据8.5需求,修改新样式,将文字远离基线
double dTmpNum = dY*1.2;
if (GetTextRatio() < 1.0 + 1E-2)
{
if (nTrueStyle == 0) // 新样式
{
dTmpNum = (sqrt(dRadius*dRadius - 0.25*nTextHeight*nTextHeight) - dY)*0.4 + dY;
}
else // ==3,出圈样式
{
dTmpNum = (dRadius - dY) * 0.4 + dY;
}
}
pt1 = m_ptIns - XPoint(nTextHeight/2, dTmpNum);
pt2 = m_ptIns + XPoint(nTextHeight/2, -dTmpNum);
}
if (IsLayoutRotated())
{
pt1.TransformBy(matRot);
pt2.TransformBy(matRot);
}
ptTextLoc = m_ptIns - vty * GetPScale()*m_dRadius/2;
if (nTrueStyle == 1) // 旧样式
dc.DrawTextFit(m_strTH, pt1, pt2, nTextHeight*0.8);
else // 新样式,出圈样式
dc.DrawTextFit(m_strTH, pt1, pt2, dY);
}
return Acad::eOk;
}
Acad::ErrorStatus
TDbInSight::subGetClassID(CLSID* pClsid) const
{
#if (ADS >= 17)
#endif
return Acad::eOk;
}
// 取夹点说明
Acad::ErrorStatus TDbInSight::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es = Acad::eOk;
if( i ==0 )
cs = _T("移动内视符号");
else
es = Acad::eInvalidInput;
return es;
}
Acad::ErrorStatus TDbInSight::subGetGripPoints( AcGePoint3dArray&gripPoints,AcDbIntArray&,AcDbIntArray& ) const
{
assertReadEnabled();
gripPoints.append(m_ptIns);
return Acad::eOk;
}
Acad::ErrorStatus TDbInSight::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset )
{
assertWriteEnabled();
int iIndex = indices.at(0);
switch (iIndex)
{
case 0:
{
m_ptIns+=offset;
}
break;
default:
break;
}
return Acad::eOk;
}
Acad::ErrorStatus TDbInSight::dwgInFields( AcDbDwgFiler* pFiler )
{
assertWriteEnabled();
Acad::ErrorStatus es;
if ((es = TDbSymbWithText::dwgInFields(pFiler)) != Acad::eOk)
return es;
TCHAR* pszStr = NULL;
Adesk::Int32 nVt = 0;
pFiler->readInt16(&m_InSightStyle);
pFiler->readString(&pszStr);
m_strTH = pszStr;
pFiler->readString(&pszStr);
m_strBH = pszStr;
pFiler->readPoint3d((AcGePoint3d *)&m_ptIns);
pFiler->readDouble(&m_dRadius);
pFiler->readDouble(&m_dRotation);
pFiler->readDouble(&m_dValue);
pFiler->readInt32(&nVt);
pFiler->readItem(&m_bOldStyle);
pFiler->readItem(&m_dTextRatio);
m_nFlag = (int)nVt;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbInSight::dwgOutFields( AcDbDwgFiler* pFiler ) const
{
assertReadEnabled();
Acad::ErrorStatus es;
if ((es = TDbSymbWithText::dwgOutFields(pFiler)) != Acad::eOk)
return es;
pFiler->writeInt16(m_InSightStyle);
pFiler->writeString((LPCTSTR)m_strTH);
pFiler->writeString((LPCTSTR)m_strBH);
pFiler->writePoint3d((const AcGePoint3d &)m_ptIns);
pFiler->writeDouble(m_dRadius);
pFiler->writeDouble(m_dRotation);
pFiler->writeDouble(m_dValue);
pFiler->writeInt32(m_nFlag);
pFiler->writeItem(m_bOldStyle);
pFiler->writeItem(m_dTextRatio);
return pFiler->filerStatus();
}
// 提供对格式刷的支持
void TDbInSight::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbSymbWithText::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbInSight *pSrc = TDbInSight::cast(pSrcEntity);
if (pSrc != NULL)
{
m_nTextHeight = pSrc->m_nTextHeight; //字高
m_idTextStyle = pSrc->m_idTextStyle; //文字样式
m_colorText = pSrc->m_colorText; //文字颜色
m_dRadius = pSrc->m_dRadius; //半径
m_dRotation = pSrc->m_dRotation; //图案旋转角
m_dValue = pSrc->m_dValue; //预留
m_nFlag = pSrc->m_nFlag; //预留
m_dTextRatio = pSrc->m_dTextRatio;
}
}
void TDbInSight::SetAngle( double dRotation )
{
m_dRotation = dRotation;
}
double TDbInSight::GetAngle()
{
return m_dRotation;
}
double TDbInSight::GetTextRatio() const
{
double dRatio = m_dTextRatio;
if (fabs(dRatio) < 1.0E-3)
{
dRatio = DocGetDITextRatio();
}
return dRatio;
}
void TDbInSight::SetTextRatio( double dVal )
{
assertWriteEnabled();
m_dTextRatio = dVal;
}
void TDbInSight::SetOldStyle(int nDraw)
{
assertWriteEnabled();
m_bOldStyle = nDraw;
}
int TDbInSight::GetOldStyle() const
{
return m_bOldStyle;
}
void TDbInSight::SetRadius( double nRadius )
{
assertWriteEnabled();
m_dRadius = nRadius;
}
void TDbInSight::SetMapNoText( CString str )
{
assertWriteEnabled();
m_strTH= str;
}
void TDbInSight::SetNumberText( CString str )
{
assertWriteEnabled();
m_strBH = str;
}
int TDbInSight::GetFirstVersion() const
{
// 10 以下版本一概炸碎
return 10;
}