/**************************************************************************** @Function CObject @Input pwIdx Array of indices @Input nVrxTot Total number of vertices @Input nTriTot Total number of triangles @Input nVtxLimit Max number of vertices a block can contain @Input nTriLimit Max number of triangles a block can contain @Description The class's constructor. ****************************************************************************/ CObject::CObject( const PVRTGEOMETRY_IDX * const pwIdx, const int nVtxTot, const int nTriTot, const int nVtxLimit, const int nTriLimit) { int i; SVtx *pVtx0, *pVtx1, *pVtx2; m_nVtxLimit = nVtxLimit; m_nTriLimit = nTriLimit; m_pvMesh = new std::vector<SMesh>[nVtxLimit-2]; _ASSERT(m_pvMesh); m_ppVtxByMesh = (SVtx**)calloc(nVtxTot, sizeof(*m_ppVtxByMesh)); _ASSERT(m_ppVtxByMesh); m_nVtxTot = nVtxTot; m_nEdgTot = 0; m_nTriTot = nTriTot; m_nTriNumFree = m_nTriTot; m_pTri = (STri*)calloc(nTriTot, sizeof(*m_pTri)); _ASSERT(m_pTri); m_pEdg = (SEdg*)calloc(nTriTot*3, sizeof(*m_pEdg)); // Allocate the maximum possible number of edges, though it should be far fewer than this _ASSERT(m_pEdg); m_pVtx = (SVtx*)calloc(nVtxTot, sizeof(*m_pVtx)); _ASSERT(m_pVtx); // Run through triangles... for(i = 0; i < nTriTot; ++i) { pVtx0 = &m_pVtx[pwIdx[3*i+0]]; pVtx1 = &m_pVtx[pwIdx[3*i+1]]; pVtx2 = &m_pVtx[pwIdx[3*i+2]]; // Mark each vertex for the number of times it's referenced ++pVtx0->nTriNumFree; ++pVtx1->nTriNumFree; ++pVtx2->nTriNumFree; // Build the edge list m_pTri[i].psEdg[0] = BuildEdgeList(pVtx0, pVtx1); m_pTri[i].psEdg[1] = BuildEdgeList(pVtx1, pVtx2); m_pTri[i].psEdg[2] = BuildEdgeList(pVtx2, pVtx0); } // Run through vertices, creating enough space for pointers to each triangle using this vertex for(i = 0; i < nVtxTot; ++i) m_pVtx[i].psTri = (STri**)calloc(m_pVtx[i].nTriNumFree, sizeof(*m_pVtx[i].psTri)); // Run through triangles, marking each vertex used with a pointer to this tri for(i = 0; i < nTriTot; ++i) { pVtx0 = &m_pVtx[pwIdx[3*i+0]]; pVtx1 = &m_pVtx[pwIdx[3*i+1]]; pVtx2 = &m_pVtx[pwIdx[3*i+2]]; pVtx0->psTri[pVtx0->nTriNumTot++] = &m_pTri[i]; pVtx1->psTri[pVtx1->nTriNumTot++] = &m_pTri[i]; pVtx2->psTri[pVtx2->nTriNumTot++] = &m_pTri[i]; // Give each triangle a pointer to its indices m_pTri[i].pwIdx = &pwIdx[3*i]; } #ifdef _DEBUG for(i = 0; i < nVtxTot; ++i) { _ASSERTE(m_pVtx[i].nTriNumFree == m_pVtx[i].nTriNumTot); } #endif CreateMeshList(); }
/// Return the current list of conforming and nonconforming edges. const NCList& GetEdgeList() { if (edge_list.Empty()) { BuildEdgeList(); } return edge_list; }
ILubyte *iScanFill() { Edge **edges = NULL, *active = NULL/*, *temp*/; ILuint i, scan; iRegionMask = NULL; if ((RegionPointsi == NULL && RegionPointsf == NULL) || PointNum == 0) return NULL; if (RegionPointsf) { RegionPointsi = (ILpointi*)ialloc(sizeof(ILpointi) * PointNum); if (RegionPointsi == NULL) goto error; } for (i = 0; i < PointNum; i++) { if (RegionPointsf) { RegionPointsi[i].x = (ILuint)(iluCurImage->Width * RegionPointsf[i].x); RegionPointsi[i].y = (ILuint)(iluCurImage->Height * RegionPointsf[i].y); } if (RegionPointsi[i].x >= (ILint)iluCurImage->Width || RegionPointsi[i].y >= (ILint)iluCurImage->Height) goto error; } edges = (Edge**)ialloc(sizeof(Edge*) * iluCurImage->Height); iRegionMask = (ILubyte*)ialloc(iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth); if (edges == NULL || iRegionMask == NULL) goto error; imemclear(iRegionMask, iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth); for (i = 0; i < iluCurImage->Height; i++) { edges[i] = (Edge*)ialloc(sizeof(Edge)); edges[i]->next = NULL; } BuildEdgeList(PointNum, RegionPointsi, edges); active = (Edge*)ialloc(sizeof(Edge)); active->next = NULL; for (scan = 0; scan < iluCurImage->Height; scan++) { BuildActiveList(scan, active, edges); if (active->next) { FillScan(scan, active); UpdateActiveList(scan, active); ResortActiveList(active); } } // Free edge records that have been allocated. /*for (i = 0; i < iluCurImage->Height; i++) { while (edges[i]) { temp = edges[i]->next; ifree(edges[i]); edges[i] = temp; } }*/ ifree(edges); if (RegionPointsf) { ifree(RegionPointsi); RegionPointsi = NULL; } return iRegionMask; error: if (RegionPointsf) { ifree(RegionPointsi); RegionPointsi = NULL; } // Free edge records that have been allocated. ifree(edges); ifree(iRegionMask); return NULL; }
/// /// ScanFill() VOID ScanFill( FRAME *frame ) { int cnt = frame->selection.nVertices; Point *pts = frame->selection.vertices; EdgePtr *edges, active; int scan, i; edges = pmalloc( sizeof(EdgePtr) * (frame->pix->height+1) ); D(bug("ScanFill: allocating edges\n")); for( i = 0; i <= frame->pix->height; i++ ) { edges[i] = smalloc( sizeof(EdgeRec) ); edges[i]->next = NULL; } active = smalloc( sizeof(EdgeRec) ); active->next = NULL; BuildEdgeList( cnt, pts, edges ); for( scan = 0; scan < frame->pix->height; scan++ ) { D(bug(" Line=%d\n",scan)); D(bug("List: edges[%d]\n",scan)); D(PrintList( "", edges[scan] )); BuildActiveList( scan, edges, active ); // D(bug("List: edges[%d]\n",scan)); // D(PrintList( "", edges[scan] )); D(PrintList( "active", active )); if( active->next ) { ROWPTR cp; cp = GetPixelRow( frame->selection.mask, scan, globxd ); bzero( cp, frame->pix->bytes_per_row ); FillScan( cp, scan, active ); PutPixelRow( frame->selection.mask, scan, cp, globxd ); UpdateActiveList( scan, active ); ResortActiveList( active ); } } D(bug(" ScanFill done\n")); #if 1 for( i = 0; i <= frame->pix->height; i++ ) { if( edges[i] ) { sfree( edges[i] ); } } #endif #if 1 if( active ) { EdgePtr e,ep; D(PrintList( "active", active )); ep = active->next; while( ep ) { e = ep->next; sfree( ep ); ep = e; } sfree( active ); } #endif pfree(edges); }