Neighbor class and disconnected polygons



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/08/2012 at 10:33, xxxxxxxx wrote:

    Just for completeness, here is the latest in-use code...

      
    class ConnectedPolyGroup  
    {  
    private:  
      Bool        m_bInit;  
      LONG        m_numVerts;  
      LONG        m_numPolys;  
      LONG        m_numMappedPolys;  
      LONG        m_GroupCount;  
      CPolygon    *m_pDstPolys;  
      UCHAR        *m_pDstPolyProcessed;  
      UCHAR        *m_pNeighborsAdded;  
      LONG        *m_pGroupIDs;  
      Neighbor    m_dstNbr;  
      
      Bool ProccessConnectedPolys(void);  
    public:  
      void FreeData(void);  
      BaseSelect *SelectGroup(LONG GroupID);  
      LONG NumPolys(void)                        { return m_numPolys; }  
      LONG NumConnectedGroups(void)            { return m_GroupCount; }  
      LONG GroupID(LONG polyNdx)                { if(!m_bInit || polyNdx >= m_numPolys) return NOTOK;    return  m_pGroupIDs[polyNdx]; }  
      Bool Init(PolygonObject *pPolyObj);  
      
      ConnectedPolyGroup(void);  
      ~ConnectedPolyGroup(void);  
    };  
      
    ConnectedPolyGroup::ConnectedPolyGroup(void)  
    {  
      m_bInit = false;  
      m_GroupCount = 0;  
      m_pDstPolyProcessed = NULL;  
      m_pNeighborsAdded = NULL;  
      m_pGroupIDs = NULL;  
    }  
      
    ConnectedPolyGroup::~ConnectedPolyGroup(void)  
    {  
      this->FreeData();  
    }  
      
    void ConnectedPolyGroup::FreeData(void)  
    {  
      bDelete(m_pDstPolyProcessed);  
      bDelete(m_pNeighborsAdded);  
      bDelete(m_pGroupIDs);  
      m_numMappedPolys = 0;  
      m_GroupCount = 0;  
      m_numVerts = 0;  
      m_numPolys = 0;  
      m_bInit = false;  
    }  
      
    // generate a BaseSelect based on connected GroupID - caller owns returned BaseSelect pointer  
    BaseSelect *ConnectedPolyGroup::SelectGroup(LONG GroupID)  
    {  
      if(!m_bInit || GroupID >= m_GroupCount)    return NULL;  
      
      BaseSelect *pSel = BaseSelect::Alloc();  
      if( !pSel )                                return NULL;  
      pSel->DeselectAll();    // <-- shouldn't actually be needed  
      
      LONG polyNdx;  
      for(polyNdx=0; polyNdx<m_numPolys; polyNdx++)  
      {  
          if( m_pGroupIDs[polyNdx] == GroupID )  
              pSel->Select(polyNdx);  
      }  
      return pSel;  
    }  
      
    Bool ConnectedPolyGroup::Init(PolygonObject *pPolyObj)  
    {  
      this->FreeData();  
      
      m_numVerts = pPolyObj->GetPointCount();  
      m_numPolys = pPolyObj->GetPolygonCount();  
      m_pDstPolys = pPolyObj->GetPolygonW();  
      
      // track which polys have been processed.  
      m_pDstPolyProcessed = bNew UCHAR[m_numPolys];  
      if( !m_pDstPolyProcessed )        return false;  
      
      // track which polys have had their neighbors added.  
      m_pNeighborsAdded = bNew UCHAR[m_numPolys];  
      if( !m_pNeighborsAdded )        return false;  
      
      // track which 'connected group' each poly belongs to  
      m_pGroupIDs = bNew LONG[m_numPolys];  
      if( !m_pGroupIDs )                return false;  
      
      // initialize Neighbor class  
      if( !m_dstNbr.Init(m_numVerts, m_pDstPolys, m_numPolys, NULL) )    return false;  
      
      ClearMem(m_pDstPolyProcessed, m_numPolys * sizeof(UCHAR), 0);  
      ClearMem(m_pNeighborsAdded, m_numPolys * sizeof(UCHAR), 0);  
      ClearMem(m_pGroupIDs, m_numPolys * sizeof(LONG), 0);  
      
      LONG polyNdx;  
      Bool done = false;  
      for(polyNdx=0; polyNdx<m_numPolys; polyNdx++)  
      {  
          if( m_pDstPolyProcessed[polyNdx] )    continue;  
      
          m_pGroupIDs[polyNdx] = m_GroupCount;                        // set group index/ID  
          m_pDstPolyProcessed[polyNdx] = 1;                            // mark this one off...  
          m_numMappedPolys++;  
      
          done = this->ProccessConnectedPolys();                        // set all neighbors to same group index/ID  
      
          m_GroupCount++;                                                // bump group index/ID for next group  
          if( done )    break;  
      }  
      
      // done with these...  
      bDelete(m_pDstPolyProcessed);  
      bDelete(m_pNeighborsAdded);  
      m_bInit = true;  
      return true;  
    }  
      
    Bool ConnectedPolyGroup::ProccessConnectedPolys(void)  
    {  
      Bool morePolys = true;  
      while( morePolys )  
      {  
          morePolys = false;  
          LONG polyNdx;  
          for(polyNdx=0; polyNdx<m_numPolys; polyNdx++)  
          {  
              if( !m_pDstPolyProcessed[polyNdx] )    continue;    // only adding/processing neighbors of previously matched/valid polys  
              if( m_pNeighborsAdded[polyNdx] )    continue;    // don't add/process neighbors if already added  
      
    //            CPolygon *pDstPoly = &m_pDstPolys[polyNdx];  
              PolyInfo *pDstPolyInfo = m_dstNbr.GetPolyInfo(polyNdx);  
              LONG side;  
              for(side=0; side<4; side++)  
              {  
                      LONG dstNbrNdx = pDstPolyInfo->face[side];  
                  if( dstNbrNdx == NOTOK )                continue;    // skip any sides that don't exist  
                  if( m_pDstPolyProcessed[dstNbrNdx] )    continue;    // only adding neighbors not already added  
      
                  m_pGroupIDs[dstNbrNdx] = m_GroupCount;        // all connected polys get the same index/ID  
                  m_pDstPolyProcessed[dstNbrNdx] = 1;            // mark this one off...  
                  m_numMappedPolys++;  
                  morePolys = true;                            // since we added / processed another poly, make sure we loop again to get _it's_ neighbors  
              }  
              m_pNeighborsAdded[polyNdx] = 1;                    // we've processed this polys neighbors  
      
              if( m_numMappedPolys == m_numPolys )  
              {  
                  morePolys = false;  
                  break;    // return true?  
              }  
          }  
      }  
      if( m_numMappedPolys == m_numPolys )  
          return true;  
      return false;  
    }  
    

    ...I _think_ the only difference in that and what's posted above is that I go ahead and free a couple (no-longer-needed) arrays inside Init() instead of waiting for the Destructor.

    As an aside, based on some later use of this base code (in this thread), I think that I determined that I didn't really need the m_pNeighborsAdded array/checking/tracking at all.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 04/08/2012 at 07:55, xxxxxxxx wrote:

    Will compare code and update as needed.  Thanks!


Log in to reply