#ifndef __PIPEWIREMONITOR_H #define __PIPEWIREMONITOR_H #include "acedinpt.h" #include "PipeTools.h" #include "PipePrototype.h" // sg modify,由于多次互相包含导致编译错误,将以下两个类移至NodeAssistant.h #include "NodeAssistant.h" // TEntRect、TNodeLocation #if ADS > 15 #include "AcStatusBar.h" #endif //用来监视管线的状态 // 监视管线系统的数据库变化 class PS_IMPEXP TPipeDbReactor : public AcDbDatabaseReactor { public: TPipeDbReactor() { } static void Attach(); static void Detach(); virtual void objectErased( const AcDbDatabase* dwg, const AcDbObject* dbObj, Adesk::Boolean pErased = Adesk::kTrue); virtual void objectAppended( const AcDbDatabase* dwg, const AcDbObject* dbObj); virtual void objectModified( const AcDbDatabase* dwg, const AcDbObject* dbObj); void ObjectChanged(const AcDbObject *dbObj, int nChgFlag); virtual void headerSysVarChanged(const AcDbDatabase* db, const TCHAR* name, Adesk::Boolean bSuccess);//2011-10-11 sr add 检测系统变量 }; //用来监视命令执行的状态 class PS_IMPEXP TPipeCmdReactor: public AcEditorReactor { public: static TPipeCmdReactor *g_pCmdReactor; // Myself public: TPipeCmdReactor(); ~TPipeCmdReactor(); public: static void Attach(); static void Detach(); static void BeginUserCommand(const TCHAR *pszCommand, BOOL bArxCommand); static void EndUserCommand(const TCHAR *pszCommand, BOOL bArxCommand); static void ResetAll(); public: virtual void lispWillStart(const TCHAR * firstLine); virtual void lispEnded(); virtual void commandWillStart(const TCHAR * cmdStr); virtual void commandEnded(const TCHAR *cmsStr); virtual void commandCancelled(const TCHAR * cmdStr); virtual void commandFailed(const TCHAR * cmdStr); virtual void pickfirstModified(); virtual void beginDoubleClick(const AcGePoint3d& clickPoint); virtual void endWblock (AcDbDatabase* pTo); }; class TPipeDocReactor: public AcApDocManagerReactor { public: TPipeDocReactor() {} virtual void documentToBeActivated(AcApDocument* pDoc); virtual void documentCreated(AcApDocument* pDoc); virtual void documentToBeDestroyed(AcApDocument* pDoc); }; class TPipeInputReactor : public AcEdInputContextReactor { public: virtual void endEntsel(Acad::PromptStatus returnStatus, AcDbObjectId& entPicked, AcGePoint3d& pickPoint, const TCHAR* pKeyword); }; #if(ADS>15) class TLayerPane:public AcPane { public: virtual BOOL GetToolTipText(CString& strText) const{strText="当前图层";return TRUE;} // virtual void OnLButtonDown(UINT nFlags, CPoint point); // virtual void OnRButtonDown(UINT nFlags,CPoint point); void Update(); void Init(bool bTrue=true); }; #endif // ADS>15 /* class TEntRect { public: AcDbObjectId id; XRectAngle rect; public: TEntRect(const TEntRect& ent): id(ent.id),rect(ent.rect){ } TEntRect(const AcDbObjectId& id,const XPoint& ptMin,const XPoint& ptMax) :id(id),rect(ptMin,ptMax){} BOOL Intersect(const XRectAngle &box) const { return ExtendInBox02d(rect.lowLeft,rect.upRight,box); } BOOL Intersect(const TEntRect& other) const { return Intersect(other.rect); } BOOL InBox(const XRectAngle &box) const { return ExtendInBox2d(rect.lowLeft,rect.upRight,box); } static int CompareObjectId(const TEntRect *p1, const void *pId) { return !(p1->id==*(const AcDbObjectId *)pId); } void operator += (const TEntRect& ent) { rect.lowLeft.x = min(ent.rect.lowLeft.x, rect.lowLeft.x); rect.lowLeft.y = min(ent.rect.lowLeft.y, rect.lowLeft.y); rect.upRight.x = max(ent.rect.upRight.x, rect.upRight.x); rect.upRight.y = max(ent.rect.upRight.y, rect.upRight.y); } }; class TNodeLocation { public: AcDbObjectId id; XPoint ptLocation; public: TNodeLocation(const XPoint& pt):ptLocation(pt){} TNodeLocation(const TNodeLocation& node):id(node.id),ptLocation(node.ptLocation){} TNodeLocation(const AcDbObjectId& id,const XPoint& pt):id(id),ptLocation(pt) {} BOOL Intersect(const XRectAngle &box,double nSnap=PS_SNAP) const { return !(ptLocation.x-box.upRight.x > nSnap || ptLocation.y-box.upRight.y > nSnap || box.lowLeft.x-ptLocation.x > nSnap || box.lowLeft.y-ptLocation.y > nSnap); } BOOL Intersect(const TEntRect& ent,double nSnap=PS_SNAP) const { return Intersect(ent.rect,nSnap); } BOOL Intersect(const TNodeLocation& node,double nSnap=PS_SNAP) const { return (fabs(node.ptLocation.x-ptLocation.x)<=nSnap && fabs(node.ptLocation.y-ptLocation.y)<=nSnap); } static int CompareObjectId(const TNodeLocation *p1, const void *pId) { return !(p1->id==*(const AcDbObjectId *)pId); } BOOL EqualLocation(const XPoint & pt,double nSnap=PS_SNAP) const { return ptLocation.Distance(pt) lstAttachment; DList lstAttachPipe; //需要验证附件配属关系的管线 DList lstChangedPipe;//真正发生变化的管线(不包括删除的管线) public: UpdateInfo():sysType(TPipeSys::kUnknownSys){} void AddPipe(const AcDbObjectId& id); void AddAttach(const AcDbObjectId& id); void AddBreakPoint(const XPoint &ptBreak,int nStytle=0); BOOL NeedUpdateSys() const; }; public: TPipePerDocData(AcApDocument* pDoc); ~TPipePerDocData(); PickSet m_ssPickGrip; //上次夹点的加亮的选择集, 主要用在管线流向 protected: DList m_lstUpdate; XRectAngle m_rectSysUpdate; // 管线与节点更新区域 XRectAngle m_rectAttachUpdate; // 管线和附件更新区域 DList m_lstChangedNode; // 发生变化的节点 BOOL m_bWork; // 是否反应器起作用(当前命令有效) int m_nOptimize;// 优化值,当发生变化的管线和节点数达到优化值时ApplyUpdates优化处理 public: void ApplyUpdates(); //在发生变化的区域处理构件关系 void EnableWork(BOOL bFlag) { m_bWork=bFlag; } // 设置反应器起作用(当前命令有效) BOOL IsWork() const { return m_bWork; } // 是否反应器起作用(当前命令有效) int GetOptimize() const { return m_nOptimize; }// 获取优化值(优化后只处理构件中部分关系) void SetOptimize(int nNum) { m_nOptimize=nNum; }// 设置优化值(优化后只处理构件中部分关系) int GetChangedNum() const; // 发生变化的节点和管线数(不包括删除的) void AttachReactor(); void DetachReactor(); void ResetDocCmdGlobals(); void ObjectChanged(const AcDbObject *pObj, int nChangeFlag); static int CompareForFind(const TPipePerDocData *pDoc1, const void *pDoc2); void DoMatchPipe(); void ResetCloseEntity(); //sr add 2009-7-21 AcDbObjectId m_idMatchRes; //格式刷源 DList m_lstMatchEntity; //格式刷目标 DList m_lstCloseEntity; //关闭后要操作的对象 protected: UpdateInfo *FindUpdateInfo(TPipeSys::SysType st); UpdateInfo *NewAppendUpdateInfo(TPipeSys::SysType st); BOOL IsRectEmpty(const XRectAngle &rect) const; void UpdateRect(const XPoint& ptMin,const XPoint& ptMax,XRectAngle &rect);// 更新区域(二维) BOOL GetEntRectFromBlock(DList &lstEntRect,const AcRxClass *pClass, const XRectAngle &rect) const; BOOL GetNodeFromBlock(DList &lstNode,const XRectAngle &rect) const; BOOL UpdatePipeInfos(const TDbPipeNode *pChangedNode,const TDbPipePrototype *pPipe); BOOL UpdatePipeInfos(const TDbPipePrototype *pChangedPipe,const TDbPipePrototype *pPipe); void UpdateNodeInfos(const TDbPipePrototype *pChangedPipe,const TDbPipeNode *pNode); void DoDeepSearch(const DList &lstPipe,const DList &lstNode, XRectAngle &rectUpdate); void ResetDrawSpeed(const DList &lstPipe) const; void ValidateHideships(const DList &lstPipe,const XRectAngle &rectUpdate) const; void ValidateAttachships(const DList* pPipes=NULL) const; void UpdateSystem(DList &lstUpdatePipe); private: void ModifyPipeAtCorner(const UpdateInfo *info,const DList &lstPipe, const DList &lstNode,BOOL bOptimize=FALSE); //zxl 2012.10.30 add void GetMinEntity(std::vector &vecIds); void ModifyMatchEntity(std::map > &mapEnt); void GetIntsectEntity(const std::vector &vecIds, std::map > &mapEnt); // cet 2013.1.11 add 计算系统更新区域, 复制黏贴时,原有计算区域有误 void CalcUpdateSysRect(); // cet 2013.1.11 add 获得当前模型空间所有实体id bool GetEntIdsFromModelSpace(std::set &setEntIds); // cet 2013.1.11 add 是否需要重新计算更新区域 bool IsUpdateSysRect(const CString &sCmd); // cet 2016.4.26 add 更新管道端点(当拖动化粪池到管道时,管道被打断但端点未与化粪池相连) void UpdatePipePoints(DList &lstUpdatePipe); // cet 2016.4.26 add 更新管道与端点实体连接 void UpdatePipeLink(TDbPipePrototype *pPipe, int nPos); // cet 2016.4.27 add 更新化粪池角度 void UpdatePoolAngle(DList &lstUpdatePipe); // cet 2016.4.27 add 更新化粪池位置,使其仅与两根平行管道相连时与管道垂直 void UpdatePoolAngle(TDbPool *pPool, AcDbObjectId id1, AcDbObjectId id2); // cet 2016.9.6 add 更新井数据 void UpdateWellInfo(DList &lstUpdatePipe); private: AcApDocument* m_pDoc; TPipeDbReactor *m_pDbReactor; TPipeInputReactor *m_pInputReactor; std::set m_setEntIds; //2013-1-11 cet add 复制粘贴之前记录变更对象的id }; class TPipeAppDocGlobals: public DList { public: TPipeAppDocGlobals(); void InitDocGlobals(AcApDocument* pDoc); void RemoveDocGlobals(AcApDocument *pDoc); void OnUnloadApp(); private: TPipeDocReactor *m_pDocReactor; }; PS_IMPEXP TPipePerDocData * GetCurPipeDocData(); ////////////////////////////////////////////////////////////////////////// inline TPipePerDocData::UpdateInfo* TPipePerDocData:: NewAppendUpdateInfo(TPipeSys::SysType st) { UpdateInfo *info=FindUpdateInfo(st); if(!info) { info=new UpdateInfo; info->sysType = st; m_lstUpdate.Append(info); } return info; } inline void TPipePerDocData::UpdateInfo::AddPipe(const AcDbObjectId& id) { if(!lstAttachPipe.FindNode(&id, CompareObjectId)) lstAttachPipe.Append(new AcDbObjectId(id)); } inline void TPipePerDocData::UpdateInfo::AddAttach(const AcDbObjectId& id) { if(!lstAttachment.FindNode(&id, CompareObjectId)) lstAttachment.Append(new AcDbObjectId(id)); } inline BOOL TPipePerDocData::UpdateInfo::NeedUpdateSys() const { return lstVertice.Length()>0 || lstNeedBreak.Length()>0; } inline void TPipePerDocData:: UpdateRect(const XPoint& ptMin,const XPoint& ptMax,XRectAngle &rect) { if(IsRectEmpty(rect)) { rect.lowLeft = ptMin; rect.upRight = ptMax; } else { rect.lowLeft.x = min(ptMin.x, rect.lowLeft.x); rect.lowLeft.y = min(ptMin.y, rect.lowLeft.y); rect.upRight.x = max(ptMax.x, rect.upRight.x); rect.upRight.y = max(ptMax.y, rect.upRight.y); } } inline BOOL TPipePerDocData::IsRectEmpty(const XRectAngle &rect) const { return rect.lowLeft==XPoint() && rect.upRight==XPoint(); } #endif