#include "stdafx.h" #include "StdArx.h" #include "AecEwEditorReactor.h" #include "BimPaletteSet.h" #include "AecEwEndDeepCloneAssocMake.h" #include #include "AecDbEwEquipment.h" #include "KTCadUtility.h" #ifndef WM_PICKFIRSTMODIFIED #define WM_PICKFIRSTMODIFIED (WM_USER+0x1008) #endif #ifndef G_PSZMINFDXFNAMES #define G_PSZMINFDXFNAMES _T("AEC_EWPIPE,AEC_DBEWFIT,AEC_DBWEQUIPMENT,AEC_DBCABTRY,AEC_DBECFIT,AEC_DBDUCT,AEC_DBHVACFIT,AEC_3DROAD,AEC_ROADFIT") #endif extern GlobalContext* GetGlobalContext(); extern AcArray g_GripMessage; extern void PushGripMessage(GripMessage& msg); extern bool TransformAssocInf(AecInterface& inf,const AcGeMatrix3d& xform,const AcDbObjectId& idMsgFrom,AcDbObjectIdArray& arInfIds); AECDLLIMPEXP bool GetDoubleClickEntNoReset(LPCTSTR pszCmd,AcDbObjectId& id); AECDLLIMPEXP bool GetDoubleClickEnt(LPCTSTR pszCmd, AcDbObjectId &id); AecEwEditorReactor::AecEwEditorReactor(void) { m_nLastUserI4 = 0; } AecEwEditorReactor::~AecEwEditorReactor(void) { } void AecEwEditorReactor::commandWillStart(const ACHAR* cmdStr) { if (_tcscmp(cmdStr,_T("WBLOCK")) == 0 ) { m_nLastUserI4 = acdbCurDwg()->useri4(); acdbCurDwg()->setUseri4(KEY_NOPROTECT); } if (_tcscmp(cmdStr,_T("U")) == 0 || _tcscmp(cmdStr,_T("UNDO")) == 0) { TCHAR sbuf1[20]; struct resbuf eb1; eb1.restype = 0; _tcscpy(sbuf1, _T("AEC_EWFIT") ); eb1.resval.rstring = sbuf1; eb1.rbnext = NULL; ads_name ssSet,ent; int iRet = acedSSGet(_T("A"),NULL,NULL,&eb1,ssSet); Adesk::Int32 nLen = 0; acedSSLength(ssSet,&nLen); AcDbObjectId id; if (nLen == 1) { acedSSName(ssSet,0,ent); acdbGetObjectId(id,ent); } acedSSFree(ssSet); if (id.isValid()) { //是造簇文档. AecDbEarthWormFitting对象不单独存在于设计文档 acedPostCommand(_T("\x03")); acutPrintf(_T("\n造簇设计中不可以使用undo命令!!!")); } } if (_tcscmp(cmdStr,_T("GRIP_STRETCH")) == 0 ) { SHacedCommand(RTSTR,_T("_undo"),RTSTR,_T("BE"),RTNONE); struct resbuf rbAutoSnap; acedGetVar(_T("AUTOSNAP"),&rbAutoSnap); struct resbuf rb1; acedGetVar(_T("LASTPOINT"),&rb1); AcGePoint3d ptPick = asPnt3d(rb1.resval.rpoint); m_arInfs.removeAll(); struct resbuf *pGset = NULL,*pPSet = NULL; if (acedSSGetFirst(&pGset, &pPSet) == RTNORM) { //1.找到落在的实体上 ads_name ss,ent; AcDbObjectId id; ss[0] = pPSet->resval.rlname[0]; ss[1] = pPSet->resval.rlname[1]; Adesk::Int32 lLen = 0; acedSSLength(ss,&lLen); AecMInterfaces* pInf = NULL; for (long i = 0;i < lLen;i++) { acedSSName(ss,i,ent); acdbGetObjectId(id,ent); AcGePoint3dArray arPoints; AcDbIntArray osnapModes,geomIds; AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead)) { if (pEnt->cloneMeForDragging()) { //管线 if (pEnt->isKindOf(AecDbEwPipe::desc())) { AecDbEwPipe* pPipe = AecDbEwPipe::cast(pEnt); pInf = static_cast(pPipe); } if (pEnt->isKindOf(AecDbEwFitting::desc())) { AecDbEwFitting* pEwFit = AecDbEwFitting::cast(pEnt); pInf = static_cast(pEwFit); } if (pEnt->isKindOf(AecDbEwEquipment::desc())) { AecDbEwEquipment* pEqu = AecDbEwEquipment::cast(pEnt); pInf = static_cast(pEqu); } //桥架 if (pEnt->isKindOf(AecDbECableTray::desc())) { AecDbECableTray* pTray = AecDbECableTray::cast(pEnt); pInf = static_cast(pTray); } if (pEnt->isKindOf(AecDbEcFitting::desc())) { AecDbEcFitting* pEcFit = AecDbEcFitting::cast(pEnt); pInf = static_cast(pEcFit); } //风管 if (pEnt->isKindOf(AecDbHvacDuct::desc())) { AecDbHvacDuct* pDuct = AecDbHvacDuct::cast(pEnt); pInf = static_cast(pDuct); } if (pEnt->isKindOf(AecDbHvacFitting::desc())) { AecDbHvacFitting* pHvacFit = AecDbHvacFitting::cast(pEnt); pInf = static_cast(pHvacFit); } //道路 //道路 if (pEnt->isKindOf(AecDb3dRoad::desc())) { AecDb3dRoad* pRoad = AecDb3dRoad::cast(pEnt); pInf = static_cast(pRoad); } if (pEnt->isKindOf(AecDb3dRoadFitting::desc())) { AecDb3dRoadFitting* pRoadFit = AecDb3dRoadFitting::cast(pEnt); pInf = static_cast(pRoadFit); } if (pInf != NULL) { pInf->GetInterface(m_arInfs); pEnt->close(); break; } } pEnt->close(); } } if (pGset != NULL) acutRelRb(pGset); if (pPSet != NULL) acutRelRb(pPSet); } } //双击编辑管线,特指标高产生的更新关系联动 if (_tcscmp(cmdStr,_T("DBL_AEC_EWPIPE")) == 0 || _tcscmp(cmdStr, _T("DBL_AEC_EWPIPE_SPEC")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_DBCABTRY")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_DBDUCT")) == 0 || _tcscmp(cmdStr, _T("PL_GXGMSUB")) == 0 ) { if (_tcscmp(cmdStr, _T("DBL_AEC_EWPIPE_SPEC")) != 0 ) { m_arInfs.removeAll(); } AcDbObjectId idHost; GetDoubleClickEntNoReset(cmdStr,idHost); AcDbEntity* pEnt = NULL; AecMInterfaces* pInf = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idHost,AcDb::kForRead)) { //管道 if (pEnt->isKindOf(AecDbEwPipe::desc())) { AecDbEwPipe* pPipe = AecDbEwPipe::cast(pEnt); pInf = static_cast(pPipe); } //桥架 if (pEnt->isKindOf(AecDbECableTray::desc())) { AecDbECableTray* pTray = AecDbECableTray::cast(pEnt); pInf = static_cast(pTray); } //风管 if (pEnt->isKindOf(AecDbHvacDuct::desc())) { AecDbHvacDuct* pDuct = AecDbHvacDuct::cast(pEnt); pInf = static_cast(pDuct); } //道路 if (pEnt->isKindOf(AecDb3dRoad::desc())) { AecDb3dRoad* pRoad = AecDb3dRoad::cast(pEnt); pInf = static_cast(pRoad); } if (pEnt->isKindOf(AecDb3dRoadFitting::desc())) { AecDb3dRoadFitting* pRoadFit = AecDb3dRoadFitting::cast(pEnt); pInf = static_cast(pRoadFit); } if (pInf != NULL) { pInf->GetInterface(m_arInfs); } pEnt->close(); } } } void AecEwEditorReactor::commandEnded(LPCTSTR cmdStr) { if (_tcscmp(cmdStr,_T("WBLOCK")) == 0 ) { acdbCurDwg()->setUseri4(m_nLastUserI4); } if (_tcscmp(cmdStr,_T("GRIP_STRETCH")) == 0 || _tcscmp(cmdStr,_T("EW_DXLS")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_EWPIPE") ) == 0 || _tcscmp(cmdStr, _T("DBL_AEC_EWPIPE_SPEC")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_DBCABTRY")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_DBDUCT")) == 0 || _tcscmp(cmdStr,_T("PL_GXGMSUB")) == 0 ) { while (!g_GripMessage.isEmpty()) { GripMessage msg; PickGripMessage(msg); //消息如果是为下一个命令使用,则填回 if (msg.nType == kGripMsgContinue) { PushGripMessage(msg); break; } if (msg.nType == kSegStretchNew || msg.nType == kSegStretchDir) { acedPostCommand(_T("EW_SEGOFFSET\n")); } else { if (_tcscmp(cmdStr,_T("GRIP_STRETCH")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_EWPIPE")) == 0 || _tcscmp(cmdStr, _T("DBL_AEC_EWPIPE_SPEC")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_DBCABTRY")) == 0 || _tcscmp(cmdStr,_T("DBL_AEC_DBDUCT")) == 0 || _tcscmp(cmdStr, _T("PL_GXGMSUB")) == 0 ) { if (msg.nType >= eStart && msg.nType <= eInf10) { //消息沿接口路线传递 TransformAssocInfMsg(msg); } else if (msg.nType == eAdjust0)//更新三维,来自 AecDbX3dPartEntity 夹点变动消息 { AcDbEntity* pEnt = NULL; AcDbObjectId id = msg.idHost; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { AecDbEwPipeBase* pPB = AecDbEwPipeBase::cast(pEnt); if (pPB != NULL) { pPB->ReCreateDraw3d(); } /*AecDbSlab* pSlab = AecDbSlab::cast(pEnt); if (pSlab != NULL) { }*/ pEnt->close(); } } SHacedCommand(RTSTR,_T("_undo"),RTSTR,_T("E"),RTNONE); } } } if (_tcscmp(cmdStr, _T("DBL_AEC_EWPIPE_SPEC")) == 0) { m_arInfs.removeAll(); } } else if (_tcscmp(cmdStr,_T("ERASE")) == 0 ) { if (!g_GripMessage.isEmpty()) { GripMessage& msg = g_GripMessage.last(); if (msg.nType == eInfErase && !msg.bCmdPosted) { msg.bCmdPosted = true; CString sCmd = msg.szUser; if (!sCmd.IsEmpty()) { //只是发出,没有立刻执行 sCmd += _T("\n"); acedPostCommand(sCmd); } } } } //对于门窗等的复制,建立新的关系 if (!m_arIdEndDeepCloned.isEmpty()) { AecEwEndDeepCloneAssocMake makeAssoc(m_arIdEndDeepCloned); m_arIdEndDeepCloned.removeAll(); } } void AecEwEditorReactor::commandCancelled(const ACHAR* cmdStr) { if (_tcscmp(cmdStr,_T("WBLOCK")) == 0 ) { acdbCurDwg()->setUseri4(m_nLastUserI4); } //对于门窗等的复制,建立新的关系 if (!m_arIdEndDeepCloned.isEmpty()) { AecEwEndDeepCloneAssocMake makeAssoc(m_arIdEndDeepCloned); m_arIdEndDeepCloned.removeAll(); } } void AecEwEditorReactor::commandFailed(const ACHAR* cmdStr) { if (_tcscmp(cmdStr,_T("WBLOCK")) == 0 ) { acdbCurDwg()->setUseri4(m_nLastUserI4); } //对于门窗等的复制,建立新的关系 if (!m_arIdEndDeepCloned.isEmpty()) { AecEwEndDeepCloneAssocMake makeAssoc(m_arIdEndDeepCloned); m_arIdEndDeepCloned.removeAll(); } } void AecEwEditorReactor::pickfirstModified() { AcDbObjectIdArray ids(0); ads_name ss, ent; acedSSGet(_T("I"), NULL, NULL, NULL, ss); Adesk::Int32 len(0); acedSSLength(ss, &len); AcDbObjectId id; for (long i = 0; i < len; i++) { acedSSName(ss, i, ent); if (acdbGetObjectId(id, ent) == Acad::eOk) ids.append(id); } acedSSFree(ss); if (::IsWindow(g_bimPaletteSet::instance().m_hWnd)) { g_bimPaletteSet::instance().SetObjectIds(ids); } if (!ids.isEmpty()) { id = ids.first(); AcDbHandle hD = id.handle(); HWND hWnd = GetGlobalContext()->hWnd; if (::IsWindow(hWnd)) { static TCHAR szHandle[33]; memset(szHandle,0,sizeof(TCHAR)*33); hD.getIntoAsciiBuffer(szHandle); ::SendMessage(hWnd,WM_PICKFIRSTMODIFIED,(WPARAM)szHandle,0); } } } //不公开的消息传递处理机制,不在头文件中体现 bool ImpTransformAssocInfMsg( const AecInterface& infFr,AcDbVoidPtrArray& arMInfPtrs,std::map* >& mapMInfToInfs,const AcGeMatrix3d& xformM) { double dUnit = 1.0; struct resbuf rb; acedGetVar(_T("INSUNITS"), &rb); if (rb.resval.rint == AcDb::kUnitsMeters) { dUnit = 0.001; } bool bTransformed = false; bool bTransformedContinue = false; AecMInterfaces* pMInf = NULL; AecMInterfaces* pMInfT = NULL; AcArray* pInfs = NULL; int nIndexDone = -1; int nMIndexDone = -1; typedef std::map* >::iterator MIMapIt; for (int i = 0;i < arMInfPtrs.length();i++) { pMInf = (AecMInterfaces*)arMInfPtrs.at(i); nMIndexDone = i; //获取没有处理前的接口集合 pInfs = NULL; //pMInf->GetInterface(arAllInfs);//必须获取的是旧接口 MIMapIt it = mapMInfToInfs.find(pMInf); if (it == mapMInfToInfs.end()) { continue; } pInfs = (*it).second; for(int j = 0;j < pInfs->length();j++) { AecInterface& infTo = pInfs->at(j); //对上 if (infFr.ptPos.distanceTo(infTo.ptPos) < (0.01 * dUnit + infTo.dGasket))// { AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,infTo.idOwner,AcDb::kForWrite) ) { if (pEnt->isKindOf(AecDbEwPipe::desc())) { AecDbEwPipe* pPipe = AecDbEwPipe::cast(pEnt); pMInfT = static_cast(pPipe); } if (pEnt->isKindOf(AecDbEwFitting::desc())) { AecDbEwFitting* pFitting = AecDbEwFitting::cast(pEnt); pMInfT = static_cast(pFitting); } if (pEnt->isKindOf(AecDbEwEquipment::desc())) { AecDbEwEquipment* pEqu = AecDbEwEquipment::cast(pEnt); pMInfT = static_cast(pEqu); } //桥架 if (pEnt->isKindOf(AecDbECableTray::desc())) { AecDbECableTray* pTray = AecDbECableTray::cast(pEnt); pMInfT = static_cast(pTray); } if (pEnt->isKindOf(AecDbEcFitting::desc())) { AecDbEcFitting* pEcFit = AecDbEcFitting::cast(pEnt); pMInfT = static_cast(pEcFit); } //风管 if (pEnt->isKindOf(AecDbHvacDuct::desc())) { AecDbHvacDuct* pDuct = AecDbHvacDuct::cast(pEnt); pMInfT = static_cast(pDuct); } if (pEnt->isKindOf(AecDbHvacFitting::desc())) { AecDbHvacFitting* pHvacFit = AecDbHvacFitting::cast(pEnt); pMInfT = static_cast(pHvacFit); } //道路 if (pEnt->isKindOf(AecDb3dRoad::desc())) { AecDb3dRoad* pRoad = AecDb3dRoad::cast(pEnt); pMInfT = static_cast(pRoad); } if (pEnt->isKindOf(AecDb3dRoadFitting::desc())) { AecDb3dRoadFitting* pRoadFit = AecDb3dRoadFitting::cast(pEnt); pMInfT = static_cast(pRoadFit); } //传本接口变换 -> 内部会导致其他接口变化 //不移除本接口集 pMInf ,其其他接口继续处理 bTransformedContinue = pMInfT->TransformAssocInf(j,xformM); pEnt->close(); nIndexDone = j; bTransformed = true; arMInfPtrs.removeAt(nMIndexDone); } break; } } if (bTransformed) { break; } } if (bTransformedContinue && bTransformed )//旧的其他接口继续处理 { if (pInfs != NULL) { pInfs->removeAt(nIndexDone); for (int i = 0;i < pInfs->length();i++) { AecInterface& infTo = pInfs->at(i); ImpTransformAssocInfMsg(infTo,arMInfPtrs,mapMInfToInfs,xformM);//继续传递处理 } } } else { //其其他接口不处理 } return bTransformed; } void AecEwEditorReactor::TransformAssocInfMsg(const GripMessage& msg) { //效率??, 后期提升 struct resbuf* pRb = acutBuildList(RTDXF0, G_PSZMINFDXFNAMES , 0); ads_name ss,ent; acedSSGet(_T("A"),NULL,NULL,pRb,ss); acutRelRb(pRb); AcDbObjectId idT; Adesk::Int32 lLen = 0; acedSSLength(ss,&lLen); AcDbEntity* pEnt = NULL; AecMInterfaces* pInf = NULL; AcDbVoidPtrArray arMInfPtrs; std::map* > mapMInfToInfs; for (long j = 0;j < lLen;j++) { acedSSName(ss,j,ent); acdbGetObjectId(idT,ent); if (msg.idHost != idT)//排除自身 { if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idT,AcDb::kForRead)) { if (pEnt->isKindOf(AecDbEwPipe::desc())) { AecDbEwPipe* pPipe = AecDbEwPipe::cast(pEnt); pInf = static_cast(pPipe); } if (pEnt->isKindOf(AecDbEwFitting::desc())) { AecDbEwFitting* pFitting = AecDbEwFitting::cast(pEnt); pInf = static_cast(pFitting); } if (pEnt->isKindOf(AecDbEwEquipment::desc())) { AecDbEwEquipment* pEqu = AecDbEwEquipment::cast(pEnt); pInf = static_cast(pEqu); } //桥架 if (pEnt->isKindOf(AecDbECableTray::desc())) { AecDbECableTray* pTray = AecDbECableTray::cast(pEnt); pInf = static_cast(pTray); } if (pEnt->isKindOf(AecDbEcFitting::desc())) { AecDbEcFitting* pEcFit = AecDbEcFitting::cast(pEnt); pInf = static_cast(pEcFit); } //风管 if (pEnt->isKindOf(AecDbHvacDuct::desc())) { AecDbHvacDuct* pDuct = AecDbHvacDuct::cast(pEnt); pInf = static_cast(pDuct); } if (pEnt->isKindOf(AecDbHvacFitting::desc())) { AecDbHvacFitting* pHvacFit = AecDbHvacFitting::cast(pEnt); pInf = static_cast(pHvacFit); } //道路 if (pEnt->isKindOf(AecDb3dRoad::desc())) { AecDb3dRoad* pRoad = AecDb3dRoad::cast(pEnt); pInf = static_cast(pRoad); } if (pEnt->isKindOf(AecDb3dRoadFitting::desc())) { AecDb3dRoadFitting* pRoadFit = AecDb3dRoadFitting::cast(pEnt); pInf = static_cast(pRoadFit); } if (pInf != NULL) { AcArray* pInfs = new AcArray; pInf->GetInterface(*pInfs); std::pair*> pairT; pairT.first = pInf; pairT.second = pInfs; mapMInfToInfs.insert(pairT); arMInfPtrs.append(pInf); } pEnt->close(); } } } acedSSFree(ss); if (pInf == NULL) return; //找消息路线 // +----> + ..... // + ..... // + ----> + ---> // + ... if (msg.nData != -1)//消息触发接口索引 { if (!m_arInfs.isEmpty()) { //只从本触发接口发送消息 AecInterface infHit = m_arInfs.at(msg.nData); m_arInfs.removeAll(); m_arInfs.append(infHit); } else { return; } } AcGeMatrix3d xformM; xformM.setToTranslation(msg.vtOffset); for (int i = 0;i < m_arInfs.length();i++) { AecInterface& inf = m_arInfs.at(i);//消息源接口 //传递消息处理 ImpTransformAssocInfMsg(inf,arMInfPtrs,mapMInfToInfs,xformM); } //Free map typedef std::map* >::iterator MIMapIt; for (MIMapIt it = mapMInfToInfs.begin();it != mapMInfToInfs.end();it++) { AcArray* pInfs = (*it).second; if (pInfs != NULL) { delete pInfs; } } } void AecEwEditorReactor::endDeepClone(AcDbIdMapping& idMapping) { AcDbDatabase* pDbDest = NULL; idMapping.destDb(pDbDest); if (pDbDest == acdbCurDwg() && pDbDest != NULL) { AcDbObjectId idVal; AcDbIdPair idPair; AcDbIdMappingIter mapIter(idMapping); for (mapIter.start(); !mapIter.done(); mapIter.next()) { if (mapIter.getMap(idPair)) { idVal = idPair.value(); m_arIdEndDeepCloned.append(idVal); } } } } void AecEwEditorReactor::sysVarChanged(const ACHAR *varName, Adesk::Boolean success) { // typedef if (success && CString(varName).MakeLower() == _T("insunits")) { #ifndef ZWCAD CString dllPath(FilePath::GetArxDir() + _T("\\Dimension.arx")); #else CString dllPath(FilePath::GetArxDir() + _T("\\Dimension.zrx")); #endif typedef int(_cdecl *getUnitOfDraw)(); typedef void(_cdecl *setUnitOfDraw)(const bool &); HMODULE hmod = ::LoadLibrary(dllPath); if (!hmod) return; getUnitOfDraw func_getUnitOfDraw = (getUnitOfDraw)::GetProcAddress(hmod, "getUnitOfDraw"); setUnitOfDraw func_setUnitOfDraw = (setUnitOfDraw)::GetProcAddress(hmod, "setUnitOfDraw"); if (!func_getUnitOfDraw || !func_setUnitOfDraw) { ::FreeLibrary(hmod); return; } bool bMeter = func_getUnitOfDraw() == 0 ? false : true; int v(AcDb::kUnitsMillimeters); // 默认毫米 CKTCadUtility::GetSystemVar(_T("INSUNITS"), v); if (v == AcDb::kUnitsMillimeters) // 毫米 { if (bMeter) // 当前是米单位,改为毫米 func_setUnitOfDraw(0); // 设置为毫米 } else if (v == AcDb::kUnitsMeters) // 米 { if (!bMeter) // 当前是毫米单位,改为米 func_setUnitOfDraw(1); // 设置为米 } ::FreeLibrary(hmod); } }