Files
envi-code/SourceCode/Code2026/tg_shs/shs_public/CheckPipeMultDim.cpp
T

480 lines
11 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
#include "stdafx.h"
#include "CheckPipeMultDim.h"
#include "TDbPipeMultDim.h"
#include "TchGlobalFunc.h"
#include "TAPI.h"
#include "DbDoubleLinePipe.h"
#include "actrans.h"
namespace
{
// 是否需要修复
bool NeedRepairDim(TDbPipeMultDim *pDim)
{
DList<AcDbObjectId> lstPipe;
pDim->GetPipes(lstPipe);
int nLen = lstPipe.Length();
// 没有关联管线,需要修复
if (nLen == 0)
{
return true;
}
// 标注基线
XPoint pt1 = pDim->GetStartPoint();
XPoint pt2 = pDim->GetTurnPoint();
pt1.z = 0;
pt2.z = 0;
XLine lineBase(pt1, pt2, 1);
// 求交点
XPoint ptS, ptE;
for (int i = 0; i < nLen; ++i)
{
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, *lstPipe[i], AcDb::kForRead);
if (pPipe == NULL) // 无效id需要修复标注
{
return true;
}
ptS = pPipe->StartPoint();
ptE = pPipe->EndPoint();
pPipe->close();
ptS.z = 0.0;
ptE.z = 0.0;
XLine line(ptS, ptE, 1);
XPoint ptInt;
int ret = line.Intersection(&lineBase, ptInt); // 管线与标注线交点
if(!ptInt) // 无交点需要修复
{
return true;
}
}
return false;
}
// 需要修复的多管标注
void GetNeedRepairDim(std::vector<AcDbObjectId> &vecDim)
{
AcDbBlockTable *pBlockTable = NULL;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
if (pBlockTable == NULL)
{
return;
}
AcDbBlockTableRecord *pBlockTableRecord = NULL;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForRead);
pBlockTable->close();
if (pBlockTableRecord == NULL)
{
return;
}
// 遍历模型空间
AcDbBlockTableRecordIterator *it = NULL;
pBlockTableRecord->newIterator(it);
if (it == NULL)
{
pBlockTableRecord->close();
return;
}
for (it->start(); !it->done(); it->step())
{
AcDbEntity *pEnt = NULL;
if (it->getEntity(pEnt, AcDb::kForRead) != Acad::eOk)
{
continue;
}
// 不是多管标注
if (!pEnt->isKindOf(TDbPipeMultDim::desc()))
{
pEnt->close();
continue;
}
// 检查多管标注是否需要修复
if (NeedRepairDim((TDbPipeMultDim*)pEnt))
{
vecDim.push_back(pEnt->objectId());
}
pEnt->close();
}
delete it;
pBlockTableRecord->close();
}
// 求交
bool IntersetCurve(XLine &line, TGGeCurveSegment &seg, XPoint &ptInt)
{
if (seg.Is(CURVE_LINE))
{
XLine lineTemp = seg.GetLine();
lineTemp.SetLineFlag(1);
XPoint ptTemp;
line.Intersection(&lineTemp, ptTemp);
if (!!ptTemp)
{
ptInt = ptTemp;
return true;
}
}
else if (seg.Is(CURVE_ARC))
{
XArc arc = seg.GetArc();
XPoint pt1, pt2;
arc.Intersection(&line, pt1, pt2);
if (!!pt1 && !pt2)
{
ptInt = pt1;
return true;
}
}
return false;
}
}
// 检查多管标注
void CheckPipeMultDim()
{
// 检查是否有错误的多管标注
std::vector<AcDbObjectId> vecDim;
GetNeedRepairDim(vecDim);
if (vecDim.size() == 0)
{
acutPrintf(_T("\n检查完毕,未发现错误!"));
return;
}
// 显示检查对话框
CAcModuleResourceOverride vTemp;
CCheckPipeMultDim dlg;
dlg.SetCheckDim(vecDim);
dlg.DoModal();
}
IMPLEMENT_DYNAMIC(CCheckPipeMultDim, CDialog)
CCheckPipeMultDim::CCheckPipeMultDim(CWnd* pParent /*=NULL*/)
: CDialog(CCheckPipeMultDim::IDD, pParent)
{
}
CCheckPipeMultDim::~CCheckPipeMultDim()
{
}
void CCheckPipeMultDim::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_DIM, m_lstCtrlDim);
}
BEGIN_MESSAGE_MAP(CCheckPipeMultDim, CDialog)
ON_BN_CLICKED(IDOK, &CCheckPipeMultDim::OnBnClickedOk)
ON_BN_CLICKED(ID_BTN_SINGIN_REPAIR, &CCheckPipeMultDim::OnBnClickedBtnSinginRepair)
ON_BN_CLICKED(ID_BTN_ALL_REPAIR, &CCheckPipeMultDim::OnBnClickedBtnAllRepair)
ON_NOTIFY(NM_DBLCLK, IDC_LIST_DIM, &CCheckPipeMultDim::OnNMDblclkListDim)
END_MESSAGE_MAP()
BOOL CCheckPipeMultDim::OnInitDialog()
{
CDialog::OnInitDialog();
// 初始化CListCtrl
InitListCtrl();
// 更新CListCtrl
UpdateListCtrl();
return TRUE;
}
void CCheckPipeMultDim::OnBnClickedOk()
{
POSITION pos = m_lstCtrlDim.GetFirstSelectedItemPosition();
if(pos == NULL)
{
return;
}
int nIndex = m_lstCtrlDim.GetNextSelectedItem(pos);
ShowDim(m_vecDim[nIndex]);
}
void CCheckPipeMultDim::InitListCtrl()
{
LONG lStyle;
lStyle = GetWindowLong(m_lstCtrlDim.m_hWnd, GWL_STYLE);// 获取当前窗口style
lStyle &= ~LVS_TYPEMASK; // 清除显示方式位
lStyle |= LVS_REPORT; // 设置style
SetWindowLong(m_lstCtrlDim.m_hWnd, GWL_STYLE, lStyle);// 设置style
DWORD dwStyle = m_lstCtrlDim.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT; // 选中某行使整行高亮(只适用与report风格的listctrl)
dwStyle |= LVS_EX_GRIDLINES; // 网格线(只适用与report风格的listctrl)
m_lstCtrlDim.SetExtendedStyle(dwStyle); // 设置扩展风格
m_lstCtrlDim.InsertColumn(0, _T("实体编号"), LVS_ALIGNLEFT, 200);
}
void CCheckPipeMultDim::UpdateListCtrl()
{
m_lstCtrlDim.DeleteAllItems();
int nNum = 0;
CString sText;
std::vector<AcDbObjectId>::iterator it, itEnd = m_vecDim.end();
for (it = m_vecDim.begin(); it != itEnd; ++it)
{
int nIndex = m_lstCtrlDim.GetItemCount();
++nNum;
sText.Format(_T("%d#"), nNum);
nIndex = m_lstCtrlDim.InsertItem(nIndex, sText);
}
}
void CCheckPipeMultDim::SetCheckDim(std::vector<AcDbObjectId> &vecDim)
{
m_vecDim = vecDim;
m_mapDim.clear();
std::vector<AcDbObjectId>::iterator it, itEnd = m_vecDim.end();
for (it = m_vecDim.begin(); it != itEnd; ++it)
{
m_mapDim.insert(std::make_pair(*it, false));
}
}
void CCheckPipeMultDim::ShowDim(const AcDbObjectId &id)
{
TDbPipeMultDim *pDim = NULL;
acdbOpenObject(pDim, id, AcDb::kForRead);
if (pDim == NULL)
{
return;
}
XPoint ptStart = pDim->GetStartPoint();
XPoint ptTurn = pDim->GetTurnPoint();
double dScale = pDim->GetPScale();
pDim->close();
// 缩放视图
XPoint ptMid;
Midpoint(ptStart, ptTurn, ptMid);
double dWidth = ptStart.Distance2d(ptTurn) * 2;
double dHeight = dWidth * 1.5;
ArxZoomTo(ptMid, dWidth, dHeight);
// 绘制标志
XPoint ptCen = ptMid;
double dDist = dScale;
XPoint p1, p2, p3, p4;
ads_polar(ptCen, 0, dDist, p1);
ads_polar(p1, PI/2, dDist, p1);
ads_polar(ptCen, PI, dDist, p2);
ads_polar(p2, PI/2, -dDist, p2);
ads_grdraw(p1, p2, 2, 0);
ads_polar(ptCen, PI/2, dDist, p3);
ads_polar(p3, PI, dDist, p3);
ads_polar(ptCen, PI/2, -dDist, p4);
ads_polar(p4, 0, dDist, p4);
ads_grdraw(p3, p4, 2, 0);
HideDialog(this, TRUE);
TCHAR szTmp[256];
ads_getstring(NULL, _T("\n按任意键返回对话框:<返回>"), szTmp);
HideDialog(this, FALSE);
}
void CCheckPipeMultDim::OnBnClickedBtnSinginRepair()
{
POSITION pos = m_lstCtrlDim.GetFirstSelectedItemPosition();
if(pos == NULL)
{
MessageBox(_T("请选择需要修复的标注!"), _T("提示"));
return;
}
int nIndex = m_lstCtrlDim.GetNextSelectedItem(pos);
AcDbObjectId id = m_vecDim[nIndex];
if (m_mapDim[id])
{
acutPrintf(_T("\n已修复!"));
return;
}
// 修复标注
if (RepairDim(m_vecDim[nIndex]))
{
acutPrintf(_T("\n修复成功!"));
}
else
{
acutPrintf(_T("\n修复失败!"));
}
actrTransactionManager->flushGraphics(); //acad 刷新
acedUpdateDisplay(); //解决光标不在VIEW上无法刷新的问题
}
void CCheckPipeMultDim::OnBnClickedBtnAllRepair()
{
int nSucced = 0, nFail = 0;
int nCount = m_vecDim.size();
for (int i = 0; i < nCount; ++i)
{
AcDbObjectId id = m_vecDim[i];
// 已修复
if (m_mapDim[id])
{
continue;
}
// 修复
if (RepairDim(id))
{
++nSucced;
}
else
{
++nFail;
}
}
CString sTip;
sTip.Format(_T("\n成功修复%d个,还有%d个错误"), nSucced, nFail);
acutPrintf(sTip);
actrTransactionManager->flushGraphics(); //acad 刷新
acedUpdateDisplay(); //解决光标不在VIEW上无法刷新的问题
}
bool CCheckPipeMultDim::RepairDim(const AcDbObjectId &id)
{
// 管线数据
if (m_mapPipe.size() == 0)
{
GetPipeData();
}
// 没有获得管线数据
if (m_mapPipe.size() == 0)
{
return false;
}
// 标注基线
TDbPipeMultDim *pDim = NULL;
acdbOpenObject(pDim, id, AcDb::kForRead);
if (pDim == NULL)
{
return false;
}
XPoint pt1 = pDim->GetStartPoint();
XPoint pt2 = pDim->GetTurnPoint();
pDim->close();
pt1.z = 0;
pt2.z = 0;
XLine lineBase(pt1, pt2, 1);
// 与标注相交的管线
std::map<double, AcDbObjectId> mapDist; // 与标注相交的管线距离标注起点距离
std::map<AcDbObjectId, TGGeCurveSegment>::iterator it, itEnd = m_mapPipe.end();
for (it = m_mapPipe.begin(); it != itEnd; ++it)
{
XPoint ptInt;
// 无交点
if (!IntersetCurve(lineBase, it->second, ptInt))
{
continue;
}
// 保存交点
mapDist.insert(std::make_pair(ptInt.Distance2d(pt1), it->first));
}
// 没有找到与标注相交的管线
if (mapDist.size() == 0)
{
return false;
}
// 更新标注
acdbOpenObject(pDim, id, AcDb::kForWrite);
if (pDim == NULL)
{
return false;
}
pDim->assertWriteEnabled();
DList<AcDbObjectId> lstPipe;
std::map<double, AcDbObjectId>::iterator itPipe, itPipeEnd = mapDist.end();
for (itPipe = mapDist.begin(); itPipe != itPipeEnd; ++itPipe)
{
lstPipe.Append(new AcDbObjectId(itPipe->second));
}
pDim->SetPipes(lstPipe);
pDim->close();
m_mapDim[id] = true;
return true;
}
void CCheckPipeMultDim::GetPipeData()
{
// 获得管线基线
std::vector<AcDbObjectId> vecPipe;
GetAllPipes(vecPipe);
// 管线基线
XPoint ptS, ptE, ptMid;
TGGeCurveSegment seg;
std::vector<AcDbObjectId>::const_iterator it, itEnd = vecPipe.end();
for (it = vecPipe.begin(); it != itEnd; ++it)
{
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, *it, AcDb::kForRead);
if (pPipe != NULL)
{
ptS = pPipe->StartPoint();
ptE = pPipe->EndPoint();
ptS.z = 0.0;
ptE.z = 0.0;
if (pPipe->IsVertical()) // 立管
{
seg = XLine(ptS, ptE);
}
else if (fabs(pPipe->GetBulge()) > 0.001) // 弧管
{
ptMid = pPipe->MidPoint();
ptMid.z = 0.0;
seg = XArc(ptS, ptMid, ptE);
}
else // 直管
{
seg = XLine(ptS, ptE);
}
m_mapPipe.insert(std::make_pair(pPipe->objectId(), seg));
pPipe->close();
}
}
}
// 获得所有管线
void CCheckPipeMultDim::GetAllPipes(std::vector<AcDbObjectId> &vecPipe)
{
AcDbBlockTable *pBlockTable = NULL;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
if (pBlockTable == NULL)
{
return;
}
AcDbBlockTableRecord *pBlockTableRecord = NULL;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForRead);
pBlockTable->close();
if (pBlockTableRecord == NULL)
{
return;
}
// 遍历模型空间
AcDbBlockTableRecordIterator *it = NULL;
pBlockTableRecord->newIterator(it);
if (it == NULL)
{
pBlockTableRecord->close();
return;
}
for (it->start(); !it->done(); it->step())
{
AcDbEntity *pEnt = NULL;
if (it->getEntity(pEnt, AcDb::kForRead) != Acad::eOk)
{
continue;
}
// 管线
if (pEnt->isKindOf(TDbPipe::desc()) && !pEnt->isKindOf(TDbDoubleLinePipe::desc()))
{
vecPipe.push_back(pEnt->objectId());
}
pEnt->close();
}
pBlockTableRecord->close();
}
void CCheckPipeMultDim::OnNMDblclkListDim(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
ShowDim(m_vecDim[pNMItemActivate->iItem]);
*pResult = 0;
}