#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 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 &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 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::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 &vecDim) { m_vecDim = vecDim; m_mapDim.clear(); std::vector::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 mapDist; // 与标注相交的管线距离标注起点距离 std::map::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 lstPipe; std::map::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 vecPipe; GetAllPipes(vecPipe); // 管线基线 XPoint ptS, ptE, ptMid; TGGeCurveSegment seg; std::vector::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 &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(pNMHDR); ShowDim(m_vecDim[pNMItemActivate->iItem]); *pResult = 0; }