#include "stdafx.h" #include "globalFunc.h" #include "IntersectPointNumberDlg.h" #include #include #include #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 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 mapData; AcGePoint3d ptInt; std::vector vec; std::vector::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::iterator itM; for (itM = mapData.begin(); itM != mapData.end(); itM++) { vec.push_back((*itM).second); } } else // nRet == 2 || nRet == 3 { std::multimap::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; }