Example #1
0
void Face <T> ::print ( std::ostream * output ) const
{
        //Print Face
        if ( edge != NULL )
        {
                //Get next edge in cell
                HalfEdge <T> *e = edge;

                //Proces all edges of the Face
                do
                {
                        //Print edge
                        e->print ( output );

                        //Add new line
                        *output << '\n';

                        //Increment edge
                        e = e->getNextEdge();

                }
                while ( e != edge );
        }

        std::cout << std::endl;
}
bool Face::include_edge(Edge *e)
{
	HalfEdge * he = m_halfedge;
	if(he->edge () == e || he->he_next ()->edge () == e || he->he_prev ()->edge () == e)
		return true;
	return false;
}
Example #3
0
// Return whether a point is inside, on, or outside the cell:
//   -1: point is outside the perimeter of the cell
//    0: point is on the perimeter of the cell
//    1: point is inside the perimeter of the cell
//
int Cell::pointIntersection(double x, double y) {
	// Check if point in polygon. Since all polygons of a Voronoi
	// diagram are convex, then:
	// http://paulbourke.net/geometry/polygonmesh/
	// Solution 3 (2D):
	//   "If the polygon is convex then one can consider the polygon
	//   "as a 'path' from the first vertex. A point is on the interior
	//   "of this polygons if it is always on the same side of all the
	//   "line segments making up the path. ...
	//   "(y - y0) (x1 - x0) - (x - x0) (y1 - y0)
	//   "if it is less than 0 then P is to the right of the line segment,
	//   "if greater than 0 it is to the left, if equal to 0 then it lies
	//   "on the line segment"
	HalfEdge* he;
	size_t edgeCount = halfEdges.size();
	Point2 p0;
	Point2 p1;
	double r;

	while (edgeCount--) {
		he = halfEdges[edgeCount];
		p0 = *he->startPoint();
		p1 = *he->endPoint();
		r = (y - p0.y)*(p1.x - p0.x) - (x - p0.x)*(p1.y - p0.y);

		if (r == 0) {
			return 0;
		}
		if (r > 0) {
			return -1;
		}
	}
	return 1;
}
Example #4
0
void Face <T>::removeAdjacency()
{
        //Set twin edges of Faces adjacent to actual Face to NULL
        if ( edge != NULL )
        {
                //Get actual edge in cell
                HalfEdge <T> *e = edge;

                //Proces all edges of the Face
                do
                {
                        //Get twin edge
                        HalfEdge <T> *e_twin = e->getTwinEdge();

                        //Adjacent cell exists
                        if ( e_twin != NULL )
                        {
                                //Set pointer to NULL
                                e_twin -> setTwinEdge ( NULL );
                        }

                        //Increment edge
                        e = e->getNextEdge();

                }
                while ( e != edge );
        }
}
int TriangleAdjacencyGraph::fillIndexFromFan( std::vector<Index> &indexVec,
    HalfEdge &firstEdge )
{
  int count = 0;
  HalfEdge *halfEdge(&firstEdge);
  HalfEdge *gateEdge = 0;

  if (halfEdge) {
    count = 3;
    indexVec.resize(2);
    indexVec[0] = halfEdge->vertexStart();
    indexVec[1] = halfEdge->vertexEnd();
    for ( gateEdge = halfEdge->next->next->twin;
	gateEdge != halfEdge;
	gateEdge = gateEdge->next->next->twin ) {
      indexVec.push_back(gateEdge->vertexEnd());
      count++;
    }
    indexVec.push_back(halfEdge->vertexEnd());
  }
  else {
    cerr << "Invalid fac in fillIndexFromFan()" << endl;
  }

  return count;
}
int TriangleAdjacencyGraph::calcEgdeLines ( vector<Index> & indexVec, bool codeBorder )
{
  unsigned int i, nN, j, nE, halfEdgeCount = 0;
  Index startVertexIndex, endVertexIndex;
  HalfEdge *halfEdge;
  bool isBorder;

  indexVec.clear();
  nN = _temporaryVector.size();
  for (i = 0; i < nN; i++) {
    nE = _temporaryVector[i].size();
    for ( j = 0; j < nE; j++) {      
      halfEdge = _temporaryVector[i][j].second;
      startVertexIndex = halfEdge->vertexStart();
      endVertexIndex = halfEdge->vertexEnd();

      if ((isBorder = (halfEdge->twin == 0)) || (startVertexIndex <
	    endVertexIndex)) {
	indexVec.push_back(startVertexIndex);
	indexVec.push_back(endVertexIndex);
	if (codeBorder)
	  indexVec.push_back(isBorder ? 0 : 1);
	halfEdgeCount++;
      }
    }
  }

  return halfEdgeCount;
}
Example #7
0
unsigned int Face <T> ::countVertices() const
{
        //Count vertices of the Face
        unsigned int vertices = 0;

        //There is a valid edge
        if ( edge != NULL )
        {
                //Get next edge in cell
                HalfEdge <T> *e = edge;

                //Proces all edges of the Face
                do
                {
                        //Increment vertices
                        vertices ++;

                        //Increment edge
                        e = e->getNextEdge();

                }
                while ( e != edge );
        }

        return vertices;
}
Example #8
0
void DigraphL::print(void) {
	// Wagi krawedzi od 'v' do kazdego z V wierzcholkow (moga byc nieskonczone)
	int matrix[V];	
	HalfEdge* edge;
			
 	for (int v = 0; v < V; v++) {
		edges[v]->rewind();
		// Inicjujemy tablice nieskonczonymi wagami
 		for (int w = 0; w < V; w++)
			matrix[w] = INF;	
		
		// Uaktualniamy wagi odpowadajace istniejacym krawedziom
		while (edges[v]->hasMoreElements()) {
			edge = edges[v]->getNext();
			matrix[edge->getEndingVertexIndex()] = edge->getWeight();
		}
		
		// Wypisujemy wagi na ekran
  		for (int w = 0; w < V; w++) {
			cout << "\t";
 			if (matrix[w] != INF)
				cout << matrix[w];
			else
				cout << "-";
		}
		cout << endl;
	}
	cout << endl;
}
Example #9
0
//----------------------------------------------------------------------
// Method: fillPrimFromFan
// Author: jbehr
// Date:   Tue Feb 15 18:16:59 2000
// Description:
//
//----------------------------------------------------------------------
Int32 HalfEdgeGraph::fillIndexFromFan(std::vector<HalfEdgeGraph::IndexT> &indexVec,
                                      HalfEdge &firstEdge )
{
    Int32 count = 0;
    HalfEdge *halfEdge(&firstEdge);
    HalfEdge *gateEdge = 0;

    if(halfEdge)
    {
        count = 3;
        indexVec.resize(2);
        indexVec[0] = halfEdge->vertexStart();
        indexVec[1] = halfEdge->vertexEnd();
        for(gateEdge = halfEdge->next->next->twin;
                gateEdge != halfEdge;
                gateEdge = gateEdge->next->next->twin)
        {
            indexVec.push_back(gateEdge->vertexEnd());
            ++count;
        }
        indexVec.push_back(halfEdge->vertexEnd());
    }
    else
    {
        SWARNING << "Invalid fac in fillIndexFromFan()" << endl;
    }
    return count;
}
Example #10
0
//----------------------------------------------------------------------
// Method: calcEdgeLines
// Author: jbehr
// Date:   Tue Feb 15 18:16:59 2000
// Description:
//
//----------------------------------------------------------------------
Int32 HalfEdgeGraph::calcEgdeLines(vector<HalfEdgeGraph::IndexT> & indexVec,
                                   bool codeBorder )
{
    UInt32 i, nN, j, nE, halfEdgeCount = 0;
    HalfEdgeGraph::IndexT startVertexIndex, endVertexIndex;
    HalfEdge *halfEdge;
    bool isBorder;

    indexVec.clear();
    nN = _edgeLinkVec.size();
    for (i = 0; i < nN; ++i)
    {
        nE = _edgeLinkVec[i].size();
        for ( j = 0; j < nE; ++j)
        {
            halfEdge = _edgeLinkVec[i][j].second;
            startVertexIndex = halfEdge->vertexStart();
            endVertexIndex = halfEdge->vertexEnd();

            if ((isBorder = (halfEdge->twin == 0)) || (startVertexIndex <
                    endVertexIndex))
            {
                indexVec.push_back(startVertexIndex);
                indexVec.push_back(endVertexIndex);
                if(codeBorder)
                    indexVec.push_back(isBorder ? 0 : 1);
                ++halfEdgeCount;
            }
        }
    }
    return halfEdgeCount;
}
Example #11
0
T FacePerimeter:: getFacePerimeter ( const HalfEdge <T> *e_start )
{
        //Get perimeter of the Face given by start half edge
        T perimeter = 0;
        HalfEdge <T> *e = const_cast <HalfEdge <T> *> ( e_start );

        //There is a valid edge
        if ( e_start != NULL )
        {
                //Get point
                Node3DCartesian <T> *pi = e->getPoint();

                //Proces all edges of the Face
                do
                {
                        //Get point
                        Node3DCartesian <T> *pii = e->getNextEdge()->getPoint();

                        //Compute area
                        perimeter += EuclDistance::getEuclDistance2D ( pi->getX(), pi->getY(), pii->getX(), pii->getY() );

                        //Assign point
                        pi = pii;

                        //Assign edge
                        e = e->getNextEdge();

                }
                while ( e != e_start );
        }

        //Get area
        return perimeter;
}
Example #12
0
QVector3D Slice::linePLaneIntersection(HalfEdge edge, QVector3D planeOrigin, QVector3D planeNormal){
    QVector3D u=edge.getStart()->toVector3D()-edge.getStop()->toVector3D();
    QVector3D w=edge.getStop()->toVector3D()-planeOrigin;
    QVector3D normal=planeNormal;

    float d=QVector3D::dotProduct(normal,u);
    float n=-QVector3D::dotProduct(normal,w);
    //line is parallel to plane
    if(fabs(d)<0.00000001){
        if(n==0){
            qDebug() << "line is on plane";
            return QVector3D(edge.getStart()->toVector3D());
        }
        else{
            qDebug() << "no intersection";
            return QVector3D();
        }
    }
    //line croses plane
    float sI = n/d;
    if(sI<0 || sI>1){
        qDebug() << "no intersection";
        return QVector3D();
    }
    return edge.getStop()->toVector3D() + u*sI;
}
Example #13
0
//fill list of edges crossing plane on some z height
void Slice::fillEdgeLayer(){
    QList<Face*> currentLayer;
    Face* currentFace;
    HalfEdge* currentEdge;
    for(int i=0; i<this->triLayer.size(); i++){
        currentLayer=*this->triLayer.at(i);
        //take first face from list
        if(currentLayer.size()>0){
            while(currentLayer.size()>0){
                currentFace=currentLayer.takeFirst();
                currentEdge=currentFace->getEdgesCrossingPlane(this->layerHeight*i).at(0);
                //create list for firts edge loop
                this->edgeLayer.at(i)->append(new QList<HalfEdge*>);
                this->pointLayer.at(i)->append(new QList<QVector3D>);
                this->edgeLayer.at(i)->last()->append(currentEdge);
                //while all faces are processed
                do{
                    currentLayer.removeAt(currentLayer.indexOf(currentFace));
                    //take his twin
                    currentEdge=currentEdge->getTwin();
                    currentFace=currentEdge->getFaces().at(0);
                    //qDebug() << currentFace->getNeighbors().size();
                    if(currentFace->getEdgesCrossingPlane(this->layerHeight*i,currentEdge).size()!=1){
                        //qDebug() << "dupa" <<currentFace->getEdgesCrossingPlane(this->layerHeight*i,currentEdge).size();
                    }
                    currentEdge=currentFace->getEdgesCrossingPlane(this->layerHeight*i,currentEdge).first();
                    this->edgeLayer.at(i)->last()->append(currentEdge);
                }while(currentLayer.contains(currentFace));
            }
        }
    }
}
Example #14
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);
}
 /** Return node no ix from triangle.
 * \param ix is either 0, 1 or 2.
 */
 Node* getNode(size_t ix) {
     HalfEdge *he = m_he_;
     for(size_t i=0; i<ix; i++) {
         he = he->getNext();
     }
     return he->getSourceNode();
 }
Example #16
0
Curve::Curve(std::list<Edge *> edges)
{
	std::list<Edge *>::iterator eiter = edges.begin();
	Edge * e  = *eiter;
	HalfEdge * he = e->halfedge(0);
	Vertex * v = he->source();
	BuildList(edges, v);
}
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;

}
Example #18
0
  void TriMesh::buildConnectivity() {
  // skip
  // Use the algorithm from the lecture to categorize the edges into inner, boundary or non-manifold
  // Set the twin edge appropriately to the category of the current edge
  // For each node take its leading halfedge and rewind (using getVtxRingPrev) until:
  // - We get the one that we started with (no need to do anything)
  // - We get NULL - then the previous choice should be used as the nodes leading halfedge
  // unskip

    std::vector<SortElement> helper = std::vector<SortElement>();

    for(int i = 0; i < m_halfedges.size(); i++){
      helper.push_back(m_halfedges[i]);
    }

    std::sort(helper.begin(), helper.end());
    int i,j;
  //Loop through all edges
    for(j=0; j<helper.size(); j++){
      //Find i so that i and i+1 are different edges
      for(i=j; i<helper.size()-1; i++){
        if(helper[i].m_a != helper[i+1].m_a || helper[i].m_b != helper[i+1].m_b){
          break;
        }
      }

      if(i==j){
        helper[j].m_he->m_twin_ = NULL;
        // helper[j] points to a boundary edge
      }

      else if (i==j+1){
        helper[i].m_he->m_twin_ = helper[j].m_he;
        helper[j].m_he->m_twin_ = helper[i].m_he;
        // connect the triangles of helper[i] and helper[j]
      }
      else{
        std::cout << "Non-manifold mesh!" << std::endl;
      }
      j = i;
    }

	for (int i = 0; i < m_nodes.size(); i++){
		HalfEdge* beginLead = m_nodes[i].getLeadingHalfEdge();
		HalfEdge* tempLead = m_nodes[i].getLeadingHalfEdge();
		while(true){
			HalfEdge* rewindHe = tempLead->getVtxRingPrev();
			if (rewindHe == NULL){
				m_nodes[i].m_he_ = tempLead;
				break;
			}
			else if (rewindHe == beginLead)
				break;
			tempLead = rewindHe;
		}
	}

  }
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;
}
Example #20
0
void writePly(Interface& interface) {

    QFile file(saveToFileName);
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out(&file);

    QVector<Face *> faces = interface.getFaces();

    out << "ply" << "\n";
    out << "format ascii 1.0" << "\n";

    int vertex_count = interface.getVertices().size();
    int faces_count = faces.size();

    out << "element vertex " << vertex_count << "\n";
    out << "property float x" << "\n";
    out << "property float y" << "\n";

    out << "element face " << faces_count << "\n";
    out << "property list uchar int vertex_index" << "\n";

    out << "end_header" << "\n";

    QList<Vertex*> points = interface.getVertices().values();
    for (int i = 0; i < points.size(); i++) {
        QPointF p = points[i]->getPoint();
        qDebug() << "adicionando ponto: (" << p.x() << "," << p.y() << ")\n";
        //out << i << " ";
        out << p.x() << " " << p.y() << "\n";
    }

    for (int i = 0; i < faces.size(); i++) {
        HalfEdge* start = faces.at(i)->getOuterComp();
        HalfEdge* aux = start;

        //out << i << " ";

        qDebug() << "### Face: " << i << "\n";

        int vertex_per_face_counter = 0;
        QString tempStr;
        do {            
            QTextStream tempStream(&tempStr);

            Vertex* vertex = aux->getOrigem();
            int index = points.indexOf(vertex);

            tempStream << index << " ";
            aux = aux->getProx();

            vertex_per_face_counter++;
        } while (aux != start);

        out << vertex_per_face_counter << " " << tempStr << "\n";
    }

}
Example #21
0
HalfEdge* Face::MaxEdge()
{
	HalfEdge* MaxEdge = OuterEdge;

	MaxEdge = OuterEdge->Next->Lenght() > MaxEdge->Lenght() ? OuterEdge->Next : MaxEdge;
	MaxEdge = OuterEdge->Prev->Lenght() > MaxEdge->Lenght() ? OuterEdge->Prev : MaxEdge;

	return MaxEdge;
}
Example #22
0
HalfEdge* Face::MinEdge()
{
	HalfEdge* MinEdge = OuterEdge;

	MinEdge = OuterEdge->Next->Lenght() < MinEdge->Lenght() ? OuterEdge->Next : MinEdge;
	MinEdge = OuterEdge->Prev->Lenght() < MinEdge->Lenght() ? OuterEdge->Prev : MinEdge;

	return MinEdge;
}
Example #23
0
int Curve::CreateBoundaryLoop(Vertex * startV)
{
	HalfEdge * he = startV->most_ccw_out_halfedge();
	if (!he->edge()->boundary())
	{
		he = startV->most_clw_out_halfedge();
		assert(he->edge()->boundary());
	}
	return CreateBoundaryLoop(he);
}
Example #24
0
bool MyObject::buildHalfEdges(THalfEdgeList& lst)
{
    int pli, i;

    TPointPairHash m_pntmap;
    m_pntmap.reserve(150);
    // the pointer is the half edge already between these points

    for(pli = 0; pli < nPolys; ++pli)
    {
        MyPolygon *pol = poly[pli];

        HalfEdge *he = nullptr, *lasthe = nullptr;
        for(i = 3; i >= 0; --i)
        {
            //he = new HalfEdge(pol, pol->vtx[i], he);
            HalfEdge *prevhe = he;
            he = m_alloc->m_hePool.allocate();
            he->init(pol, pol->vtx[i], prevhe);
            lst.push_back(he);
            if (lasthe == nullptr)
                lasthe = he;

            if (pol->vtx[i]->he == nullptr)
                pol->vtx[i]->he = he;

        }
        lasthe->next = he;
        pol->he = he;

        for(i = 3; i >= 0; --i)
        {	
            PointPair pp(he->point, he->next->point);
            TPointPairHash::iterator it = m_pntmap.find(pp);
            if (it == m_pntmap.end()) // its not there, add it
                m_pntmap.insert(make_pair(pp, he));
            else
            {
                HalfEdge *she = it->second;
                M_ASSERT((she->next->point == he->point) && (he->next->point == she->point));
                he->pair = she;
                she->pair = he;
                m_pntmap.erase(it); // no longer needed in the map
            }
            he = he->next;
        }
        // maximum size of m_pntmap is 134
    }

    M_ASSERT(m_pntmap.empty());

    return true;
}
void TetrahedMesh::deconnect(vector<unsigned int> adjecentList, arma::Mat<double> v, unsigned int vIndex) {
	unsigned int vInd;
	Vertex temp;
	temp.setPosition(v);

	mVertices->push_back(temp);
	vInd = mVertices->size()-1;

	for (int j = 0; j < adjecentList.size(); j++) {

		vector<unsigned int> faceIndices = mTetraheds->at(adjecentList.at(j)).getFaceInd();

			for (int i = 0; i< faceIndices.size();i++) {

				Face & face = mFaces->at(faceIndices[i]);


				HalfEdge* edge = &mHalfEdges->at(face.getEdgeInd());

				Vertex & v1 = mVertices->at(edge->getVertexInd());

				if(vecEquals(v1.getPosition(),v)) {
					//mFaces->at(faceIndices[i]).setOppositeFaceInd(-1);
					edge->setVertexInd(vInd);

					break;
				}

				edge = &mHalfEdges->at(edge->getNextInd());

				Vertex & v2 = mVertices->at(edge->getVertexInd());

					if(vecEquals(v2.getPosition(),v)) {
					//mFaces->at(faceIndices[i]).setOppositeFaceInd(-1);
					edge->setVertexInd(vInd);


					break;
				}

				edge = &mHalfEdges->at(edge->getNextInd());

				Vertex & v3 = mVertices->at(edge->getVertexInd());

					if(vecEquals(v3.getPosition(),v)) {

					edge->setVertexInd(vInd);


					break;
				}



			}
	}
}
Example #26
0
void Interface::addFace(QVector<QPointF> in)
{
    Face *f = new Face();
    HalfEdge *ant = NULL;
    HalfEdge *first, *twin, *temp;

    for(int i = 0; i < in.size(); i++)
    {
        HalfEdge *e = new HalfEdge();
        if (i == 0)     first = e;

        temp = findTwin(in[i],in[(i+1)%in.size()]);
        if (temp != NULL)
            e = temp;
        else
            map[qMakePair(in[i], in[(i+1)%in.size()])] = e;

        twin = e->getTwin();
        if (twin == NULL)
            twin = findTwin(in[(i+1)%in.size()],in[i]);


        minX = MIN(minX, in[i].x());
        maxX = MAX(maxX, in[i].x());
        minY = MIN(minY, in[i].y());
        maxY = MAX(maxY, in[i].y());

        Vertex *v = addVertex(in[i]);
        v->setEdge(e);
        e->setOrigem(v);

        e->setFace(f);

        e->setAnt(ant);
        if (ant!= NULL)
        {
            ant->setProx(e);
        }

        e->setTwin(twin);
        if (twin!= NULL)
        {
            twin->setTwin(e);
        }

        ant = e;
    }

    first->setAnt(ant);
    ant->setProx(first);

    f->setOuterComp(first);

    faces.push_back(f);
}
Example #27
0
long DigraphL::getWeight(int v, int w) {
	if (v >= 0 && w >=0 && v < V && w < V) {
		HalfEdge* edge;		
		edges[v]->rewind();
		while (edges[v]->hasMoreElements()) {
			edge = edges[v]->getNext();
			if (edge->getEndingVertexIndex() == w)
				return edge->getWeight();
		}
		return INF;
	}
	else
		return INF;	
}
Example #28
0
double Face::S()
{
	HalfEdge* tmpHalfEdge = OuterEdge;

	double a = tmpHalfEdge->Lenght();
	tmpHalfEdge = tmpHalfEdge->Next;

	double b = tmpHalfEdge->Lenght();
	tmpHalfEdge = tmpHalfEdge->Next;

	double c = tmpHalfEdge->Lenght();
	tmpHalfEdge = tmpHalfEdge->Next;

	return sqrt( (a + b + c)*(b + c - a)*(a + c - b)*(a + b - c) );
}
Example #29
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();
}
Example #30
0
Face <T> :: Face ( const Container <Node3DCartesian <T> *, destructable> &nl, Container <HalfEdge <T> *> &hl )
{
        //Create Face from the list of nodes
        this->vertices_count = nl.size();
        this->edge = NULL;

        //Nodes list contains some points
        if ( this->vertices_count > 2 )
        {
                //Create first half edge
                HalfEdge <T> *h = new HalfEdge <T> ( nl [0], NULL, NULL, NULL ); //Create first edge
                HalfEdge <T> *h_start = h;
                hl.push_back ( h );

                //Create other half edges
                HalfEdge <T> *h_old = h;

                //Process all vertices
                for ( unsigned int i = 1; i < this->vertices_count; i++, h_old = h )
                {
                        //Create new edge and set previous edge
                        h = new HalfEdge <T> ( nl [i], h_old, NULL, NULL );

                        //Set next edge
                        h_old->setNextEdge ( h );

                        //Set face for each edge
                        h->setFace ( this );

                        //Add half edge to the list
                        hl.push_back ( h );
                }

                //Set previous edge of the first edge
                h_start->setPreviousEdge ( h );

                //Set next edge for the last edge
                h->setNextEdge ( h_start );

                //Set face for h start
                h_start->setFace ( this );

                //Set start edge of the Face
                this->edge = h_start;
        }
}