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

481 lines
11 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 "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;
}