611 lines
13 KiB
C++
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);
|
|
}
|
|
}
|