481 lines
11 KiB
C++
481 lines
11 KiB
C++
#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;
|
||
}
|