#ifndef _DUCTPIPELINK_H_2006_6_29_ #define _DUCTPIPELINK_H_2006_6_29_ #include "NodeAssistant.h" #include "DbDuct.h" #include "TDbDuctNode.h" /*============================================================================* * Copyright(c), 1994-2007, Beijing Tangent Engineering Software Co.Ltd. * 文 件 名: DuctPipeLink.h * 版 本: 2.0 * 作 者: sg * 描 述: 风管专用处理机制 * 归属项目: 暖通 * 历史记录: =============================================================================*/ class TDsSide; /*============================================================================* * 类 名: TDsNode * 功能描述: 抽象的风管节点类,用于连接系统 * 备 注: TNodeLocation(id、ptLocation):节点信息,节点、设备都有效 m_nMain:主风管标号,TDbDuctNode有效 DStack:记录连接的边 m_types:连接类型,与TDsNode的长度及顺序必须完全一致,但不包括 与实体连接,不在更新区域内的管线。0为正常,1为空接口, 2接节点, 3为掏洞 ==============================================================================*/ class TDsNode: public DStack { public: // 构造函数 TDsNode(const XPoint &ptLoc, const BOOL &bAutoLiving = TRUE): m_node(ptLoc), m_nMain(0), m_bAutoLiving(bAutoLiving), m_bBad(FALSE) {} TDsNode(const TNodeLocation &node, const BOOL &bAutoLiving): m_node(node), m_nMain(0), m_bAutoLiving(bAutoLiving), m_bBad(FALSE) {} ~TDsNode(); public: TNodeLocation m_node; // 节点自身信息 int m_nMain; // 主风管标号,仅对TDbDuctNode有用 BOOL m_bAutoLiving; // 是否自动生成 AcDbIntArray m_types; // 连接类型 BOOL m_bBad; // 无法正常连接的节点,标记为坏节点不再进行处理 mcl add 08.10.6 public: // 处理系统中传递值方便,包括节点连接的全部管线或节点 DList ids; // ID AcDbIntArray mods; // 连接类型 AcGeDoubleArray ws; // 宽度 AcGeDoubleArray hs; // 高度 AcGeDoubleArray as; // 角度 DList vs; // 方向 DList ss; // segs DList ps; // 位置 public: // Set、Get函数 AcDbObjectId GetId() const { // ID return m_node.id; } void SetLocation(const XPoint &ptLoc); // 位置坐标 XPoint GetLocation() const { return m_node.ptLocation; } void SetMainDuct(const int &nMain); // 主风管标号 int GetMainDuct() const { return m_nMain; } void SetBad(BOOL bBad){ m_bBad = bBad; } BOOL IsBad() const{ return m_bBad; } public: BOOL IsDbObject() const { // Id是否有效 return m_node.id.isValid(); } BOOL IsAutoLiving() const { // 是否自动生成 return m_bAutoLiving; } BOOL IsVisibal() const; // 是否可见 public: // 重合部分的处理,暂时不考虑 BOOL IsDupLocation(const XPoint &ptLoc) const { // 是否与当前节点位置重合 return m_bAutoLiving && m_node.EqualLocation(ptLoc); } BOOL IsDupLocation(const TNodeLocation &node) const { return m_bAutoLiving && m_node.EqualLocation(node.ptLocation); } public: // 7.6新增函数 void ClearSS(); // 清空一系列辅助处理的数组或链表 int SetInfo(); // 获取节点连接情况的信息,初始化成员变量 BOOL AssureArrayNum(int nNum); // 保证数组或链表长度正确 TDbDuctNode::DuctNodeType GetNewNType(); // 获取新节点类型 int GetOldIFNum(TDbDuctNode::DuctNodeType &nType); // 获取原接口数量及类型 int FindSide(const TDsSide &pSide); // 查找是否与指定边有连接关系 public: // 处理函数 // 判断节点是否可以连接边的指定端点,同TPsNode里的CanLinkSide BOOL FindNode(const TDsSide &side, const int &nPos); // 删除、替换接口,同TPsNode里的RemovePipeFromDb、ReplacePipeFromDb void RemoveInterface(const AcDbObjectId sideId); void ReplaceInterface(const AcDbObjectId &idOld, const AcDbObjectId &idNew); void UpdateLinkage(const TPipeSys::SysType st); // 对st类型节点进行更新 }; /*============================================================================* * 类 名: TDsSide * 功能描述: 抽象的风管管线类,用于连接系统 * 备 注: 1、边的概念 2、XCurveSegment(startPoint/endPoint):管线真实起止点 TEntRect(id、rect):管线信息,其中的upRight/lowLeft为上下节 点所构成的矩形 ==============================================================================*/ class TDsSide: public XDirectionCurve { public: // 构造函数 TDsSide(const AcDbObjectId &id); TDsSide(const TEntRect &duct); public: // 专用于节点直接相连函数 TDsSide(const AcDbObjectId &startId, const AcDbObjectId &endId); // 构造 BOOL FindSide(AcDbObjectId id1, AcDbObjectId id2); // 查找 public: TEntRect m_duct; // 管线 TDsNode *m_pStartNode; // 起止点连接的节点 TDsNode *m_pEndNode; public: BOOL IsDbObject() const { // 注:比较与IsNull的区别 return m_duct.id.isValid(); } public: // 重合部分的处理,暂时不考虑 BOOL IsFullDupSide(const XCurveSegment *pSeg) const { // 完全重合的管段 return ((XCurveSegment &)*this == *pSeg); } BOOL IsFullDupSide(const TDsSide &side) const; public: // Get函数 AcDbObjectId GetId() const { // ID return m_duct.id; } XPoint GetPt(const TPipeSys::PtLoction nSide, int nMod) const; // 获取端点 public: // 处理函数 BOOL MergeWith(TDsSide &other, const TDsNode &merge); // 合并 // 更新管线对节点的连接 void UpdateLinkage(const XPoint ptNew, const TPipeSys::PtLoction nSide); }; /*============================================================================* * 类 名: TDuctLinkSys * 功能描述: 由风管系统抽象出来的单线系统类 * 备 注: 1、其中TDPsSide、TDPsNode分别与TDbDuct、TDbDuctNode对应 2、不显示,仅用于处理各个部件连接的系统 3、与TSearchPipeSys系统的区别:增加了UpdateDuctInfo的链表,用于处理更新 ==============================================================================*/ class TDuctLinkSys { public: class UpdateDuctInfo // 需要更新的管线信息 { public: AcDbObjectId id; // 管线ID TPipeSys::PtLoction nSide; // 修改管线的起点或终点 XPoint pt; // 修改后的点的位置 public: UpdateDuctInfo():nSide(TPipeSys::kStartPt) {} ~UpdateDuctInfo() {} BOOL operator == (const UpdateDuctInfo &info) const { if (id==info.id && pt==info.pt && nSide==info.nSide) return TRUE; else return FALSE; } }; public: TDuctLinkSys(BOOL bOptimize = FALSE): m_bOptimize(bOptimize) { m_lstUpdate.Reset(); } ~TDuctLinkSys() {} public: DList m_lstAllSide; // 更新区域内的全部管线 DList m_lstAllNode; // 节点 DList m_lstDupDuct; // 重合,待删除的管段 DList m_lstDupNode; // 重合节点 BOOL m_bOptimize; // 是否优化 :1、不判断重合管线 // 2、只处理自动生成的管线为一个的节点 DList m_lstUpdate; // 更新信息 public: static int CompareUpdateInfo(const TDuctLinkSys::UpdateDuctInfo *info1, const void *info2) { if (*info1 == *(const TDuctLinkSys::UpdateDuctInfo*)info2) return 0; return 1; } public: // 同TSearchPipeSys void InitSystem(TPipeSys::SysType st, const DList &lstDucts, const DList &lstNodes, const XPointList &lstBreaks); // 初始化系统 void MergeDucts(XPointList &lstCorners, PickSet &ssDel); // 合并 void BreakDucts(XPointList &lstCorners); // 打断 void UpdateDuctLinkage(); // 更新管线对节点的连接 // 更新节点对管线的连接,box为指定的更新范围(忽略Z坐标) void UpdateNodeLinkage(TPipeSys::SysType st, const XRectAngle* box = NULL); void AddAutoNodeToDb(const XRectAngle* box = NULL); // 添加节点 void DelDupNodeFromDb(const XRectAngle &box); // 删除节点、管线 void DelDupDuctFromDb(const XRectAngle &box); // 删除独立的节点 void DelSoleNodeFromDb(TPipeSys::SysType st, const XRectAngle* box = NULL); public: // 区别于TSearchPipeSys,新增加的函数 void InitSystem2(TPipeSys::SysType st, const DList &lstNodes, const XPointList &lstBreaks); // 用于lstDudts中没有管线的情况 // 根据不同的节点类型,确定要更新的管线和节点 void JudgeNodeType(PickSet &ssDel); void BuildUpdateDuct(const AcDbObjectId &id, const XPoint &pt, const TPipeSys::PtLoction nSide, int nType); // 构造更新信息 BOOL CalElbowPts(TDsNode &node, const BOOL bConfig = TRUE, const BOOL bKouElbow = FALSE); BOOL CalTaperedPts(TDsNode &node, const BOOL bConfig = TRUE); BOOL CalYiZiElbowPts(TDsNode &node, const BOOL bConfig = TRUE); BOOL Cal3TPts(TDsNode &node, const BOOL bConfig = TRUE); BOOL CalTaoDongPts(TDsNode &node, const BOOL bConfig = TRUE); BOOL Cal4TPts(TDsNode &node, const BOOL bConfig = TRUE); BOOL DealTaoDong(TDsSide &side, TDsNode &node); // 处理掏洞的情况 void ValidateClingNode(); // 更新管线上附着的节点关系 protected: // 同TSearchPipeSys // 构造处理系统里的边和连接关系,同TSearchPipeSys里的AddPipe void AddDuct(const TEntRect &duct, TPipeSys::SysType st); // 查找和pSide连接的指定节点,是否在m_lstAllNode中;同TSearchPipeSys里的FindPsNodeAt TDsNode* FindDsNode(const TDsSide &side, TPipeSys::PtLoction nSide); // 在第nPos个位置,合并、打断管段 BOOL MergeDuctAt(int nPos, XPointList &lstCorners, PickSet &ssDel); void BreakDuctAt(int nPos, XPointList &lstCorners); void UpdateBreak(TDbDuct* pDuct, TDsSide &side, TDsNode &node, AcDbObjectId &newDuctId); // 更新打断后的连接关系 // 从数据库中删除重合节点、管线 BOOL DelNodeFromDb(const AcDbObjectId &id, const XRectAngle &box); BOOL DelDuctFromDb(const AcDbObjectId &id, const XRectAngle &box); BOOL IsDupNode(const TNodeLocation &node) const; // 是否为重复节点 BOOL IsDupNode(const XPoint &ptLoc) const; BOOL IsFullDupDuct(const XCurveSegment* pSeg) const; // 是否完全重合的管线 BOOL IsFullDupDuct(const TDsSide &side) const; protected: // 区别于TSearchPipeSys,新增加的函数 // 根据节点,构造管线处理系统里的边和连接关系 void AddNode(const TNodeLocation &node, TPipeSys::SysType st); // 通过ID查找pSide是否在m_lstAllSide内,以确保连接关系 TDsSide* FindSideById(AcDbObjectId ductId); TDsSide* FindSideById(AcDbObjectId id1, AcDbObjectId id2); // 用于节点直接相连函数 int FindNodeByPt(const XPoint &ptLoc) const; // 通过pt查找pNode是否在m_lstAllNode内 }; #endif