Point Face::norm()
{
	HalfEdge * he = m_halfedge;
	Point p1 = he->target ()->point () - he->source ()->point ();
	Point p2 = he->he_next ()->target ()->point () - he->target ()->point ();
	Point n = p1 ^ p2;
	n /= n.norm ();
	return n;
}
Esempio n. 2
0
bool Curve::RobustTraceBoundaryLoop(HalfEdge* startHe, int & loopSize)
{
	HalfEdge * che = startHe;
	if (!che->source()->boundary() || !che->target()->boundary())
	{
		std::cerr << "Error: the input halfedge is not on the boundary!" << std::endl;
		loopSize=0;
		return false;
	}
	bool ccw;
	Vertex * ver = che->source();
	HalfEdge * the = ver->most_ccw_out_halfedge();
	if (the == che)
	{ //Possiblly ccw is right, except the case that there is only one out halfedge starting from ver
		//in that case, check one more step forward is enough
		HalfEdge * tempthe = the->target()->most_ccw_out_halfedge();
		if (tempthe->edge()->boundary())
			ccw = true;
		else
		{
			assert(ver->most_ccw_out_halfedge() == ver->most_clw_out_halfedge());
			ccw = false;
		}
	}
	else
	{
		ccw = false;
		the = ver->most_clw_out_halfedge();
		assert(the == che);
	}
	the = che;
	std::vector<HalfEdge *>::iterator finditer;
	while (the->target() != ver)
	{
		finditer = std::find(helist.begin(), helist.end(), the);
		if (finditer != helist.end())
		{//found
			std::cerr << "Possible Error: not go back to the starting point!" << std::endl;
			helist.erase(helist.begin(), finditer-1);
			loopSize =  helist.size();
			return false;
		}
		else
		{//not found
			helist.push_back(the);
		}	
		
		if (ccw)
			the = the->target()->most_ccw_out_halfedge();
		else 
			the = the->target()->most_clw_out_halfedge();
	}
	helist.push_back(the);
	loopSize = helist.size();
	return true;
}
Esempio n. 3
0
void SolidDelegate::removeFace (Solid * pS, Face * f) 
{
	int i;
	HalfEdge * he = f->halfedge ();
	for(i=0; i<3; i++)
	{
		he = he->he_next ();
		Vertex * v = he->target ();
		if(v->halfedge () == he)
		{
			for(SolidEdgeIterator eiter(pS); !eiter.end (); ++eiter)
			{
				Edge * e = *eiter;
				HalfEdge * hhe = e->halfedge (0);
				if(hhe->target () == v && hhe != he)
				{
					v->halfedge () = hhe;
					break;
				}
				else if (e->halfedge (1) != NULL && e->halfedge (1)->target () == v && e->halfedge (1) != he)
				{
					v->halfedge () = e->halfedge (1);
					break;
				}
			}
		}
		if(v->halfedge () == he)
			v->halfedge () = NULL;
	}
	for(i=0; i<3; i++)
	{
		HalfEdge * nhe = he->he_next ();
	//	Vertex * v = he->target ();
		Edge * e = he->edge ();
		if(e->halfedge (1) == NULL)
		{
			removeEdge(pS, e);
			delete e;
			delete he;
		}
		else
		{
			if(e->halfedge (0) == he)
				e->halfedge (0) = e->halfedge (1);
			delete he;
			e->halfedge(1) = NULL;
		}
		he = nhe;
	}

	pS->m_faces.remove(f);
}
Esempio n. 4
0
void Curve::ReplaceSections(Vertex * startV, Vertex * endV, std::vector<HalfEdge  *> & replaceList)
{	
	int i,j;
	int startInd, endInd;
	startInd = endInd = -1;
	for (i=0;i<helist.size(); ++i)
	{
		HalfEdge * he = helist[i];
		if (he->source() == startV)
		{
			startInd = i;
			break;
		}
	}
	assert(startInd != -1);
	for (j=i; j<helist.size();++j)
	{
		HalfEdge * he = helist[j];
		if (he->target() == endV)
		{
			endInd = j;
			break;
		}
	}
	assert(endInd != -1);
	ReplaceSections(startInd, endInd, replaceList);
}
Esempio n. 5
0
int Curve::TraceFeatureCurve(Mesh * mesh, HalfEdge * heStart)
{
	helist.clear();
	MeshUtility::MarkSharpEdges(mesh);
	HalfEdge * che = heStart;
	Edge * ce = che->edge();
	if (!ce->sharp())
	{
		std::cerr << "Error: the input halfedge is not a feature edge!" << std::endl;
		return 0;
	}
	helist.push_back(che);

	Vertex * startV = che->source();
	Vertex * cv = che->target();

	while (cv!=startV)
	{
		bool flag = false;
		for (VertexOutHalfedgeIterator vhe(mesh, cv); !vhe.end(); ++vhe)
		{
			HalfEdge * he = *vhe;
			if (he->edge()->sharp() && he->edge() != ce)
			{
				che = he;
				cv = che->target();
				ce = che->edge();				
				flag = true;
				break;
			}
		}
		if (!flag)
		{
			std::cerr << "Cannot find a circle!" << std::endl;
			helist.clear();
			return 0;
		}

		helist.push_back(che);
		if (che->target() == startV)
		{
			//succeed
			return helist.size();
		}	
	}
	return helist.size();
}
bool Face::include_vertex(Vertex *v)
{
	HalfEdge * he = m_halfedge;
	if(he->target () == v || he->source () == v || he->he_next ()->target () == v)
		return true;
	return false;

}
Esempio n. 7
0
	int superMi::assign_kuv_to_edge(Solid* mesh)
	{
		for (SolidEdgeIterator seiter(mesh); !seiter.end(); ++seiter){
			Edge* se = *seiter;
			se->kuv_h() = 0.0;
			//Point p1 = mesh->edgeVertex1(se)->point();
			//Point p3 = mesh->edgeVertex2(se)->point();

			//HalfEdge* he2 = se->halfedge(0)->ccw_rotate_about_source();
			//HalfEdge* he4 = se->halfedge(0)->clw_rotate_about_source();

			//Point p2 = he2->target()->point();
			//Point p4 = he4->target()->point();

			//double alpha =  ((p3 - p2)*(p1 - p2) / ((p3 - p2) ^ (p1 - p2)).norm()) / 2.0;
			//double beta =  ((p3 - p4)*(p1 - p4) / ((p3 - p4) ^ (p1 - p4)).norm()) / 2.0;

			//se->kuv_h() = alpha + beta;

			HalfEdge* he = se->halfedge(0);
			HalfEdge* nhe = he->he_next();
			HalfEdge* phe = he->he_prev();
			Face* hef = he->face();

			double nhel = (nhe->target()->point() - nhe->source()->point()).norm();
			double phel = (phe->target()->point() - phe->source()->point()).norm();
			double hel = (he->target()->point() - he->source()->point()).norm();

			se->kuv_h() += (nhel*nhel + phel*phel - hel*hel) / hef->area() / 8.0;

			he = se->halfedge(1);
			nhe = he->he_next();
			phe = he->he_prev();
			hef = he->face();
			nhel = (nhe->target()->point() - nhe->source()->point()).norm();
			phel = (phe->target()->point() - phe->source()->point()).norm();

			se->kuv_h() += (nhel*nhel + phel*phel - hel*hel) / hef->area() / 8.0;

			se->kuv_t() = 1.0;
			//std::cout << se->kuv() << std::endl;
		}

		return 0;
	}
Esempio n. 8
0
void Curve::TraceBoundary(HalfEdge * startHe, Vertex * endV)
{
	HalfEdge * che = startHe;
	if (!che->source()->boundary() || !che->target()->boundary())
	{
		std::cerr << "Error: the input halfedge is not on the boundary!" << std::endl;
		return;
	}
	bool ccw;
	Vertex * ver = che->source();
	HalfEdge * the = ver->most_ccw_out_halfedge();
	if (the == che)
	{ //Possiblly ccw is right, except the case that there is only one out halfedge starting from ver
		//in that case, check one more step forward is enough
		HalfEdge * tempthe = the->target()->most_ccw_out_halfedge();
		if (tempthe->edge()->boundary())
			ccw = true;
		else
		{
			assert(ver->most_ccw_out_halfedge() == ver->most_clw_out_halfedge());
			ccw = false;
		}
	}
	else
	{
		ccw = false;
		the = ver->most_clw_out_halfedge();
		assert(the == che);
	}
	the = che;
	std::vector<HalfEdge *>::iterator finditer;

	while (the->vertex() != endV)
	{
		helist.push_back(the);
		if (ccw)
			the = the->target()->most_ccw_out_halfedge();
		else 
			the = the->target()->most_clw_out_halfedge();
		if (helist.size()>10000000)
		{
			assert(0);
		}
	}
}
Esempio n. 9
0
bool Curve::WriteToFile(const char file[])
{
	//if (!valid)
	//{
	//	std::cerr << "Error: The curve is invalid" << std::endl;
	//	return false;
	//}

	std::ofstream fp;
	fp.open(file);
	if (!fp.good())
	{
		std::cerr << "I/O Error: Cannot write into file " << file << " !" << std::endl;
		return false;
	}
	fp << helist.size() << std::endl;
	for (int i=0;i<helist.size(); ++i)
	{
		HalfEdge * he = helist[i];
		fp << he->source()->id() << " " << he->target()->id() << std::endl;
	}
	fp.close();
	return true;
}
Esempio n. 10
0
void main(int argc, char *argv[])
{
	// Read in the obj file
	Solid mesh;
	
	OBJFileReader of;
	std::ifstream in(argv[1]);
	of.readToSolid(&mesh, in);

	SolidDelegate sodel;
	SolidVertexIterator viter(&mesh);
	SolidFaceIterator faceiter(&mesh);
	
	Point deltaPL[2502];
	Point Normal[2502];
	Point tuettePoint[2502];
	Point harmonicPoint[2502];
	double innerProduct;
	Point normalComp;
	Point aDerv;
	for (int i = 0; i < 2502; i++)
	{
		deltaPL[i][0] = 0.0;
		deltaPL[i][1] = 0.0;
		deltaPL[i][2] = 0.0;
		Normal[i][0] = 0.0;
		Normal[i][1] = 0.0;
		Normal[i][2] = 0.0;
		tuettePoint[i][0] = 0.0;
		tuettePoint[i][1] = 0.0;
		tuettePoint[i][2] = 0.0;
		harmonicPoint[i] = { 0.0, 0.0, 0.0 };

	}
	for (; !viter.end(); ++viter)
	{
		
		Vertex *vertmp = *viter;
		//VertexOutHalfedgeIterator voh(&mesh, vertmp);
		
		Point norm;//calc new Norm
		double totalArea = 0.0;
		
		norm[0] = norm[1] = norm[2] = 0.0;
		VertexFaceIterator vf(vertmp);
		for (; !vf.end(); ++vf){
			double area = 0.0;
			Face *f = *vf;
			
			Point v1 = f->halfedge()->source()->point();
			Point v2 = f->halfedge()->target()->point();
			Point v3 = f->halfedge()->he_next()->target()->point();

			area = ((v3 - v1) ^ (v2 - v1)).norm();
			

			Point n = f->norm();
			norm += n * area;
			totalArea += area;
		}
		

		Point newNorm;
		norm = norm / totalArea;
		double normN = norm.norm();
		newNorm = norm / normN;
		

		//Normal & Gauss Map
		Normal[vertmp->id() - 1] = newNorm;
	
		

	}
	
	SolidEdgeIterator edgeiter(&mesh);

	
	double tuetteEnergy = 0.0;
	double newTEnergy = 0.0;
	double harmoincEnergy = 0.0;
	double newHEnergy = 0.0;
	double stepLength = 0.01;
	double eThreshold = 0.00001;
	
	for (; !edgeiter.end(); ++edgeiter) {
		Edge *e = *edgeiter;

		Vertex *s = mesh.edgeVertex1(e);
		Vertex *t = mesh.edgeVertex2(e);
	
		tuetteEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2();
		 
		
	}

	//harmonic K
	double K, cota, cotb;


	edgeiter.reset();
	
	for (; !edgeiter.end(); ++edgeiter) {
		Edge *e = *edgeiter;
		Vertex *s = mesh.edgeVertex1(e);
		Vertex *t = mesh.edgeVertex2(e);
		HalfEdge *he = e->halfedge(1);
		he = he->ccw_rotate_about_source();
		Vertex *v1 = he->target();
		he = he->clw_rotate_about_source()->clw_rotate_about_source();
		Vertex *v2 = he->target();
		cota = (s->point() - v1->point())*(t->point() - v1->point()) / ((s->point() - v1->point()) ^ (t->point() - v1->point())).norm();
		cotb = (s->point() - v2->point())*(t->point() - v2->point()) / ((s->point() - v2->point()) ^ (t->point() - v2->point())).norm();
		
		
		K = (cota + cotb) / 2.0;
		edgemap.insert({ e, K });

	}

	viter.reset();
	//Gauss map update
	for (; !viter.end(); ++viter) {
		Vertex *vertmp = *viter;
		vertmp->point() = Normal[vertmp->id() - 1]  ;
	}

	
	
	viter.reset();
	

	for (; !viter.end(); ++viter)//step2
	{


		Vertex *vertmp = *viter;
		VertexOutHalfedgeIterator voh(&mesh, vertmp);
		Point u = vertmp->point();
		int id = vertmp->id()-1;
		double num = 0.0;
		for (; !voh.end(); ++voh)
		{
			
			HalfEdge *he1 = *voh;
			Vertex *v1 = he1->target();
			Point v = v1->point();

			deltaPL[id] += v - u;
			num = num + 1.0;
		}
		deltaPL[id] = deltaPL[id] / num;
	}

	//absolute derivatives
	viter.reset();
	for (; !viter.end(); ++viter)//step2
	{
		Vertex *vertmp = *viter;
		VertexOutHalfedgeIterator voh(&mesh, vertmp);
		Point u = vertmp->point();
		int id = vertmp->id() - 1;
		
		innerProduct = deltaPL[id] * Normal[id];
	
	
		normalComp[0] = innerProduct * Normal[id][0];
		normalComp[1] = innerProduct * Normal[id][1];
		normalComp[2] = innerProduct * Normal[id][2];
		
		Point aDerv = deltaPL[id] - normalComp;
		Point tuetteUpdate = aDerv * stepLength;
		

		tuettePoint[id] = tuetteUpdate; //step 3
		
	}

	viter.reset();
	for (; !viter.end(); ++viter)//step2
	{
		Vertex *vertmp = *viter;
		int id = vertmp->id() - 1;
		Normal[id] += tuettePoint[id];
		Normal[id] = Normal[id] / Normal[id].norm();
	}

	
		
	edgeiter.reset();
		
	for (; !edgeiter.end(); ++edgeiter) {
		Edge *e = *edgeiter;

		Vertex *s = mesh.edgeVertex1(e);
		Vertex *t = mesh.edgeVertex2(e);

		newTEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2();

   	}
	viter.reset();
		//tuette map update
	for (; !viter.end(); ++viter) {
		Vertex *vertmp = *viter;
		vertmp->point() =Normal[vertmp->id() - 1];
	}

	
	
	
	
	//while(1==0)
	while (!(fabs(newTEnergy - tuetteEnergy) < eThreshold*1000))
	{//step 5
		tuetteEnergy = newTEnergy;
		newTEnergy = 0.0;
		//printf("%f\n", tuetteEnergy);
		
		
		
		
		viter.reset();


		for (; !viter.end(); ++viter)//step2
		{


			Vertex *vertmp = *viter;
			VertexOutHalfedgeIterator voh(&mesh, vertmp);
			Point u = vertmp->point();
			int id = vertmp->id() - 1;
			double num = 0.0;
			for (; !voh.end(); ++voh)
			{

				HalfEdge *he1 = *voh;
				Vertex *v1 = he1->target();
				Point v = v1->point();

				deltaPL[id] += v - u;
				num = num + 1.0;
			}
			deltaPL[id] = deltaPL[id] / num;
		}

		viter.reset();
		for (; !viter.end(); ++viter)//step2
		{
			Vertex *vertmp = *viter;
			VertexOutHalfedgeIterator voh(&mesh, vertmp);
			Point u = vertmp->point();
			int id = vertmp->id() - 1;

			innerProduct = deltaPL[id] * Normal[id];


			normalComp[0] = innerProduct * Normal[id][0];
			normalComp[1] = innerProduct * Normal[id][1];
			normalComp[2] = innerProduct * Normal[id][2];

			Point aDerv = deltaPL[id] - normalComp;
			Point tuetteUpdate = aDerv * stepLength;


			tuettePoint[id] = tuetteUpdate; //step 3

		}

		viter.reset();
		for (; !viter.end(); ++viter)//step2
		{
			Vertex *vertmp = *viter;
			int id = vertmp->id() - 1;
			Normal[id] += tuettePoint[id];
			Normal[id] = Normal[id] / Normal[id].norm();
		}



		edgeiter.reset();

		for (; !edgeiter.end(); ++edgeiter) {
			Edge *e = *edgeiter;

			Vertex *s = mesh.edgeVertex1(e);
			Vertex *t = mesh.edgeVertex2(e);

			newTEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2();

		}
		viter.reset();
		//tuette map update
		for (; !viter.end(); ++viter) {
			Vertex *vertmp = *viter;
			vertmp->point() = Normal[vertmp->id() - 1];
		}
}

	tuetteEnergy = newTEnergy;
	harmoincEnergy = tuetteEnergy;
	//harmonic

	viter.reset();


	for (; !viter.end(); ++viter)//step2
	{


		Vertex *vertmp = *viter;
		VertexOutHalfedgeIterator voh(&mesh, vertmp);
		Point u = vertmp->point();
		int id = vertmp->id() - 1;
		double num = 0.0;
		for (; !voh.end(); ++voh)
		{

			HalfEdge *he1 = *voh;
			Edge *e = he1->edge();
			Vertex *v1 = he1->target();
			Point v = v1->point();
			std::unordered_map<Edge*,double>::const_iterator got = edgemap.find(e);
			double K = got->second;
			deltaPL[id] += (v - u) * K;
			num = num + 1.0;
		}
		deltaPL[id] = deltaPL[id] / num;
	}
	
	//absolute derivatives
	viter.reset();
	for (; !viter.end(); ++viter)//step2
	{
		Vertex *vertmp = *viter;
		VertexOutHalfedgeIterator voh(&mesh, vertmp);
		Point u = vertmp->point();
		int id = vertmp->id() - 1;

		innerProduct = deltaPL[id] * Normal[id];


		normalComp[0] = innerProduct * Normal[id][0];
		normalComp[1] = innerProduct * Normal[id][1];
		normalComp[2] = innerProduct * Normal[id][2];

		Point aDerv = deltaPL[id] - normalComp;
		Point hUpdate = aDerv * stepLength;


		harmonicPoint[id] =hUpdate; //step 3

	}
	// compute mass center
	Point mass = { 0.0, 0.0, 0.0 };
	viter.reset();

	for (; !viter.end(); ++viter)//step2
	{
		Vertex *vertmp = *viter;
		mass += vertmp->point();
	}
	mass = mass / 2502;

	// h update w/ mass
	viter.reset();
	for (; !viter.end(); ++viter)//step2
	{
		Vertex *vertmp = *viter;
		int id = vertmp->id() - 1;
		Normal[id] +=harmonicPoint[id];
		Normal[id] -= mass;
		Normal[id] = Normal[id] / Normal[id].norm();
	}

	//h energy
	edgeiter.reset();

	for (; !edgeiter.end(); ++edgeiter) {
		Edge *e = *edgeiter;

		Vertex *s = mesh.edgeVertex1(e);
		Vertex *t = mesh.edgeVertex2(e);
		
		std::unordered_map<Edge*, double>::const_iterator got = edgemap.find(e);
		double K = got->second;
		
		newHEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2()*K;

	}
	viter.reset();
	//h map update
	for (; !viter.end(); ++viter) {
		Vertex *vertmp = *viter;
		vertmp->point() = Normal[vertmp->id() - 1];
	}
	
	
	
	while (!(fabs(newHEnergy - harmoincEnergy) < eThreshold))
	{
		harmoincEnergy = newHEnergy;
		newHEnergy = 0.0;
		//printf("%f\n", harmoincEnergy);


		viter.reset();


		for (; !viter.end(); ++viter)//step2
		{


			Vertex *vertmp = *viter;
			VertexOutHalfedgeIterator voh(&mesh, vertmp);
			Point u = vertmp->point();
			int id = vertmp->id() - 1;
			double num = 0.0;
			for (; !voh.end(); ++voh)
			{

				HalfEdge *he1 = *voh;
				Edge *e = he1->edge();
				Vertex *v1 = he1->target();
				Point v = v1->point();
				std::unordered_map<Edge*, double>::const_iterator got = edgemap.find(e);
				double K = got->second;
				deltaPL[id] += (v - u) * K;
				num = num + 1.0;
			}
			deltaPL[id] = deltaPL[id] / num;
		}

		//absolute derivatives
		viter.reset();
		for (; !viter.end(); ++viter)//step2
		{
			Vertex *vertmp = *viter;
			VertexOutHalfedgeIterator voh(&mesh, vertmp);
			Point u = vertmp->point();
			int id = vertmp->id() - 1;

			innerProduct = deltaPL[id] * Normal[id];


			normalComp[0] = innerProduct * Normal[id][0];
			normalComp[1] = innerProduct * Normal[id][1];
			normalComp[2] = innerProduct * Normal[id][2];

			Point aDerv = deltaPL[id] - normalComp;
			Point hUpdate = aDerv * stepLength;


			harmonicPoint[id] = hUpdate; //step 3

		}
		// compute mass center
		Point mass = { 0.0, 0.0, 0.0 };
		viter.reset();

		for (; !viter.end(); ++viter)//step2
		{
			Vertex *vertmp = *viter;
			mass += vertmp->point();
		}
		mass = mass / 2502;

		// h update w/ mass
		viter.reset();
		for (; !viter.end(); ++viter)//step2
		{
			Vertex *vertmp = *viter;
			int id = vertmp->id() - 1;
			Normal[id] += harmonicPoint[id];
			Normal[id] -= mass;
			Normal[id] = Normal[id] / Normal[id].norm();
		}

		//h energy
		edgeiter.reset();

		for (; !edgeiter.end(); ++edgeiter) {
			Edge *e = *edgeiter;

			Vertex *s = mesh.edgeVertex1(e);
			Vertex *t = mesh.edgeVertex2(e);

			std::unordered_map<Edge*, double>::const_iterator got = edgemap.find(e);
			double K = got->second;

			newHEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2()*K;

		}
		viter.reset();
		//h map update
		for (; !viter.end(); ++viter) {
			Vertex *vertmp = *viter;
			vertmp->point() = Normal[vertmp->id() - 1];
		}

	}

	/***conformal****/


	// Write out the resultant obj file
	int vObjID = 1;
	std::map<int, int> vidToObjID;

	std::ofstream os(argv[2]);

	SolidVertexIterator iter(&mesh);

	for (; !iter.end(); ++iter)
	{
		Vertex *v = *iter;
		Point p = v->point();
		os << "v " << p[0] << " " << p[1] << " " << p[2] << std::endl;
		vidToObjID[v->id()] = vObjID++;
	}
	os << "# " << (unsigned int)mesh.numVertices() << " vertices" << std::endl;


	//texture
	float u = 0.0, v = 0.0;
	for (iter.reset(); !iter.end(); ++iter)
	{
		Vertex *vv = *iter;
		std::string key("uv");
		std::string s = Trait::getTraitValue(vv->string(), key);
		if (s.length() > 0)
		{
			sscanf(s.c_str(), "%f %f", &u, &v);
		}
		os << "vt " << u << " " << v << std::endl;
	}
	os << "# " << (unsigned int)mesh.numVertices() << " texture coordinates" << std::endl;

	SolidFaceIterator fiter(&mesh);
	for (; !fiter.end(); ++fiter)
	{
		Face *f = *fiter;
		FaceVertexIterator viter(f);
		os << "f ";
		for (; !viter.end(); ++viter)
		{
			Vertex *v = *viter;
			os << vidToObjID[v->id()] << "/" << vidToObjID[v->id()] << " ";
		}
		os << std::endl;
	}
	os.close();
}
Esempio n. 11
0
void Curve::BuildList(std::list<Edge *> edges, Vertex * startV)
{
	// first we find the startV;
	valid = false;
	HalfEdge * startHE;
	std::list<Edge *>::iterator listEiter;
	for (listEiter=edges.begin(); listEiter!=edges.end(); ++listEiter)
	{
		//Edge * e = edges[i];
		Edge * e = *listEiter;
		
		if (e->halfedge(0)->source() == startV)
		{
			valid = true;
			startHE = e->halfedge(0);
			break;
		}
		else if (e->halfedge(1) && e->halfedge(1)->source() == startV)
		{
			valid = true;
			startHE = e->halfedge(1);
			break;
		}			
	}

	if (!valid)
		return;
	
	HalfEdge * che = startHE;
	helist.push_back(che);
	edges.erase(listEiter);
	
				
	while (edges.size()>0)
	{
		valid = false;
		for (listEiter=edges.begin(); listEiter!=edges.end(); ++listEiter)
		{
			Edge * e = *listEiter;
			HalfEdge * he1 = e->halfedge(0);
			//HalfEdge * he2 = e->halfedge(1);
			if (he1->source() == che->target())
			{
				// use he1
				valid = true;
				che = he1;	
				helist.push_back(che);
				break;
			}
			else if (he1->target() == che->target())
			{

				// he1
				che = e->halfedge(1);
				if (!che)
				{
					valid = false;
					return;							
				}
				else
				{
					valid = true;
					helist.push_back(che);
					break;
				}
			}
		}
		if (valid)
			edges.erase(listEiter);
		else
			return;
	}
}