예제 #1
0
/*
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;
}
예제 #2
0
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;
}
예제 #3
0
/*
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;
}
예제 #4
0
	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);
		}

	}
예제 #5
0
	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;
        }
예제 #6
0
/*
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
}
예제 #7
0
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;
}