#include "stdafx.h" #include #include "KTInfoMonitor.h" #include "KTCadUtility.h" #include "KTCADUtilityEx.h" #include "AecDbportroom.h" #include "AecDbEarthWorm.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif namespace { void split(LPCTSTR pszSrc, TCHAR sp, std::vector &vec) { if (!pszSrc) return; vec.clear(); CString src(pszSrc); CString oneString(_T("")); TCHAR ch; for (int i = 0; i < src.GetLength(); ++i) { ch = src[i]; if (ch == sp) { if (oneString.IsEmpty()) continue; else { vec.push_back(oneString); oneString.Empty(); } } else oneString += ch; } if (!oneString.IsEmpty()) vec.push_back(oneString); } CString getNodeName(EFnctType type) { switch (type) { case kStartOrEnd: case kEspJoint: case kProModel: case kStackNode: case kRoomBroaden: case kRoomArcFillet: case kGripCtrlView: case kGripCtrlErase: case kSegGradient: case kSegElevation: case kSegCtrlOffset: case kSegStretchNew: case kSegStretchDir: case kGripPoint: break; case kDrainWell: return _T("集水井"); case kPipeDoghouse: return _T("管类投料口"); case kCableDoghouse: return _T("线缆类投料口"); case kHeatDoghouse: return _T("热力投料口"); case kVenDoghouse: return _T("通风口"); case kFirwWall: return _T("防火墙"); case kEscapeHatch: return _T("逃生人孔"); case kFireOutlet: return _T("消防引出口"); case kEWOutLethouse: return _T("水电管廊引出口"); case kHTOutLetHouse: return _T("热力舱引出口"); case kCrossUplifted: return _T("管廊交叉隆起"); case kUserDoghouse: return _T("任意开口上下左右"); case kSinkOutletRoom: return _T("管廊交叉交叉下沉"); case kSinkOutletRoom20: return _T("管廊交叉上部八边形上部结构"); case kSinkOutletRoom21: return _T("管廊交叉下沉八边形下部结构"); case kBDOutLetHouse: return _T("直埋引出"); case kSubEspJoint: return _T("变形缝"); case kVerticalWell: return _T("圆形或方型竖井"); default: break; } return _T(""); } Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt, AcDbDatabase* pDb = NULL, bool bClose = true) { if (pDb == NULL) pDb = acdbHostApplicationServices()->workingDatabase(); Acad::ErrorStatus es; AcDbBlockTable* pTbl = NULL; if (Acad::eOk == (es = pDb->getBlockTable(pTbl, AcDb::kForRead))) { AcDbBlockTableRecord* pBTR = NULL; if (Acad::eOk == (es = pTbl->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite))) { es = pBTR->appendAcDbEntity(pEnt); if (bClose) pEnt->close(); pBTR->close(); } pTbl->close(); } return es; } } KTInputMonitor::KTInputMonitor() : m_bEnabled(TRUE), m_pDocMonitor(NULL) { } KTInputMonitor::~KTInputMonitor() { Stop(); } BOOL KTInputMonitor::Start(AcApDocument* pDoc) { Stop(); if (NULL != pDoc) { pDoc->inputPointManager()->addPointMonitor(this); m_pDocMonitor = pDoc; } return TRUE; } BOOL KTInputMonitor::Stop() { if (NULL != m_pDocMonitor ) { m_pDocMonitor->inputPointManager()->removePointMonitor(this); m_pDocMonitor = NULL; } return TRUE; } BOOL KTInputMonitor::Stop(AcApDocument* pDoc) { if (NULL != m_pDocMonitor && pDoc == m_pDocMonitor ) { m_pDocMonitor->inputPointManager()->removePointMonitor(this); m_pDocMonitor = NULL; } return TRUE; } BOOL KTInputMonitor::IsEnabled() const { return m_bEnabled; } void KTInputMonitor::SetEnabled(BOOL bEnable) { m_bEnabled = bEnable; } Acad::ErrorStatus KTInputMonitor::monitorInputPoint(const AcEdInputPoint& input, AcEdInputPointMonitorResult& output) { int iCmdActive = 0; if (CKTCadUtility::GetSystemVar(_T("CMDACTIVE"), iCmdActive) && 0 == iCmdActive) { AcDbObjectId idEnt; if ( m_bEnabled && input.pointComputed() && !input.pickedEntities().isEmpty() ) { m_sInfoTip.Empty(); //if (input.tooltipString() != NULL) { AcDbObjectId idSub = input.pickedEntities().first(); if ( OnExtractAecDbInfo(idSub) || OnExtractEw(input.rawPoint(), idSub) ) { output.setAdditionalTooltipString((LPCTSTR)m_sInfoTip); //acutPrintf( _T("\nAppending %s"), output.additionalTooltipString() ); //acedPostCommandPrompt(); //OnHighlightEntity(idEnt, TRUE); } } } //OnHighlightEntity(m_idCurrent, FALSE); m_idCurrent = idEnt; } return Acad::eOk; } BOOL KTInputMonitor::OnHighlightEntity(AcDbObjectId idEnt, BOOL bHighlight) { if (idEnt.isNull()) return FALSE; ads_name ent; if (Acad::eOk != acdbGetAdsName(ent, idEnt)) return FALSE; ads_name ssSet; if (RTNORM == acedSSGet(_T("I"), NULL, NULL, NULL, ssSet)) { int iRet = acedSSMemb(ent, ssSet); acedSSFree(ssSet); if (RTNORM == iRet) return FALSE; } return (RTNORM == acedRedraw(ent, (bHighlight ? 3 : 4))); } BOOL KTInputMonitor::OnExtractAecDbInfo(AcDbObjectId& idEnt) { bool bRes = false; AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idEnt,AcDb::kForRead)) { AecDbPortRoom* pPortRoom = AecDbPortRoom::cast(pEnt); if (pPortRoom != NULL) { pEnt->close(); return FALSE; } AecDbEarthWorm* pEw = AecDbEarthWorm::cast(pEnt); if (pEw != NULL) { pEnt->close(); return FALSE; } AecDbEntityBase* pEntBase = AecDbEntityBase::cast(pEnt); if (pEntBase != NULL) { bRes = pEntBase->GetBimInfoTip(m_sInfoTip); } AecDbCurveBase* pCrvBase = AecDbCurveBase::cast(pEnt); if (pCrvBase != NULL) { bRes = pCrvBase->GetBimInfoTip(m_sInfoTip); } pEnt->close(); } return bRes ? TRUE : FALSE; } BOOL KTInputMonitor::OnExtractEw(const AcGePoint3d &pt, AcDbObjectId& idEnt) { // 舱室名-[功能1][功能2] typedef std::map > DataMap; DataMap datas; std::pair pr; AcDbObjectId idEw(idEnt); OPENOBJ_BEGIN(idEnt, AcDb::kForRead, AecDbPortRoom, pPr) { if (pPr) idEw = pPr->GetEWormId(); } OPENOBJ_END() OPENOBJ_BEGIN(idEw, AcDb::kForRead, AecDbEarthWorm, pEw) { if (!pEw) return false; AcArray arNodes; AcGePoint3dArray arNodePnts; CString type(_T("")), room(_T("")); AcDbCurve *pCurve = pEw->GetBaseCurve(); if (!pCurve) return false; AcGePoint3d ptOn(AcGePoint3d::kOrigin); pCurve->getClosestPointTo(pt, ptOn); DELETE_PTR(pCurve); pEw->GetFncNodeAt(ptOn, 5, arNodes, arNodePnts); for (int i = 0; i < arNodes.length(); ++i) { EWFnctNode &node = arNodes[i]; if (node.eFnType != kProModel) { type = getNodeName(node.eFnType); if (type.IsEmpty()) continue; room = pEw->GetRoomTypeByIdx(node.nRoomIndex); pr = datas.insert(std::make_pair(room, std::vector())); pr.first->second.push_back(type); } else { pr = datas.insert(std::make_pair(node.szNodeSpec, std::vector())); std::vector vec(0); split(node.szNodeDefSpec, _T('|'), vec); if (!vec.empty()) pr.first->second.assign(vec.begin(), vec.end()); } } } OPENOBJ_END() std::wstringstream ss; for (DataMap::iterator it = datas.begin(); it != datas.end(); ++it) { ss << (LPCTSTR)it->first << _T(":") << std::endl; std::vector &sub(it->second); for (size_t i = 0; i < sub.size(); ++i) { ss << _T("\t") << (LPCTSTR)sub[i] << std::endl; } } m_sInfoTip = ss.str().c_str(); return !m_sInfoTip.IsEmpty(); } KTInfoMonitor::KTInfoMonitor() { } KTInfoMonitor::~KTInfoMonitor() { } BOOL KTInfoMonitor::StartMonitor() { m_cInputMonitor.Start(curDoc()); //curDoc()->inputPointManager()->registerPointFilter( &m_cInputFilter ); acDocManager->addReactor(this); return TRUE; } BOOL KTInfoMonitor::StopMonitor() { acDocManager->removeReactor(this); m_cInputMonitor.Stop(); //m_cInputFilter.Stop(); return TRUE; } void KTInfoMonitor::documentCreated(AcApDocument * pDocCreating) { ASSERT(NULL != pActivatingDoc); m_cInputMonitor.Start(pDocCreating); //pDocCreating->inputPointManager()->registerPointFilter( &m_cInputFilter ); } void KTInfoMonitor::documentToBeActivated(AcApDocument* pActivatingDoc) { ASSERT(NULL != pActivatingDoc); m_cInputMonitor.Start(pActivatingDoc); //pActivatingDoc->inputPointManager()->registerPointFilter( &m_cInputFilter ); } void KTInfoMonitor::documentToBeDeactivated(AcApDocument* pDeActivatedDoc) { ASSERT(NULL != pDeActivatedDoc); m_cInputMonitor.Stop(); //m_cInputFilter.Stop(); } void KTInfoMonitor::documentToBeDestroyed(AcApDocument* pDocToDestroy) { m_cInputMonitor.Stop(pDocToDestroy); //m_cInputFilter.Stop(pDocToDestroy); } void KTInputContext::endSSGet(Acad::PromptStatus returnStatus, const AcArray& ss) { //acutPrintf(_T("\n%d"), ss.length()); } KTInputFilter::KTInputFilter() { } KTInputFilter::~KTInputFilter() { } BOOL KTInputFilter::Stop() { if ( NULL != curDoc()->inputPointManager()->currentPointFilter() ) { curDoc()->inputPointManager()->revokePointFilter(); } return TRUE; } BOOL KTInputFilter::Stop(AcApDocument* pDoc) { if ( NULL != pDoc->inputPointManager()->currentPointFilter() ) { pDoc->inputPointManager()->revokePointFilter(); } return TRUE; } Acad::ErrorStatus KTInputFilter::processInputPoint(const AcEdInputPoint& input, AcEdInputPointFilterResult& output) { if ( !input.pointComputed() ) return Acad::eOk; if ( 0 != input.pickedEntities().length() ) { m_sInfoTip.Empty(); AcDbObjectId idSub = input.pickedEntities().first(); if ( OnExtractAecDbInfo(idSub) || OnExtractEw(input.rawPoint(), idSub) ) { output.setNewTooltipString((LPCTSTR)m_sInfoTip); } } return Acad::eOk; } BOOL KTInputFilter::OnExtractAecDbInfo(AcDbObjectId& idEnt) { bool bRes = false; AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idEnt,AcDb::kForRead)) { AecDbPortRoom* pPortRoom = AecDbPortRoom::cast(pEnt); if (pPortRoom != NULL) { pEnt->close(); return FALSE; } AecDbEarthWorm* pEw = AecDbEarthWorm::cast(pEnt); if (pEw != NULL) { pEnt->close(); return FALSE; } AecDbEntityBase* pEntBase = AecDbEntityBase::cast(pEnt); if (pEntBase != NULL) { bRes = pEntBase->GetBimInfoTip(m_sInfoTip); } AecDbCurveBase* pCrvBase = AecDbCurveBase::cast(pEnt); if (pCrvBase != NULL) { bRes = pCrvBase->GetBimInfoTip(m_sInfoTip); } pEnt->close(); } return bRes ? TRUE : FALSE; } BOOL KTInputFilter::OnExtractEw(const AcGePoint3d &pt, AcDbObjectId& idEnt) { // 舱室名-[功能1][功能2] typedef std::map > DataMap; DataMap datas; std::pair pr; AcDbObjectId idEw(idEnt); OPENOBJ_BEGIN(idEnt, AcDb::kForRead, AecDbPortRoom, pPr) { if (pPr) idEw = pPr->GetEWormId(); } OPENOBJ_END() OPENOBJ_BEGIN(idEw, AcDb::kForRead, AecDbEarthWorm, pEw) { if (!pEw) return false; AcArray arNodes; AcGePoint3dArray arNodePnts; CString type(_T("")), room(_T("")); AcDbCurve *pCurve = pEw->GetBaseCurve(); if (!pCurve) return false; AcGePoint3d ptOn(AcGePoint3d::kOrigin); pCurve->getClosestPointTo(pt, ptOn); DELETE_PTR(pCurve); pEw->GetFncNodeAt(ptOn, 5, arNodes, arNodePnts); for (int i = 0; i < arNodes.length(); ++i) { EWFnctNode &node = arNodes[i]; if (node.eFnType != kProModel) { type = getNodeName(node.eFnType); if (type.IsEmpty()) continue; room = pEw->GetRoomTypeByIdx(node.nRoomIndex); pr = datas.insert(std::make_pair(room, std::vector())); pr.first->second.push_back(type); } else { pr = datas.insert(std::make_pair(node.szNodeSpec, std::vector())); std::vector vec(0); split(node.szNodeDefSpec, _T('|'), vec); if (!vec.empty()) pr.first->second.assign(vec.begin(), vec.end()); } } } OPENOBJ_END() std::wstringstream ss; for (DataMap::iterator it = datas.begin(); it != datas.end(); ++it) { ss << (LPCTSTR)it->first << _T(":") << std::endl; std::vector &sub(it->second); for (size_t i = 0; i < sub.size(); ++i) { ss << _T("\t") << (LPCTSTR)sub[i] << std::endl; } } m_sInfoTip = ss.str().c_str(); return !m_sInfoTip.IsEmpty(); } void KTDocReactor::documentCreated(AcApDocument * pDocCreating) { addReactor(pDocCreating); } void KTDocReactor::documentToBeDestroyed(AcApDocument * pDocToDestroy) { delReactor(pDocToDestroy); } void KTDocReactor::init() { AcApDocumentIterator *pIt = acDocManager->newAcApDocumentIterator(); while (pIt->done()) { AcApDocument *pDoc = pIt->document(); addReactor(pDoc); pIt->step(); } } void KTDocReactor::addReactor(AcApDocument * pDoc) { if (!pDoc) return; PtrMap::const_iterator it(m_adrMap.find(pDoc)); if (it == m_adrMap.end()) { KTInputContext *pIC = new KTInputContext(); pDoc->inputPointManager()->addInputContextReactor(pIC); m_adrMap.insert(std::make_pair(pDoc, pIC)); } } void KTDocReactor::delReactor(AcApDocument * pDoc) { PtrMap::iterator it(m_adrMap.find(pDoc)); if (it != m_adrMap.end()) { pDoc->inputPointManager()->removeInputContextReactor(it->second); DELETE_PTR(it->second); m_adrMap.erase(it); } }