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!