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

733 lines
18 KiB
C++

#include "StdAfx.h"
#include "CoordGrid.h"
#include "dbcolor.h"
#include "DataLoadAndSave.h"
#include "GlwGlobalVariable.h"
#include "CroodGridSetDlg.h"
#define TARCH20_SYMBOL_KEY_COORDGRID_CSTRING _T("CoordGrid_CString") //注册表项
#define TARCH20_SYMBOL_TERMNAME _T("AllControlWndData\\CoordGridWndData") //键
#define DIVSTRING _T("^@^") //分割符号
namespace
{
#if ADS <= 18
double _ttof(LPCTSTR psz)
{
if (!psz) return .0;
USES_CONVERSION;
return atof(W2A(psz));
}
#endif
}
//坐标网格
void SymbCoordGrid()
{
AcDbObjectId idTextStyle = InitTextStyle(TS_SYMBOL);
if (!idTextStyle)
return;
CcoordGridSetDlg* pDlg = new CcoordGridSetDlg(acedGetAcadFrame());
pDlg->Create(IDD_DIALOG_CROODGRID);
pDlg->ShowWindow(SW_SHOW);
//命令退出标识
bool bExit = false;
acedGetAcadDwgView()->SetFocus();
while(1)
{
// 标记是否使用了ESC退出
pDlg->m_bUseEsc = true;
bool bContinueDraw = true;
if(!GET_GLOBAL_VARIABLE(CCoordGridDataManage))
SET_GLOBAL_VARIABLE(CCoordGridDataManage, new CCoordGridDataManage);
CCoordGridDataManage *pDataManage = GET_GLOBAL_VARIABLE(CCoordGridDataManage);
TADSGePoint3d ptUpLeft, ptLowRight;
if (kSelectPolyLine == pDataManage->GetDrawType())
{
Entity entPoly;
THookMsg hookmsg;
TRBList rbFilter(acutBuildList(RTDXF0, _T("CIRCLE,POLYLINE,LWPOLYLINE"), NULL));
if (SelectEntity(_T("\n请选择网格边框线<退出>: "), entPoly,
rbFilter) != RTNORM)
{
int vn = hookmsg.GetValue();
if(vn == 0 && GetFocus() == acedGetAcadDwgView()->GetSafeHwnd())//当前焦点在CAD上,并且没有选中
{
acutPrintf(_T("\n请选择一多段线!"));
continue;
}
else
{
if (pDlg->m_bUseEsc) // != RTNORM,并且没有切换绘制方式,命令真正结束
break;
else
bContinueDraw = false;
}
}
else
{
XPoly2D poly2d(entPoly);
XPoint pt1, pt2;
if (kLineGrid == pDataManage->GetGirdType())
{
for (int i = 0; i < poly2d.Length(); ++i)
{
WCS2UCS(*poly2d.GetAt(i)); //世界坐标系转用户坐标系
}
}
poly2d.GetExtend(pt1, pt2);
XRectAngle rect(pt1, pt2);
ptUpLeft = rect.GetUpLeft();
ptLowRight = rect.GetLowRight();
}
}
else
{
XPoint ptCorner1, ptCorner2;
if (ads_getpoint(NULL, _T("\n请点取网格角点<退出>:"), ptCorner1) == RTNORM &&
XGetCorner(ptCorner1, _T("\n请点取另一个角点<退出>: "), ptCorner2) == RTNORM)
{
if (kCrossGrid == pDataManage->GetGirdType())//用户坐标系下绘制十字网格,转到世界坐标系
{
XRectAngle rect(ptCorner1, ptCorner2);
XPoly2D poly2d;
poly2d.AppendNode(rect.GetLowRight(), 0);
poly2d.AppendNode(rect.GetUpRight(), 0);
poly2d.AppendNode(rect.GetUpLeft(), 0);
poly2d.AppendNode(rect.GetLowLeft(), 0);
int nTest = poly2d.Length();
for (int i = 0; i < poly2d.Length(); ++i)
{
TADSGePoint3d pt = *poly2d.GetAt(i);
*poly2d.GetAt(i) = Ucs2Wcs(pt); //用户坐标系转世界坐标系
}
XPoint pt1, pt2;
poly2d.GetExtend(pt1, pt2);
XRectAngle rectWCS(pt1, pt2);
ptUpLeft = rectWCS.GetUpLeft();
ptLowRight = rectWCS.GetLowRight();
}
else//网格通线
{
XRectAngle rect(ptCorner1, ptCorner2);
ptUpLeft = rect.GetUpLeft();
ptLowRight = rect.GetLowRight();
}
}
else
{
if (pDlg->m_bUseEsc) // != RTNORM,并且没有切换绘制方式,命令真正结束
{
break;
}
else
bContinueDraw = false;
}
}
if (bContinueDraw)
{
CCoordGridDrawStyle coordGridStyle;
if (kCrossGrid == pDataManage->GetGirdType())
{
coordGridStyle.DrawCroosGridrInterface(ptUpLeft, ptLowRight, pDataManage->GetGridSpacing());
}
else
{
coordGridStyle.DrawLineGridInterface(ptUpLeft, ptLowRight, pDataManage->GetGridSpacing());
}
}
if (pDlg->m_bUseEsc) // != RTNORM,并且没有切换绘制方式,命令真正结束
{
break;
}
}
if (pDlg)
{
pDlg->DestroyWindow();
delete pDlg;
}
};
/************************************************************************/
/*CCoordGridDrawStyle */
/************************************************************************/
bool CCoordGridDrawStyle::GetEdgePoints(TADSGePoint3d ptLeftTop, TADSGePoint3d ptRightBottom, int nGridSpacing)
{
_int64 iGridSpacing = nGridSpacing;
int iVerticalNum = abs( (ptRightBottom.x / iGridSpacing) - (ptLeftTop.x / iGridSpacing));
if (ptRightBottom.x * ptLeftTop.x <= 0)
iVerticalNum++;
int iHorizonNum = abs((ptLeftTop.y / iGridSpacing) - (ptRightBottom.y / iGridSpacing));
if (ptRightBottom.y * ptLeftTop.y <= 0)
iHorizonNum++;
if (iVerticalNum < 0 || iHorizonNum < 0)
return false;
m_ptsLeft.Reset();
m_ptsRight.Reset();
m_ptsTop.Reset();
m_ptsBottom.Reset();
//获得左右边线点,x不变,y变化
_int64 nModNum = 0, nModNum2 = 0;
for (int i = 0; i < iHorizonNum; ++i)
{
TADSGePoint3d *pPostionLeft = new TADSGePoint3d();
pPostionLeft->x = ptLeftTop.x;
if (i == 0)
{
nModNum = (ptRightBottom.y + (i + 1) * iGridSpacing) / iGridSpacing;
if (ptRightBottom.y + (i + 1) * iGridSpacing < 0 || ptRightBottom.y == 0)
{
nModNum--;
}
pPostionLeft->y = nModNum * iGridSpacing;
}
else
{
nModNum++;
pPostionLeft->y = nModNum * iGridSpacing;
}
m_ptsLeft.Append(pPostionLeft);
TADSGePoint3d *pPostionRight = new TADSGePoint3d();
pPostionRight->x = ptRightBottom.x;
if (i == 0)
{
nModNum2 = (ptRightBottom.y + (i + 1) * iGridSpacing) / iGridSpacing;
if (ptRightBottom.y + (i + 1) * iGridSpacing < 0 || ptRightBottom.y == 0)
{
nModNum2--;
}
pPostionRight->y = nModNum2 * iGridSpacing;
}
else
{
nModNum2++;
pPostionRight->y = nModNum2 * iGridSpacing;
}
m_ptsRight.Append(pPostionRight);
}
//获取上下边先,y不变,x变化
for (int i = 0; i < iVerticalNum; ++i)
{
TADSGePoint3d *pPostionTop = new TADSGePoint3d();
pPostionTop->y = ptLeftTop.y;
if (i == 0)
{
nModNum = (ptLeftTop.x + (i + 1) * iGridSpacing) / iGridSpacing;
if ((ptLeftTop.x + (i + 1) * iGridSpacing) < 0 || ptLeftTop.x == 0)
{
nModNum--;
}
pPostionTop->x = nModNum * iGridSpacing;
}
else
{
nModNum++;
pPostionTop->x = nModNum * iGridSpacing;
}
m_ptsTop.Append(pPostionTop);
TADSGePoint3d *pPostionBottom = new TADSGePoint3d();
pPostionBottom->y = ptRightBottom.y;
if (i == 0)
{
nModNum2 = (ptLeftTop.x + (i + 1) * iGridSpacing) / iGridSpacing;
if ((ptLeftTop.x + (i + 1) * iGridSpacing) < 0 || ptLeftTop.x == 0)
{
nModNum2--;
}
pPostionBottom->x = nModNum2 * iGridSpacing;
}
else
{
nModNum2++;
pPostionBottom->x = nModNum2 * iGridSpacing;
}
m_ptsBottom.Append(pPostionBottom);
}
return true;
}
//功能:给点一个点,绘制世界坐标的十字交叉线,需要判断当前图纸单位
void CCoordGridDrawStyle::DrawCrossLine(TADSGePoint3d ptPosition)
{
TADSGePoint3d ptLeft, ptRight, ptTop, ptBottom; //世界坐标系
if (DocGetMeterUnitDraw())
{
ptLeft.y = ptPosition.y;
ptLeft.x = ptPosition.x - 2.5;
ptRight.y = ptPosition.y;
ptRight.x = ptPosition.x + 2.5;
ptTop.x = ptPosition.x;
ptTop.y = ptPosition.y + 2.5;
ptBottom.x = ptPosition.x;
ptBottom.y = ptPosition.y - 2.5;
}
else
{
ptLeft.y = ptPosition.y;
ptLeft.x = ptPosition.x - 2500;
ptRight.y = ptPosition.y;
ptRight.x = ptPosition.x + 2500;
ptTop.x = ptPosition.x;
ptTop.y = ptPosition.y + 2500;
ptBottom.x = ptPosition.x;
ptBottom.y = ptPosition.y - 2500;
}
AcDbLine *pLineL2R = new AcDbLine();
pLineL2R->setStartPoint(ptLeft);
pLineL2R->setEndPoint(ptRight);
AcDbLine *pLineT2B= new AcDbLine();
pLineT2B->setStartPoint(ptTop);
pLineT2B->setEndPoint(ptBottom);
pLineL2R->setLayer(InitLayer(LAY_COORD_GRID));
pLineT2B->setLayer(InitLayer(LAY_COORD_GRID));
AddToModelSpace(pLineL2R);
AddToModelSpace(pLineT2B);
}
//功能:根据上下左右边界点,生成十字交叉线,返回生成的十字交叉线个数
int CCoordGridDrawStyle::DrawCroosGrid()
{
//生成线
if (m_ptsLeft.Length() != m_ptsRight.Length() || m_ptsTop.Length() != m_ptsBottom.Length())
return 0;
if (m_ptsLeft.Length() < 2 || m_ptsTop.Length() < 2)
return 0;
TDPtrList<TGGeLine> lstSegLinesL2R, lstSegLinesT2B;
for (int i = 0; i < m_ptsLeft.Length(); ++i)
{
TGGeLine *pSeg = new TGGeCurveSegment(LS_INFINITE);
pSeg->SetStartPoint(*m_ptsLeft.GetAt(i));
pSeg->SetEndPoint(*m_ptsRight.GetAt(i));
lstSegLinesL2R.Append(pSeg);
}
for (int i = 0; i < m_ptsTop.Length(); ++i)
{
TGGeLine *pSeg = new TGGeCurveSegment(LS_INFINITE);
pSeg->SetStartPoint(*m_ptsTop.GetAt(i));
pSeg->SetEndPoint(*m_ptsBottom.GetAt(i));
lstSegLinesT2B.Append(pSeg);
}
TDPtrList<TADSGePoint3d> ptList;
for(int i = 0; i < lstSegLinesL2R.Length(); i++)
{
TGGeLine line1(LS_INFINITE);
line1 = *lstSegLinesL2R[i];
for(int j = 0; j < lstSegLinesT2B.Length(); j++)
{
TGGeLine line2(LS_INFINITE);
line2 = *lstSegLinesT2B[j];
ads_point ptAds = {0,0,0};
line1.Intersection(&line2, ptAds);
TADSGePoint3d *pPtInter = new TADSGePoint3d(ptAds);
ptList.Append(pPtInter);
}
}
for (int i = 0; i < ptList.Length(); ++i)
{
DrawCrossLine(*ptList[i]);
}
return ptList.Length();
}
//功能:根据上下左右边界点,生成十字交叉线,返回生成的十字交叉线个数
int CCoordGridDrawStyle::DrawLineGrid()
{
//生成线
if (m_ptsLeft.Length() != m_ptsRight.Length() || m_ptsTop.Length() != m_ptsBottom.Length())
return 0;
if (m_ptsLeft.Length() < 2 || m_ptsTop.Length() < 2)
return 0;
int iLineNum = 0;
for (int i = 0; i < m_ptsLeft.Length(); ++i)
{
AcDbLine *pLine = new AcDbLine();
TADSGePoint3d ptStart = *m_ptsLeft.GetAt(i);
TADSGePoint3d ptEnd = *m_ptsRight.GetAt(i);
ptStart = Ucs2Wcs(ptStart);
ptEnd = Ucs2Wcs(ptEnd);
pLine->setStartPoint(ptStart);
pLine->setEndPoint(ptEnd);
pLine->setLayer(InitLayer(LAY_COORD_GRID));
AddToModelSpace(pLine);
iLineNum++;
}
for (int i = 0; i < m_ptsTop.Length(); ++i)
{
AcDbLine *pLine = new AcDbLine();
TADSGePoint3d ptStart = *m_ptsTop.GetAt(i);
TADSGePoint3d ptEnd = *m_ptsBottom.GetAt(i);
ptStart = Ucs2Wcs(ptStart);
ptEnd = Ucs2Wcs(ptEnd);
pLine->setStartPoint(ptStart);
pLine->setEndPoint(ptEnd);
pLine->setLayer(InitLayer(LAY_COORD_GRID));
AddToModelSpace(pLine);
iLineNum++;
}
return iLineNum;
}
bool CCoordGridDrawStyle::DrawCroosGridrInterface(TADSGePoint3d ptLeftTop, TADSGePoint3d ptRightBottom, int iGridSpacing)
{
if (!GetEdgePoints(ptLeftTop, ptRightBottom, iGridSpacing))
return false;
if (0 == DrawCroosGrid())
{
adsout<<_T("\n输入的范围太小,请重新输入!");
return false;
}
DrawTextSymbol(kCrossGrid);
return true;
}
bool CCoordGridDrawStyle::DrawLineGridInterface(TADSGePoint3d ptLeftTop, TADSGePoint3d ptRightBottom, int iGridSpacing)
{
if (!GetEdgePoints(ptLeftTop, ptRightBottom, iGridSpacing))
return false;
if (0 == DrawLineGrid())
{
adsout<<_T("\n输入的范围太小,请重新输入!");
return false;
}
DrawTextSymbol(kLineGrid);
return true;
}
//功能:根据上下左右边界点,以及网格类型,生成不同的标注点
void CCoordGridDrawStyle::DrawTextSymbol(int nType)
{
double dDis2Gird = 2500;//文字距离网格距离
double dDividend = 1000.0;//坐标网格均以米为单位进行标注
if(!GET_GLOBAL_VARIABLE(CCoordGridDataManage))
SET_GLOBAL_VARIABLE(CCoordGridDataManage, new CCoordGridDataManage);
CCoordGridDataManage *pDataManage = GET_GLOBAL_VARIABLE(CCoordGridDataManage);
bool bEquationForm = pDataManage->GetEquationForm();
if (DocGetMeterUnitDraw())
{
dDis2Gird = 2.5;
dDividend = 1.0;
}
for (int i = 0; i < m_ptsLeft.Length(); ++i)
{
CString strText(_T(""));
XPoint ptTextPosition;
ptTextPosition.x = m_ptsLeft.GetAt(i)->x - dDis2Gird;
ptTextPosition.y = m_ptsLeft.GetAt(i)->y;
if (nType == kCrossGrid)
{
if (bEquationForm)
strText = _T("X=");
else
strText = _T("X");
}
else
{
if (bEquationForm)
strText = _T("A=");
else
strText = _T("A");
}
CString strTemp(_T(""));
strTemp.Format(_T("%g"), m_ptsLeft.GetAt(i)->y / dDividend);
strText += strTemp;
DrawTDbText(strText, ptTextPosition);
}
for (int i = 0; i < m_ptsBottom.Length(); ++i)
{
CString strText(_T(""));
XPoint ptTextPosition;
ptTextPosition.x = m_ptsBottom.GetAt(i)->x;
ptTextPosition.y = m_ptsBottom.GetAt(i)->y - dDis2Gird;
if (nType == kCrossGrid)
{
if (bEquationForm)
strText = _T("Y=");
else
strText = _T("Y");
}
else
{
if (bEquationForm)
strText = _T("B=");
else
strText = _T("B");
}
CString strTemp(_T(""));
strTemp.Format(_T("%g"), m_ptsBottom.GetAt(i)->x / dDividend);
strText += strTemp;
//当前坐标系
double dDirAng = AcGeVector3d::kXAxis.angleTo(AcGeVector3d::kYAxis, AcGeVector3d::kZAxis);
DrawTDbText(strText, ptTextPosition, dDirAng);
}
}
void CCoordGridDrawStyle::DrawTDbText (CString &strText, XPoint &ptLocation, double dDirAng)
{
if(!GET_GLOBAL_VARIABLE(CCoordGridDataManage))
SET_GLOBAL_VARIABLE(CCoordGridDataManage, new CCoordGridDataManage);
CCoordGridDataManage *pDataManage = GET_GLOBAL_VARIABLE(CCoordGridDataManage);
TDbText *pText = new TDbText;
pText->SetText(strText);
if (kLineGrid == pDataManage->GetGirdType())
{
ptLocation = Ucs2Wcs(ptLocation);
dDirAng = Ucs2Wcs(dDirAng);
}
pText->SetLocation(ptLocation);
pText->SetRotation(dDirAng);
pText->SetStyleId(InitTextStyle(pDataManage->GetTextStyle()));
pText->SetHeight(pDataManage->GetTextHeight());
pText->SetAlignment(XExplodeDraw::kMiddleRight);
AcCmColor color;
#if ADS > 23
#if defined(ZWCAD) && ADS < 25
color.setColor(AcCmEntityColor::kByLayer);
#else
color.setByLayer();
#endif
#else
color.setColor(AcCmEntityColor::kByLayer);
#endif
pText->setColor(color);
pText->setLayer(InitLayer(LAY_COORD_GRID));
AddToModelSpace(pText);
}
/************************************************************************/
/* CCoordGridDataManage */
/************************************************************************/
namespace
{
int SplitString(LPCTSTR pszOri, LPCTSTR pszSplit, std::vector<CString> &vec)
{
do
{
if (!pszOri) break;
vec.clear();
if (!pszSplit)
{
vec.push_back(pszOri);
return 1;
}
CString sOri(pszOri), sSplit(pszSplit), sRel(_T(""));
int nSplitLen(sSplit.GetLength()), nFindPos(0), nRel(0);
while ((nFindPos = sOri.Find(sSplit, 0)) != -1)
{
sRel = sOri.Mid(0, nFindPos);
vec.push_back(sRel);
sOri = sOri.Right(sOri.GetLength() - nFindPos - nSplitLen);
++nRel;
}
if (!sOri.IsEmpty())
{
vec.push_back(sOri);
++nRel;
}
return nRel;
} while (false);
return 0;
}
CString MergeStr(const std::vector<CString>& subStr)
{
CString str = _T("");
CString strTemp = _T("");
std::vector<CString>::const_iterator iter = subStr.begin();
if (iter == subStr.end())
return str;
strTemp = *iter;
if (strTemp.IsEmpty()) strTemp = _T(" ");
str += strTemp;
++iter;
for (iter; iter != subStr.end(); ++iter)
{
strTemp = *iter;
if (strTemp.IsEmpty()) strTemp = _T(" ");
str += DIVSTRING + strTemp;
}
return str;
}
}
CCoordGridDataManage::CCoordGridDataManage(void)
{
m_iGridType = kCrossGrid;
m_iDrawType = kSelectDiagonalPt;
m_iGridSpacing = 100;
m_strTextStyle = _T("_TCH_DIM");
m_dTextHeight = 3.5;
m_bEquationForm = false;
SetDefalutTextStyleAndTextHight();
//读取注册表
CString strTmp;
std::vector<CString> strWndData;
DataLoadAndSave::readRecordDataCString(TARCH20_SYMBOL_KEY_COORDGRID_CSTRING, strTmp, TARCH20_SYMBOL_TERMNAME);
strWndData.clear();
SplitString(strTmp, DIVSTRING, strWndData);
int iDataNum = strWndData.size();
if (iDataNum == 4)
{
m_iGridType = _ttoi(strWndData.at(0));
m_iDrawType = _ttoi(strWndData.at(1));
m_iGridSpacing = _ttoi(strWndData.at(2));
//m_strTextStyle = strWndData.at(3);
//m_dTextHeight = _ttof(strWndData.at(4));
m_bEquationForm = _ttoi(strWndData.at(3));
}
}
CCoordGridDataManage::~CCoordGridDataManage()
{
std::vector<CString> strWndData;
strWndData.clear();
CString strDataInfo(_T(""));
strDataInfo.Format(_T("%d"), m_iGridType);
strWndData.push_back(strDataInfo);
strDataInfo.Format(_T("%d"), m_iDrawType);
strWndData.push_back(strDataInfo);
strDataInfo.Format(_T("%d"), m_iGridSpacing);
strWndData.push_back(strDataInfo);
//strWndData.push_back(m_strTextStyle);
//strDataInfo.Format(_T("%g"), m_dTextHeight);
//strWndData.push_back(strDataInfo);
if (m_bEquationForm)
strDataInfo = _T("1");
else
strDataInfo = _T("0");
strWndData.push_back(strDataInfo);
CString strTmp = MergeStr(strWndData);//组合字符串
DataLoadAndSave::writeRecordDataCString(TARCH20_SYMBOL_KEY_COORDGRID_CSTRING, strTmp, TARCH20_SYMBOL_TERMNAME);
}
int CCoordGridDataManage::GetGridSpacing() //获取网格间距
{
if (!DocGetMeterUnitDraw())
return m_iGridSpacing * 1000;
return m_iGridSpacing;
}
// 读取路径
CString CCoordGridDataManage::GetFullPath(const TCHAR *szFileName)
{
CString szFullPath = g_sDwbPath;
// 文件的路径
if (_tcscmp(szFileName, _T("")) == 0)
{
szFullPath = szFullPath.Left(szFullPath.GetLength() - 5) + _T("\\sys\\");
}
else
{
szFullPath = szFullPath.Left(szFullPath.GetLength() - 5) + _T("\\sys\\") + szFileName;
// 用于动态添加文字样式文件时使用
CString csTmp = szFileName;
if (csTmp.Find(_T(".")) == -1)
{
szFullPath += _T(".tts");
}
}
return szFullPath;
}
//获取默认的文字样式和文字字高
void CCoordGridDataManage::SetDefalutTextStyleAndTextHight()
{
//判断TextStyleDef.DAT文件路径是否存在
CString szTextStyleDefFile(_T(""));
szTextStyleDefFile = GetFullPath(_T("TextStyleDef.DAT"));
if (_taccess(szTextStyleDefFile, 0) == -1)
return;
//读取文件内容
CStdioFile file;
if (!file.Open(szTextStyleDefFile, CFile::modeRead))
{
AfxMessageBox(CString(_T("打开文件 \"")) + szTextStyleDefFile + _T("\" 失败"));
return;
}
CString sReadString(_T(""));
while (file.ReadString(sReadString))
{
TCHAR sKey[256] = _T(""); // 关键字
TCHAR sName[256] = _T(""); // 样式名称
TCHAR sChinese[265] = _T(""); // 中文字体
TCHAR sEnglish[256] = _T(""); // 西文字体
TCHAR sWindows[256] = _T(""); // Windows字体
float dHeigh(0.0), // 字高
dChineseScale(0.0), // 中文宽高比
dHeighScale(0.0), // 高度比例
dWideScale(0.0); // 宽度比例
//int nColor = 0; // 颜色
TCHAR sNote[256] = _T(""); // 备注
// 读出数据
_stscanf(sReadString, _T("%s%s%s%s%s%f%f%f%f%s"), sKey, sName, sWindows, sChinese, sEnglish,
&dChineseScale, &dHeighScale, &dWideScale, &dHeigh, sNote);
if (_tcscmp(sKey, _T("其他符号")) == 0)
{
m_dTextHeight = dHeigh;
m_strTextStyle = sName;
break;
}
}
file.Close();
}