Files
envi-code/SourceCode/Code2026/CoreLibrary/KTInfoMonitor.cpp
T
2026-09-28 15:28:50 +08:00

611 lines
13 KiB
C++

#include "stdafx.h"
#include <sstream>
#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<CString> &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<CString, std::vector<CString> > DataMap;
DataMap datas;
std::pair<DataMap::iterator, bool> 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<EWFnctNode> 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<CString>()));
pr.first->second.push_back(type);
}
else
{
pr = datas.insert(std::make_pair(node.szNodeSpec, std::vector<CString>()));
std::vector<CString> 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<CString> &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<AcDbObjectId>& 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<CString, std::vector<CString> > DataMap;
DataMap datas;
std::pair<DataMap::iterator, bool> 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<EWFnctNode> 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<CString>()));
pr.first->second.push_back(type);
}
else
{
pr = datas.insert(std::make_pair(node.szNodeSpec, std::vector<CString>()));
std::vector<CString> 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<CString> &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);
}
}