Neighbor class and disconnected polygons
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/07/2012 at 11:10, xxxxxxxx wrote:
Thanks for the explanation.
I understand how you're getting the BOOL now.I think I was misunderstanding what a UCHAR is. Please check my thinking on this.
UCHAR is used to store values. Specifically positive values. Not characters as the name seems to imply.
The same way a DWORD stores unsigned long values. Not strings as the name seems to imply.
So there is no such thing as converting a UCHAR to a string.Is that correct?
-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/07/2012 at 11:13, xxxxxxxx wrote:
...Just for completeness (I'm still not clear exactly what you're asking/trying to accomplish)...
If you literally want to print the values of a UCHAR array, you can still do that fairly easily...
GePrint(String("PolyProcessed[0] = ")+LongToString((LONG)PolyProcessed[0]));
...you could even leave out the (LONG) cast (it would get cast anyway - I just added it for clarity).
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/07/2012 at 11:15, xxxxxxxx wrote:
Originally posted by xxxxxxxx
Thanks for the explanation.
I understand how you're getting the BOOL now.I think I was misunderstanding what a UCHAR is. Please check my thinking on this.
UCHAR is used to store values. Specifically positive values. Not characters as the name seems to imply.
The same way a DWORD stores unsigned long values. Not strings as the name seems to imply.
So there is no such thing as converting a UCHAR to a string.Is that correct?
-ScottA
Yes - you are correct - I'm using it to just store some value between 0 - 255 (and in this case, just either 1 or 0).
An array of UCHARs is actually a C string, by definition and can be used as such as long as it's null-terminated (erm... and as long as it contains printable characters - but not how I'm using it).
Again, just for completeness/correctness... you can in fact store characters in a UCHAR array...
mystring[0] = 'H'; // H mystring[1] = 'e'; // e mystring[2] = 'l'; // l mystring[3] = 'l'; // l mystring[4] = 'o'; // o mystring[5] = ' '; // <space> mystring[6] = 'W'; // W mystring[7] = 'o'; // o mystring[8] = 'r'; // r mystring[9] = 'l'; // l mystring[10] = 'd'; // d mystring[11] = '\0'; // null termination.
...the above is equivalent to my previous post, just using characters instead of the equivalent ASCII values that represent those same characters.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/07/2012 at 12:05, xxxxxxxx wrote:
Thanks a lot for explaining this stuff.
I did some searching on WCHAR to see If it could help me learn more about UCHAR. But you've eplained it quite well.Thank you.
-ScottA -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/08/2012 at 04:43, xxxxxxxx wrote:
Just a heads up: there is a slight bug in your ConnectedPolyGroup.Init() method. I've moved ++m_GroupCount to below ProcessConnectedPolys() or your groupIDs are set too high in that method. Now it appears to be working as expected.
Bool done = FALSE; for(LONG polyNdx = 0L; polyNdx != m_numPolys; ++polyNdx) { if (m_pDstPolyProcessed[polyNdx]) continue; // set group index/ID m_pGroupIDs[polyNdx] = m_GroupCount; // mark this one off... m_pDstPolyProcessed[polyNdx] = 1; ++m_numMappedPolys; // set all neighbors to same group index/ID done = this->ProcessConnectedPolys(); // bump group index/ID for next group // THIS HAS BEEN MOVED TO BELOW ProcessConnectedPolys()! ++m_GroupCount; if (done) break; }
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/08/2012 at 10:03, xxxxxxxx wrote:
Hmm... I don't see any difference in what you posted and the latest posted code above (?). Maybe I found/fixed the post after you had already grabbed the code? Or am I missing something?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/08/2012 at 10:11, xxxxxxxx wrote:
Hehe...... Must have grabbed an earlier version of the code. Good that you found it too!
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/08/2012 at 10:22, xxxxxxxx wrote:
I thought that might be the case :). I don't recall what other changes I made (and whether or not any changes were bug-fixes), so you might want to compare the rest of that to what you're using as well.
-
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!