void _FillAdjMatrix( CvGraph* graph, int** connected, int reverse ) { //assume all vertices are marked for( int i = 0; i < graph->total; i++ ) { for( int j = 0; j < graph->total; j++ ) { connected[i][j] = 0|reverse; } //memset( connected[i], 0, sizeof(int)*graph->total ); CvGraphVtx* ver = cvGetGraphVtx( graph, i ); if( ver ) { connected[i][i] = 1; for( CvGraphEdge* e = ver->first; e ; e = CV_NEXT_GRAPH_EDGE( e, ver ) ) { CvGraphVtx* v = CV_GET_ADJ_VTX( ver, e ); connected[i][NUMBER(v)] = 1^reverse; } } } }
CV_IMPL int icvNextGraphItem( CvGraphScanner* scanner ) { int code = -1; CV_FUNCNAME("icvNextGraphItem"); __BEGIN__; CvGraphVtx* vtx; CvGraphVtx* dst; CvGraphEdge* edge; CvGraphItem item; if( !scanner || !(scanner->stack)) CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR ); dst = scanner->dst; vtx = scanner->vtx; edge = scanner->edge; for(;;) { for(;;) { if( dst && !CV_IS_GRAPH_VERTEX_VISITED(dst) ) { scanner->vtx = vtx = dst; edge = vtx->first; dst->flags |= CV_GRAPH_ITEM_VISITED_FLAG; if((scanner->mask & CV_GRAPH_VERTEX)) { scanner->vtx = vtx; scanner->edge = vtx->first; scanner->dst = 0; code = CV_GRAPH_VERTEX; EXIT; } } while( edge ) { dst = edge->vtx[vtx == edge->vtx[0]]; if( !CV_IS_GRAPH_EDGE_VISITED(edge) ) { // check that the edge is outcoming if( !CV_IS_GRAPH_ORIENTED( scanner->graph ) || dst != edge->vtx[0] ) { edge->flags |= CV_GRAPH_ITEM_VISITED_FLAG; code = CV_GRAPH_BACK_EDGE; if( !CV_IS_GRAPH_VERTEX_VISITED(dst) ) { item.vtx = vtx; item.edge = edge; vtx->flags |= CV_GRAPH_SEARCH_TREE_NODE_FLAG; cvSeqPush( scanner->stack, &item ); if( scanner->mask & CV_GRAPH_TREE_EDGE ) { code = CV_GRAPH_TREE_EDGE; scanner->dst = dst; scanner->edge = edge; EXIT; } break; } else { if( scanner->mask & (CV_GRAPH_BACK_EDGE| CV_GRAPH_CROSS_EDGE| CV_GRAPH_FORWARD_EDGE) ) { code = (dst->flags & CV_GRAPH_SEARCH_TREE_NODE_FLAG) ? CV_GRAPH_BACK_EDGE : (edge->flags & CV_GRAPH_FORWARD_EDGE_FLAG) ? CV_GRAPH_FORWARD_EDGE : CV_GRAPH_CROSS_EDGE; edge->flags &= ~CV_GRAPH_FORWARD_EDGE_FLAG; if( scanner->mask & code ) { scanner->vtx = vtx; scanner->dst = dst; scanner->edge = edge; EXIT; } } } } else if( (dst->flags & (CV_GRAPH_ITEM_VISITED_FLAG| CV_GRAPH_SEARCH_TREE_NODE_FLAG)) == (CV_GRAPH_ITEM_VISITED_FLAG| CV_GRAPH_SEARCH_TREE_NODE_FLAG)) { edge->flags |= CV_GRAPH_FORWARD_EDGE_FLAG; } } edge = CV_NEXT_GRAPH_EDGE( edge, vtx ); } if( !edge ) // need to backtrack { if( scanner->stack->total == 0 ) { if( scanner->index >= 0 ) vtx = 0; else scanner->index = 0; break; } cvSeqPop( scanner->stack, &item ); vtx = item.vtx; vtx->flags &= ~CV_GRAPH_SEARCH_TREE_NODE_FLAG; edge = item.edge; dst = 0; if( scanner->mask & CV_GRAPH_BACKTRACKING ) { scanner->vtx = vtx; scanner->edge = edge; scanner->dst = edge->vtx[vtx == edge->vtx[0]]; code = CV_GRAPH_BACKTRACKING; EXIT; } } } if( !vtx ) { vtx = (CvGraphVtx*)icvSeqFindNextElem( (CvSeq*)(scanner->graph), CV_FIELD_OFFSET( flags, CvGraphVtx ), CV_GRAPH_ITEM_VISITED_FLAG|1, 0, &(scanner->index) ); if( !vtx ) { code = CV_GRAPH_OVER; icvEndScanGraph( scanner ); scanner->stack = 0; break; } } dst = vtx; if( scanner->mask & CV_GRAPH_NEW_TREE ) { scanner->dst = dst; scanner->edge = 0; scanner->vtx = 0; code = CV_GRAPH_NEW_TREE; break; } } __END__; return code; }