Files
envi-code/SourceCode/Code2026/Dimension/IntersectPointNumberDlg.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

645 lines
17 KiB
C++

#include "stdafx.h"
#include "globalFunc.h"
#include "IntersectPointNumberDlg.h"
#include <vector>
#include <map>
#include <algorithm>
#include "PickEntSet.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//***************************************************************************************************
// 交点编号
//***************************************************************************************************
extern AcDbObjectId InitLayer(const TCHAR *szLayer, BOOL bApplyChange = TRUE);
extern void CheckIsPtOnPipe(XPoint ptIns, PickSet& ssSel);
extern CString GetLayerNames(const TCHAR * szTgSubName);
//void SetBlockAttribute(/*AcDbBlockReference *pRef*/AcDbObjectId ident, const CString& strText, int nAlign, const AcGePoint3d &ptInt, int nColor)
void SetBlockAttribute(AcDbObjectId ident, const CString& strText, int nAlign, const AcGePoint3d &ptInt, int nColor, double nHeight, AcDbObjectId idStyle)
{
AcDbBlockReference *pRef = NULL;
acdbOpenObject(pRef, ident, AcDb::kForWrite);
if (pRef != NULL)
{
//设置块颜色
pRef->setColorIndex(nColor);
AcDbObjectId idBlkRec = AcDbObjectId::kNull;
idBlkRec = pRef->blockTableRecord();
if (!idBlkRec.isValid())
{
return;
}
AcDbBlockTableRecord *pBlkRec = NULL;
Acad::ErrorStatus st = acdbOpenObject(pBlkRec, idBlkRec, AcDb::kForWrite);
if (pBlkRec != NULL)
{
AcDbBlockTableRecordIterator *pItr = NULL;
pBlkRec->newIterator(pItr);
AcDbEntity *pEnt = NULL;
for (pItr->start(); !pItr->done(); pItr->step())
{
pItr->getEntity(pEnt, AcDb::kForWrite);
if (pEnt != NULL)
{
pEnt->setColorIndex(nColor);
pEnt->close();
}
}
pBlkRec->close();
delete pItr;
pItr = NULL;
}
//设置属性字及其对齐方式
AcDbObjectIterator *pIter=pRef->attributeIterator();
if (pIter != NULL)
{
AcDbObjectId idAtt = AcDbObjectId::kNull;
for (pIter->start(); !pIter->done();pIter->step())
{
idAtt = pIter->objectId();
AcDbEntity *pEntAtrri = NULL;
Acad::ErrorStatus stus = acdbOpenAcDbEntity(pEntAtrri, idAtt, AcDb::kForWrite);
if (stus == Acad::eOk)
{
AcDbAttribute *pAtt = AcDbAttribute::cast(pEntAtrri);
if (pAtt != NULL)
{
TCHAR *pszName = pAtt->tag(); //得到标记
if(_tcsicmp(pszName, _T("交点编号")) == 0)
{
pAtt->setTextString(strText);
}
AcGePoint3d ptIns = pRef->position();
AcGeMatrix3d mat;
AcGeVector3d vec = AcGeVector3d::kXAxis;
vec = vec * (1.0 * GlobalFunc::DocGetPScale());
switch (nAlign)
{
case CIntersectPointNumberDlg::eLeftUp:
{
vec.rotateBy(PI * 3 / 4, AcGeVector3d::kZAxis);
pAtt->setHorizontalMode(AcDb::kTextRight);
pAtt->setVerticalMode(AcDb::kTextVertMid);
break;
}
case CIntersectPointNumberDlg::eLeft:
{
vec = -vec;
pAtt->setHorizontalMode(AcDb::kTextRight);
pAtt->setVerticalMode(AcDb::kTextVertMid);
break;
}
case CIntersectPointNumberDlg::eUp:
{
vec.rotateBy(PI / 2, AcGeVector3d::kZAxis);
pAtt->setHorizontalMode(AcDb::kTextMid);
pAtt->setVerticalMode(AcDb::kTextBottom);
break;
}
case CIntersectPointNumberDlg::eRightUp:
{
vec.rotateBy(PI / 4, AcGeVector3d::kZAxis);
pAtt->setHorizontalMode(AcDb::kTextLeft);
pAtt->setVerticalMode(AcDb::kTextVertMid);
break;
}
case CIntersectPointNumberDlg::eRight:
{
pAtt->setHorizontalMode(AcDb::kTextLeft);
pAtt->setVerticalMode(AcDb::kTextVertMid);
break;
}
case CIntersectPointNumberDlg::eRightDown:
{
vec.rotateBy(-PI / 4, AcGeVector3d::kZAxis);
pAtt->setHorizontalMode(AcDb::kTextLeft);
pAtt->setVerticalMode(AcDb::kTextVertMid);
break;
}
case CIntersectPointNumberDlg::eDown:
{
vec.rotateBy(-PI / 2, AcGeVector3d::kZAxis);
pAtt->setHorizontalMode(AcDb::kTextMid);
pAtt->setVerticalMode(AcDb::kTextTop);
break;
}
case CIntersectPointNumberDlg::eLeftDown:
{
vec.rotateBy(-PI * 3/ 4, AcGeVector3d::kZAxis);
pAtt->setHorizontalMode(AcDb::kTextRight);
pAtt->setVerticalMode(AcDb::kTextTop);
break;
}
}
mat.setTranslation(vec);
ptIns = GlobalFunc::Wcs2Ucs(ptIns);
ptIns.transformBy(mat);
ptIns = GlobalFunc::Ucs2Wcs(ptIns);
pAtt->setRotation(GlobalFunc::Ucs2Wcs(0.0));
pAtt->setHeight(nHeight * GlobalFunc::DocGetPScale());
pAtt->setTextStyle(idStyle);
pAtt->setAlignmentPoint(ptIns);
pAtt->setColorIndex(nColor);
}
pEntAtrri->close();
}
}
delete pIter;
pIter = NULL;
}
pRef->close();
}
}
AcDbBlockReference * CreateBlockReference(const AcDbObjectId& idBlock, const AcGePoint3d& ptPos)
{
if (idBlock.isNull())
{
return NULL;
}
// 创建块参照对象
AcDbBlockReference *pBlkRef = new AcDbBlockReference(ptPos, idBlock);
// 判断指定的块表记录是否包含属性定义
AcDbBlockTableRecord *pBlkDefRcd = NULL;
acdbOpenObject(pBlkDefRcd, idBlock, AcDb::kForRead);
if (pBlkDefRcd != NULL && pBlkDefRcd->hasAttributeDefinitions())
{
AcDbBlockTableRecordIterator *pItr;
pBlkDefRcd->newIterator(pItr);
AcDbEntity *pEnt;
for (pItr->start(); !pItr->done(); pItr->step())
{
pItr->getEntity(pEnt, AcDb::kForRead);
// 检查是否是属性定义
AcDbAttributeDefinition *pAttDef = NULL;
pAttDef = AcDbAttributeDefinition::cast(pEnt);
if (pAttDef != NULL)
{
// 创建一个新的属性对象
AcDbAttribute *pAtt = new AcDbAttribute();
// 从属性定义获得属性对象的对象特性
pAtt->setPropertiesFrom(pAttDef);
// 设置属性对象的其他特性
pAtt->setInvisible(pAttDef->isInvisible());
AcGePoint3d ptBase = pAttDef->position();
ptBase += pBlkRef->position().asVector();
pAtt->setPosition(ptBase);
pAtt->setHeight(pAttDef->height());
pAtt->setRotation(pAttDef->rotation());
// 获得属性对象的Tag、Prompt和TextString
TCHAR *pStr;
pStr = pAttDef->tag();
pAtt->setTag(pStr);
free(pStr);
pStr = pAttDef->textString();
pAtt->setTextString(pStr);
Adesk::UInt16 nLen = pAttDef->fieldLength();
pAtt->setFieldLength(nLen);
// 向块参照追加属性对象
pBlkRef->appendAttribute(pAtt);
pAtt->close();
}
pEnt->close();
pBlkRef->setBlockTableRecord(idBlock);
}
delete pItr;
pBlkDefRcd->close();
}
if (!pBlkDefRcd->hasAttributeDefinitions())
{
pBlkDefRcd->close();
}
return pBlkRef;
}
// void InsBlock(const AcDbObjectId &idBlock, const AcGePoint3d &ptInt, const CString strText, int nAlign = 0)
void InsBlock(const AcDbObjectId &idBlock, const AcGePoint3d &ptInt, const CString strText, double dHeight, AcDbObjectId id, int nAlign = 0)
{
// 创建图块
AcDbBlockReference *pRef = NULL;
pRef = CreateBlockReference(idBlock, ptInt);
if (pRef != NULL)
{
double dVal = GlobalFunc::DocGetPScale();
AcGeScale3d sca(dVal);
pRef->setScaleFactors(sca);
// 设置属性值
int nColor = 1; // 图块颜色
pRef->setLayer(InitLayer(_T("TWT_室外")));
AcDbObjectId ident = GlobalFunc::AddToCurrentSpace(pRef, Adesk::kTrue);
pRef->close();
SetBlockAttribute(ident, strText, nAlign, ptInt, nColor, dHeight, id);
}
}
void IntersectPointNumber()
{
CTemporaryResourceOverride vTemp;
CIntersectPointNumberDlg dlg(0, acedGetAcadFrame());
dlg.Create(IDD_INTERSECTPOINT_NUMBER, acedGetAcadFrame());
dlg.LoadTextStyle();
dlg.InitStyleId();
dlg.ShowWindow(SW_SHOW);
//加载图块
acDocManager->lockDocument(curDoc(),AcAp::kWrite,NULL,NULL,true);
XString xsBlk;
GlobalFunc::LoadDwbBlock(_T("TWTSYS"), _T("00000521"), xsBlk);
acDocManager->unlockDocument(curDoc());
AcDbObjectId idBlock = AcDbObjectId::kNull;
idBlock = GlobalFunc::GetBlkIdByName(_T("$TWTSYS$00000521"));
if (!idBlock.isValid())
{
acutPrintf(_T("\n交点编号图块加载失败!"));
return;
}
RBList rbMask(RTDXF0, _T("AEC_ZT_PIPE"), 8, GetLayerNames(_T("管线")), NULL);
Entity entPipe1 , entPipe2;
XPoint pt;
int nRet(0);
int nMode = OS_INT; // 设置捕捉
XPushVar<int> vOsModeOpen(_T("OSMODE"), nMode);
CString strTip = _T("\n请点取单个交叉点[多选交点(M)]<退出>:");
TCHAR szKey[32];
memset(szKey,0,32);
CString strKeyTip = _T("M");
while (TRUE)
{
INITGET_BEG(0, strKeyTip);
nRet = ads_getpoint(NULL, strTip, pt); // 选择操作
INITGET_END();
XPoint pt1, pt2, pt3, pt4;
if (nRet == RTKWORD) // 多选
{
PickSet ss(SS_FREE);
int nStatus(0);
TCHAR chKey;
INITGET_BEG(0, _T("P"));
nStatus = GlobalFunc::SelectEntities(_T("\n请框选范围{选择闭合pline线(P)}:<退出>"), ss, rbMask, _T("P"), chKey);
INITGET_END();
if (nStatus == RTKWORD) //选择关键字
{
Entity entPoly;
RBList rbMask2(RTDXF0, _T("LWPOLYLINE"), 8, _T("*"), NULL);
if(GlobalFunc::SelectEntity(_T("\n请选择表示范围的闭合PLINE:<退出>"), entPoly, rbMask2) != RTNORM)
{
continue;
}
AcDbObjectId idLine;
acdbGetObjectId(idLine, entPoly);
AcDbPolyline *pPLine = NULL;
acdbOpenObject(pPLine, idLine, AcDb::kForRead);
if (pPLine != NULL)
{
if (!pPLine->isClosed())
{
pPLine->close();
return;
}
pPLine->close();
}
XPoly2D poly2(entPoly);
XPoint ptLow3, ptUp3;
poly2.GetExtend(ptLow3, ptUp3);
poly2.TransUCS(RBGroups(0), RBGroups(1)); //RBGroups(0) wcs, RBGroups(1) ucs
RBList rbFence = poly2.Fence();
GlobalFunc::AssureInCurrentView(ptLow3, ptUp3);
ss.Get(_T("CP"), rbFence, NULL, rbMask);
}
else if(nStatus != RTNORM)
{
continue;
}
int nRet = 0;
acedGetInt(_T("\n请选择自动编号方案:{自左至右[1]/自右至左[2]/自上至下[3]/自下至上[4]}<1>:"), &nRet);
if (nRet != 2 && nRet != 3 && nRet != 4)
{
nRet = 1;
}
std::multimap<double, AcGePoint3d> mapData;
AcGePoint3d ptInt;
std::vector<AcGePoint3d> vec;
std::vector<AcGePoint3d>::iterator it;
for (long i = 0L; i < ss.Length(); i++)
{
entPipe1 = ss[i];
GlobalFunc::GetPipePoint(entPipe1, pt1, pt2); // 获取管线起始点
pt1[Z] = 0;
pt2[Z] = 0;
PickSet ssF(SS_FREE);
struct resbuf *pointlist;
ADSGePoint3d _pt1 = GlobalFunc::Wcs2Ucs(pt1);
ADSGePoint3d _pt2 = GlobalFunc::Wcs2Ucs(pt2);
pointlist = ads_buildlist(RTPOINT, &_pt1, RTPOINT, &_pt2, NULL);
ssF.Get(_T("F"), pointlist, NULL, rbMask);
ads_relrb(pointlist);
for (long j = 0; j < ssF.Length(); j++)
{
entPipe2 = ssF[j];
if (entPipe2 == entPipe1)
{
continue;
}
GlobalFunc::GetPipePoint(entPipe2, pt3, pt4);
pt3[Z] = 0;
pt4[Z] = 0;
// 求交点
AcDbLine l1(pt1, pt2), l2(pt3, pt4);
AcGePoint3dArray arPt;
l1.intersectWith(&l2, AcDb::kOnBothOperands, arPt);
if (arPt.length() == 1)
{
ptInt = arPt[0];
}
else
{
continue;
}
if (ptInt == pt1 || ptInt == pt2 || ptInt == pt3 || ptInt == pt4) // 是否在管线端点
{
continue;
}
it = std::find(vec.begin(), vec.end(), ptInt);
if (it == vec.end())
{
vec.push_back(ptInt);
}
}
}
for (it = vec.begin(); it != vec.end(); it++)
{
if (nRet == 2 || nRet == 1) // 按X坐标值存储数据
{
mapData.insert(std::make_pair((*it)[X], (*it)));
}
else if (nRet == 3 || nRet == 4) // 按Y坐标值存储数据
{
mapData.insert(std::make_pair((*it)[Y], (*it)));
}
}
vec.clear();
// 排序(按要求顺序存储)
if (nRet == 1 || nRet == 4)
{
std::multimap<double, AcGePoint3d>::iterator itM;
for (itM = mapData.begin(); itM != mapData.end(); itM++)
{
vec.push_back((*itM).second);
}
}
else // nRet == 2 || nRet == 3
{
std::multimap<double, AcGePoint3d>::reverse_iterator itM;
for (itM = mapData.rbegin(); itM != mapData.rend(); itM++)
{
vec.push_back((*itM).second);
}
}
CString strText ;
CString strPrefix = dlg.GetPrefix(), strNum = dlg.GetNumber();
int nAlign = dlg.GetTextAlign();
for (it = vec.begin(); it != vec.end(); it++)
{
strText = strPrefix + strNum;
//InsBlock(idBlock, *it, strText, nAlign);
InsBlock(idBlock, *it, strText, dlg.GetHeight(), dlg.GetStyleId(), nAlign);
dlg.Add(); //对话框编号加1
dlg.AutoAdd(strNum); // 图块编号加1
}
}
else if (nRet == RTNORM) // 单选
{
const double dLen = 2 * GlobalFunc::DocGetPScale();
pt1 = pt - AcGeVector3d::kXAxis * dLen + AcGeVector3d::kYAxis * dLen;
pt2 = pt - AcGeVector3d::kXAxis * dLen - AcGeVector3d::kYAxis * dLen;
pt3 = pt2 + AcGeVector3d::kXAxis * 2 * dLen;
pt4 = pt1 + AcGeVector3d::kXAxis * 2 * dLen;
PickSet ssSel(SS_FREE);
RBList rbPt = acutBuildList(RTPOINT,&pt1,RTPOINT,&pt2,RTPOINT,&pt3,RTPOINT,&pt4,NULL);
acedSSGet(_T("CP"),rbPt,NULL,rbMask,ssSel);
if (ssSel.Length() < 2)
{
continue;
}
else if (ssSel.Length() > 2)
{
// 检查经过pt点的管线,并存于ssSel
CheckIsPtOnPipe(GlobalFunc::Ucs2Wcs(pt), ssSel);
if (ssSel.Length() != 2)
{
continue;
}
}
entPipe1 = ssSel[0L];
entPipe2 = ssSel[1L];
GlobalFunc::GetPipePoint(entPipe1, pt1, pt2); // 获取管线起始点
GlobalFunc::GetPipePoint(entPipe2, pt3, pt4);
pt1[Z] = 0;
pt2[Z] = 0;
pt3[Z] = 0;
pt4[Z] = 0;
// 求交点
AcDbLine l1(pt1, pt2), l2(pt3, pt4);
AcGePoint3dArray arPt;
l1.intersectWith(&l2, AcDb::kOnBothOperands, arPt);
AcGePoint3d ptInt;
if (arPt.length() == 1)
{
ptInt = arPt[0];
}
else
{
continue;
}
// 判断交点是否在管线端点
if (ptInt == pt1 || ptInt == pt2 || ptInt == pt3 || ptInt == pt4)
{
continue;
}
// 插入图块
CString strText = dlg.GetPrefix() + dlg.GetNumber();
int nAlign = dlg.GetTextAlign();
//InsBlock(idBlock, ptInt, strText, nAlign);
InsBlock(idBlock, ptInt, strText, dlg.GetHeight(), dlg.GetStyleId(), nAlign);
dlg.Add(); //编号加1
}
else //退出
{
break;
}
}
if (!dlg.IsDestroy())
{
dlg.DestroyWindow();
}
}
IMPLEMENT_DYNAMIC(CIntersectPointNumberDlg, CModelessDialog)
CIntersectPointNumberDlg::CIntersectPointNumberDlg(int iType, CWnd* pParent /*=NULL*/)
: CModelessDialog(CIntersectPointNumberDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CIntersectPointNumberDlg)
m_strWndEdtNumber = _T("1");
m_strWndEdtPrefix = _T("");
m_nWndCmbTextPos = 0;
m_nHeight = 1.0;
m_strStyle = _T("");
//}}AFX_DATA_INIT
m_bDestroy = false;
}
void CIntersectPointNumberDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CIntersectPointNumberDlg)
DDX_Text(pDX, IDC_EDT_NUMBER, m_strWndEdtNumber);
DDX_Text(pDX, IDC_EDT_PREFIX, m_strWndEdtPrefix);
DDX_CBIndex(pDX, IDC_CMB_TEXTPOSITION, m_nWndCmbTextPos);
DDX_Control(pDX, IDC_COMBO_STYLE, m_comboStyle);
DDX_Text(pDX, IDC_COMBO_HEIGHT, m_nHeight);
DDX_Text(pDX, IDC_COMBO_STYLE, m_strStyle);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CIntersectPointNumberDlg, CModelessDialog)
//{{AFX_MSG_MAP(CIntersectPointNumberDlg)
ON_MESSAGE(WM_ACAD_KEEPFOCUS, onAcadKeepFocus)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, OnDeltaposSpin1)
ON_WM_CLOSE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
LONG_PTR CIntersectPointNumberDlg::onAcadKeepFocus(UINT_PTR, LONG_PTR)
{
CPoint pt;
GetCursorPos(&pt);
CRect rc;
GetWindowRect(&rc);
return (rc.PtInRect(pt) ? TRUE : FALSE);
}
void CIntersectPointNumberDlg::OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
UpdateData(TRUE);
int nNum = pNMUpDown->iDelta;
int nCount = _ttoi(m_strWndEdtNumber);
nCount -= nNum;
if (nCount == 0)
{
nCount = 1;
}
m_strWndEdtNumber.Format(_T("%d"), nCount);
UpdateData(FALSE);
*pResult = 0;
}
void CIntersectPointNumberDlg::OnClose()
{
DestroyWindow();
}
void CIntersectPointNumberDlg::OnDestroy()
{
m_bDestroy = TRUE;
CModelessDialog::OnDestroy();
acedPostCommand(_T("\33\33"));
}
bool CIntersectPointNumberDlg::IsDestroy()
{
return m_bDestroy;
}
// 对数字串加1
void CIntersectPointNumberDlg::AutoAdd(CString &strNumber)
{
strNumber = _T('1') + strNumber;
int nNum = _ttoi(strNumber);
++nNum;
strNumber.Format(_T("%d"), nNum);
TCHAR ch = strNumber.GetAt(0);
strNumber = strNumber.Right(strNumber.GetLength() - 1);
if (ch != _T('1'))
{
strNumber = _T("1") + strNumber;
}
}
void CIntersectPointNumberDlg::Add()
{
UpdateData(TRUE);
AutoAdd(m_strWndEdtNumber);
UpdateData(FALSE);
}
void CIntersectPointNumberDlg::LoadTextStyle()
{
AcDbDatabase *pCurDwg=acdbCurDwg();
AcDbTextStyleTable* pTT;
VERIFY(pCurDwg->getSymbolTable(pTT, AcDb::kForRead)==Acad::eOk);
AcDbTextStyleTableIterator* pIter = NULL;
VERIFY(pTT->newIterator(pIter)==Acad::eOk);
pTT->close();
for (pIter->start(); !pIter->done(); pIter->step())
{
AcDbTextStyleTableRecord* pTTR;
if (pIter->getRecord(pTTR, AcDb::kForRead) != Acad::eOk)
continue;
const TCHAR* pName = NULL;
if (pTTR->getName(pName) == Acad::eOk && pName != NULL)
{
if(m_lstStyle.Index(pName) < 0 ) // 如果没有重复
m_lstStyle.Append(tstrnew(pName)); // 读字体风格
}
pTTR->close();
}
delete pIter;
for (int m =0; m < m_lstStyle.Length(); m++)
m_comboStyle.AddString(m_lstStyle[m]);
UpdateData(false);
return;
}