//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : XRegionSide 类 // = Version : ver2.0 // = Author : zjq // = CreateDate : 2002-09-09 // = Description: XRegionSide 定义 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "XRegionSide.h" #include "XSideVector.h" #include "XSortSideOnVertex.h" #include "XRegion.h" DList * XRegionSide::g_pAllWalls = NULL; XRegion * XRegionSide::g_pCurRegion = NULL; static XRegionSide *g_pMarkSide = NULL; static int CompareSide(const XSideVector *p1, const void *p2) { const XRegionSide *pSide = (const XRegionSide *)p2; return (p1->m_pSide == pSide) ? 0 : 1; } XRegionSide::XRegionSide() : m_pLeftRegion(NULL), m_pRightRegion(NULL) { m_pStartNode = m_pEndNode = NULL; m_nCurSide = 0; m_bBadSide = 0; } XRegionSide::XRegionSide(const XCurveSegment &seg) : XCurveSegment(seg), m_pLeftRegion(NULL), m_pRightRegion(NULL) { m_pStartNode = m_pEndNode = NULL; m_nCurSide = 0; m_bBadSide = 0; } XRegionSide::~XRegionSide() { } // 功能: 搜索房间 // 参数: // pSpt--当前向量的起点为, nSide--以pSpt为起点的相对左(0)右(1) // 返回: RTNORM--找到一房间; RTERROR--当前墙不构成封闭域; RTNONE--第一个墙不封闭 // 注意: 当前已经进栈(Top==Tail()) // 考虑了墙体标高 int XRegionSide::Trival(XSortSideOnVertex *pSpt, int nSide) { ASSERT(pSpt); if (!XRegionSide::g_pCurRegion) { return RTERROR; } XRegion &aRegion = *g_pCurRegion; if (ads_usrbrk()) { g_pMarkSide = NULL; return RTCAN; } int nCurSide; XSortSideOnVertex *pNextPt; if (pSpt == m_pStartNode) { pNextPt = m_pEndNode; nCurSide = nSide; } else { pNextPt = m_pStartNode; nCurSide = !nSide; } m_nCurSide = nCurSide; //实际 nSide, Find Absolute nCurSide XSortSideOnVertex *pWallsOnPt = pNextPt; if (!pWallsOnPt) { ASSERT(0); return RTERROR; } XSortSideOnVertex &sortSides = *pWallsOnPt; int nLength = sortSides.Length(); XSideVector *pVector = sortSides.FindNode(this, CompareSide); if (!pVector) { ASSERT(0); return RTERROR; } int nPos = sortSides.CurPosition(); int nLen = nLength; int nRetFlg = RTERROR; if (nSide == 1) //右侧,查找相对最左边的 { for (int i = 1; i < nLen; i++) //查找最左边的有效墙 { int nIndex = i + nPos; if (nIndex >= nLen) { nIndex -= nLen; } XRegionSide *pNextWall = (XRegionSide *)(sortSides[nIndex]->m_pSide); if (!pNextWall) { continue; } else if (pNextWall == aRegion.Head()) { if (pNextPt == aRegion.Head()->GetStartNode()) { return RTNORM; // 找到一房间 } else { ASSERT(g_pMarkSide == NULL); g_pMarkSide=pNextWall; //回退到标记 pNextWall->SetBadSide(1); return RTNONE; } } else if (aRegion.Exist(pNextWall)) { ASSERT(g_pMarkSide == NULL); g_pMarkSide = pNextWall; //回退到标记 pNextWall->SetBadSide(1); return RTNONE; // Z Modify here on 2001/12/28 } aRegion.Push(pNextWall); nRetFlg = pNextWall->Trival(pNextPt, nSide); if (nRetFlg == RTNORM) { return RTNORM; } aRegion.Pop(); if (nRetFlg == RTNONE) { //回退到标记 if (aRegion.Tail()!=g_pMarkSide) { return RTNONE; } g_pMarkSide = NULL; //已经到标记 return RTERROR; } else if (nRetFlg == RTCAN) { return nRetFlg; } else if (nRetFlg == RTERROR) { } } } else // 左侧,查找相对最右边的 { for (int i = 1; i < nLen; i++) { int nIndex = nPos-i; if (nIndex < 0) { nIndex += nLen; } XRegionSide *pNextWall = (XRegionSide *)(sortSides[nIndex]->m_pSide); if (!pNextWall) { continue; } else if (pNextWall == aRegion.Head()) { if (pNextPt == aRegion.Head()->GetStartNode()) { return RTNORM; } else { ASSERT(g_pMarkSide == NULL); g_pMarkSide = pNextWall; //回退到标记 pNextWall->SetBadSide(1); return RTNONE; } } else if (aRegion.Exist(pNextWall)) //退回到pNextWall { ASSERT(g_pMarkSide == NULL); g_pMarkSide = pNextWall; //回退到标记 pNextWall->SetBadSide(1); return RTNONE; // Z Modify here on 2001/12/28 } aRegion.Push(pNextWall); nRetFlg = pNextWall->Trival(pNextPt, nSide); if (nRetFlg == RTNORM) { return RTNORM; } aRegion.Pop(); if (nRetFlg == RTNONE) { //回退到标记 if (aRegion.Tail()!=g_pMarkSide) { return RTNONE; } g_pMarkSide = NULL; //已经到标记 return RTERROR; } else if (nRetFlg == RTCAN) { return nRetFlg; } else if (nRetFlg == RTERROR) { } } } return RTERROR; } XRegion* XRegionSide::GetLeftRegion() const { return m_pLeftRegion; } void XRegionSide::SetLeftRegion(XRegion * pRegion) { m_pLeftRegion = pRegion; } XRegion* XRegionSide::GetRighttRegion() const { return m_pRightRegion; } void XRegionSide::SetRightRegion(XRegion * pRegion) { m_pRightRegion = pRegion; } TCHAR XRegionSide::GetCurSide() const { return m_nCurSide; } void XRegionSide::SetCurSide(const TCHAR nCurSide) { m_nCurSide = nCurSide; } TCHAR XRegionSide::GetBadSide() const { return m_bBadSide; } void XRegionSide::SetBadSide(const TCHAR nBadSide) { m_bBadSide = nBadSide; } XSortSideOnVertex* XRegionSide::GetStartNode()const { return m_pStartNode; } void XRegionSide::SetStartNode(XSortSideOnVertex* pNode) { m_pStartNode = pNode; } XSortSideOnVertex* XRegionSide::GetEndNode()const { return m_pEndNode; } void XRegionSide::SetEndNode(XSortSideOnVertex* pNode) { m_pEndNode = pNode; }