/* Sort graph vertices in topological order. 'vex_vec': record nodes with topological sort. NOTE: current graph will be empty at function return. If one need to keep the graph unchanged, clone graph as a tmpgraph and operate on the tmpgraph. e.g: GRAPH org; And org must be unchanged, GRAPH tmp(org); tmp.sort_in_toplog_order(...) */ bool GRAPH::sort_in_toplog_order(OUT SVECTOR<UINT> & vex_vec, bool is_topdown) { IS_TRUE(m_pool != NULL, ("Graph still not yet initialize.")); if (get_vertex_num() == 0) { return true; } LIST<VERTEX*> vlst; UINT pos = 0; vex_vec.clean(); vex_vec.grow(get_vertex_num()); while (this->get_vertex_num() != 0) { vlst.clean(); VERTEX * v; INT c; for (v = this->get_first_vertex(c); v != NULL; v = this->get_next_vertex(c)) { if (is_topdown) { if (VERTEX_in_list(v) == NULL) { vlst.append_tail(v); } } else if (VERTEX_out_list(v) == NULL) { vlst.append_tail(v); } } if (vlst.get_elem_count() == 0 && this->get_vertex_num() != 0) { IS_TRUE(0, ("exist cycle in graph")); return false; } for (v = vlst.get_head(); v != NULL; v = vlst.get_next()) { vex_vec.set(pos, VERTEX_id(v)); pos++; this->remove_vertex(v); } } return true; }
bool GRAPH::is_equal(GRAPH & g) { if (get_vertex_num() != g.get_vertex_num() || get_edge_num() != g.get_edge_num()) { return false; } BITSET vs; INT c; for (VERTEX * v1 = get_first_vertex(c); v1 != NULL; v1 = get_next_vertex(c)) { VERTEX * v2 = g.get_vertex(VERTEX_id(v1)); if (v2 == NULL) { return false; } vs.clean(); EDGE_C * el = VERTEX_out_list(v1); EDGE * e = NULL; UINT v1_succ_n = 0; if (el == NULL) { if (VERTEX_out_list(v2) != NULL) { return false; } continue; } for (e = EC_edge(el); e != NULL; el = EC_next(el), e = el ? EC_edge(el) : NULL) { vs.bunion(VERTEX_id(EDGE_to(e))); v1_succ_n++; } UINT v2_succ_n = 0; el = VERTEX_out_list(v2); for (e = EC_edge(el); e != NULL; el = EC_next(el), e = el ? EC_edge(el) : NULL) { v2_succ_n++; if (!vs.is_contain(VERTEX_id(EDGE_to(e)))) { return false; } } if (v1_succ_n != v2_succ_n) { return false; } } return true; }
/* Perform DFS to seek for unreachable node. Return true if some nodes removed. */ bool DGRAPH::remove_unreach_node(UINT entry_id) { if (get_vertex_num() == 0) return false; bool removed = false; BITSET visited; _remove_unreach_node(entry_id, visited); INT c; for (VERTEX * v = get_first_vertex(c); v != NULL; v = get_next_vertex(c)) { if (!visited.is_contain(VERTEX_id(v))) { remove_vertex(v); removed = true; } } return removed; }
void SealData::convert_vertex(DxTop2D * vert_arr, const D3DXMATRIX & world_mat, DxTop2D * converted_vert_arr) const { for (int vert_No = 0; vert_No < get_vertex_num(); ++vert_No) { const D3DVECTOR & base_pos = vert_arr[vert_No].pos; D3DXMATRIX base_mat; D3DXMatrixIdentity(&base_mat); base_mat(3, 0) = base_pos.x; base_mat(3, 1) = base_pos.y; base_mat(3, 2) = base_pos.z; D3DXMATRIX converted_mat; D3DXMatrixMultiply(&converted_mat, &base_mat, &world_mat); D3DVECTOR & converted_pos = converted_vert_arr[vert_No].pos; converted_pos.x = converted_mat(3, 0); converted_pos.y = converted_mat(3, 1); converted_pos.z = converted_mat(3, 2); } }
int saveChunkVertexVector(std::string file_name, int _chunk_num, int _chunk_size) { std::string save_file = file_name + ".cv"; FILE * fv = fopen(save_file.c_str(), "w"); if(fv == NULL){ std::cout << "file open error in vv..." << std::endl; } unsigned int _vertex_num = get_vertex_num(); fprintf(fv, "cv v%u c%d s%d\n", _vertex_num, _chunk_num, _chunk_size); for(unsigned int i = 0; i < _vertex_num; i++) { fprintf(fv, "%u", get_id_by_index(i)); int index = i * _chunk_size; for(int j = 0; j < _chunk_size; j++) { fprintf(fv, " %d", vvArray[index + j]); } fprintf(fv, "\n"); } fclose(fv); return 1; }
/* Remove transitive edge. e.g: Given edges of G, there are v1->v2->v3, v1->v3, then v1->v3 named transitive edge. Algo: INPUT: Graph with N edges. 1. Sort vertices in topological order. 2. Associate each edges with indicator respective, and recording them in one matrix(N*N) e.g: e1:v0->v2, e2:v1->v2, e3:v0->v1 0 1 2 0 -- e3 e1 1 -- -- e2 2 -- -- -- 3. Scan vertices according to toplogical order, remove all edges which the target-node has been marked at else rows. e.g: There are dependence edges: v0->v1, v0->v2. If v1->v2 has been marked, we said v0->v2 is removable, and the same goes for the rest of edges. */ void GRAPH::remove_transitive_edge() { BITSET_MGR bs_mgr; SVECTOR<UINT> vex_vec; sort_in_toplog_order(vex_vec, true); SVECTOR<UINT> vid2pos_in_bitset_map; //Map from VERTEX-ID to BITSET. INT i; //Mapping vertex id to its position in 'vex_vec'. for (i = 0; i <= vex_vec.get_last_idx(); i++) { vid2pos_in_bitset_map.set(vex_vec.get(i), i); } //Associate each edges with indicator respective. UINT vex_num = get_vertex_num(); SVECTOR<BITSET*> edge_indicator; //container of bitset. INT c; for (EDGE * e = m_edges.get_first(c); e != NULL; e = m_edges.get_next(c)) { UINT from = VERTEX_id(EDGE_from(e)); UINT to = VERTEX_id(EDGE_to(e)); UINT frompos = vid2pos_in_bitset_map.get(from); BITSET * bs = edge_indicator.get(frompos); if (bs == NULL) { bs = bs_mgr.create(); edge_indicator.set(frompos, bs); } //Each from-vertex is associated with //a bitset to record all to-vertices. bs->bunion(vid2pos_in_bitset_map.get(to)); } //end for each of edge //Scanning vertexs in topological order. for (i = 0; i < vex_vec.get_last_idx(); i++) { //Get the successor vector. BITSET * bs = edge_indicator.get(i); if (bs != NULL && bs->get_elem_count() >= 2) { //Do NOT remove the first edge. Position in bitset //has been sorted in topological order. for (INT pos_i = bs->get_first(); pos_i >= 0; pos_i = bs->get_next(pos_i)) { INT kid_from_vid = vex_vec.get(pos_i); INT kid_from_pos = vid2pos_in_bitset_map.get(kid_from_vid); //Get bitset that 'pos_i' associated. BITSET * kid_from_bs = edge_indicator.get(kid_from_pos); if (kid_from_bs != NULL) { for (INT pos_j = bs->get_next(pos_i); pos_j >= 0; pos_j = bs->get_next(pos_j)) { if (kid_from_bs->is_contain(pos_j)) { //The edge 'i->pos_j' is redundant. INT to_vid = vex_vec.get(pos_j); UINT src_vid = vex_vec.get(i); remove_edge(get_edge(src_vid, to_vid)); bs->diff(pos_j); } } } //end if } //end for } //end if } //end for each vertex }
bool si3::SealData::load( LPDIRECT3DDEVICE9 device, // in const TCHAR * path, // in LPDIRECT3DTEXTURE9 * texture, // out IDirect3DVertexBuffer9 ** vertbuff, // out IDirect3DIndexBuffer9 ** indexbuff, // out int * index_num, // out int * triangle_num, // out float piece_size, // in uint & width, // out uint & height) // out { dxsaferelease(*texture); dxsaferelease(*vertbuff); dxsaferelease(*indexbuff); HRESULT hr; // テクスチャのサイズを調べて記憶する D3DXIMAGE_INFO info; hr = D3DXGetImageInfoFromFile(path, &info); if (FAILED(hr)) return false; width = info.Width; height = info.Height; int piece_num_x = static_cast<int>(width / piece_size + 1); // 板ポリゴンを格子状に分割管理したときの列数 int piece_num_y = static_cast<int>(height / piece_size + 1); // 板ポリゴンを格子状に分割管理したときの行数 int piece_num = piece_num_x * piece_num_y; // 板ポリゴンを格子状に分割管理したときの断片の個数 int top_num_x = piece_num_x + 1; // 板ポリゴンを格子状に分割管理したときの頂点の列数 int top_num_y = piece_num_y + 1; // 板ポリゴンを格子状に分割管理したときの頂点の行数 int top_num = top_num_x*top_num_y; // 板ポリゴンを格子状に分割管理したときの頂点の個数 const int top_per_row = 2 * top_num_x; // 一行につき何個の頂点情報を使用するか const int top_of_grid = top_per_row * piece_num_y; // 格子状の頂点情報の合計 const int top_for_degen_per_row = 2; // 一行につき必要な縮退ポリゴン用の頂点情報の数 const int top_for_degen = top_for_degen_per_row * (piece_num_y - 1);// 縮退ポリゴン用の頂点情報の合計 *index_num = top_of_grid + top_for_degen; // 頂点インデックス情報の個数 *triangle_num = *index_num - 2; // 三角ポリゴンの合計 // テクスチャ作成 hr = D3DXCreateTextureFromFileEx( device, path, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture); if (FAILED(hr)) { return false; } bool result; // 頂点バッファ作成、頂点データ設定 result = init_vertex( device, top_num_x, top_num_y, top_num, static_cast<int>(width), static_cast<int>(height), piece_num_x, piece_num_y, vertbuff); if (result == false) return false; hr = device->CreateVertexBuffer( sizeof(DxTop2D)* top_num, D3DUSAGE_WRITEONLY, LAND_FVF, D3DPOOL_MANAGED, &converted_vertbuff, NULL); if (FAILED(hr)) return false; DxTop2D * vert_arr = nullptr; hr = (**vertbuff).Lock(0, 0, fw::pointer_cast<void **>(&vert_arr), 0); if (FAILED(hr)) return false; DxTop2D * converted_vert_arr = nullptr; hr = converted_vertbuff->Lock(0, 0, fw::pointer_cast<void **>(&converted_vert_arr), 0); if (FAILED(hr)) return false; memcpy(converted_vert_arr, vert_arr, sizeof(DxTop2D)*get_vertex_num()); (**vertbuff).Unlock(); converted_vertbuff->Unlock(); // 頂点インデックスバッファ作成、頂点インデックスデータ設定 result = init_index( device, *index_num, indexbuff, top_num_x, top_num_y, top_num, piece_num_x, piece_num_y); if (result == false) return false; return true; }