Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Neighbor class and disconnected polygons

    SDK Help
    0
    22
    11.9k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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!

        1 Reply Last reply Reply Quote 0
        • First post
          Last post