Example #1
0
bool Network::deleteVertex(vertex_id vid) {
	if (!containsVertex(vid)) return false;
	std::set<vertex_id> in = getInNeighbors(vid);
	std::set<vertex_id> out = getOutNeighbors(vid);

	// removing adjacent edges
	for (std::set<vertex_id>::iterator it=in.begin(); it!=in.end(); it++)
		deleteEdge(*it,vid);
	for (std::set<vertex_id>::iterator it=out.begin(); it!=out.end(); it++)
		deleteEdge(vid,*it);

	// removing the vertex
	vertexes.erase(vid);
	if (isNamed()) {
		// some more structures to empty
		const std::string& vertex_name=vertex_id_to_name[vid];
		vertex_id_to_name.erase(vid);
		vertex_name_to_id.erase(vertex_name);
	}
	// remove attribute values
	for (std::map<std::string,std::map<vertex_id,std::string> >::iterator it=vertex_string_attribute.begin(); it!=vertex_string_attribute.end(); it++)
		vertex_string_attribute[it->first].erase(vid);
	for (std::map<std::string,std::map<vertex_id,double> >::iterator it=vertex_numeric_attribute.begin(); it!=vertex_numeric_attribute.end(); it++)
		vertex_numeric_attribute[it->first].erase(vid);
	return true;
}
Example #2
0
File: HMesh.cpp Project: 3dcv/3dcv
void HMesh::deleteFace(Face* f, bool del)
{

    if(f->startEdge_->pair == NULL || f->startEdge_->pair->face == NULL)
    {
        deleteEdge(f->startEdge_);
    }

    if(f->startEdge_->next->pair == NULL || f->startEdge_->next->pair->face == NULL)
    {
        deleteEdge(f->startEdge_->next);
    }

    if(f->startEdge_->next->next->pair == NULL || f->startEdge_->next->next->pair->face == NULL)
    {
        deleteEdge(f->startEdge_->next->next);
    }

    if(del)
    {
        auto it = find(faces_.begin(), faces_.end(), f);
        if(it != faces_.end())
        {
            faces_.erase(it);
        }
    }
}
Example #3
0
int GraphState::normalizeSelf () {
    vector<pair<int, int> > removededges;
    selfdone = true;

    // temporarily change the situation to the original graph

    while ( deletededges.size () != 1 ) {
        removededges.push_back ( make_pair ( deletededges.back ().fromnode, deletededges.back ().posfromnode ) );
        reinsertEdge ();
    }

    for ( int i = closetuples->size () - 1; i >= 0; i-- )
        deleteEdge ( nodes[(*closetuples)[i].from-1].edges.back () );
    int b = normalizetree ();

    // then change the situation back

    for ( int i = closetuples->size () - 1; i >= 0; i-- )
        reinsertEdge ();

    while ( !removededges.empty () ) {
        deleteEdge ( nodes[removededges.back ().first].edges[removededges.back().second] );
        removededges.pop_back ();
    }


    return b;
}
Example #4
0
void GMap1::deleteCycle(Dart d)
{
	Dart e = phi1(d);
	while (e != d)
	{
		Dart f = phi1(e);
		deleteEdge(e);
		e = f;
	}
	deleteEdge(d);
}
Example #5
0
//void ConnectivityGraph::deleteEdge( VariableID vid, FactorID fid ) {
void ConnectivityGraph::deleteEdge( VertexID vxid1, VertexID vxid2 ) {

	assert( vxid1 != vxid2 );

//	std::cout << "deleting / decrementing edge (" << vid << ", " << fid << " / " << fxid << ")" << std::endl;

////#ifdef DEBUG
////	assert( existingEdges[e->vxid][e->fxid][fid] );
////	assert( existingEdges[e->fxid][e->vxid][fid] );
////	existingEdges[e->vxid][e->fxid].reset( fid );
////	existingEdges[e->fxid][e->vxid].reset( fid );
////#endif // DEBUG
//
//
//	if ( --e->count > 0 ) return;

	Vertex & u( vertices[vxid1] );
	Vertex & v( vertices[vxid2] );

	// find (and remove) the edge from the adjacency lists
//	EdgeIP ee = getFromAdjLists( u, v, e->level, e->isTree );
	EdgeIP ee = getFromAdjLists( u, v );

	if ( ee == NULL ) {
		std::cout << "Can't delete edge " <<
				Edge( /*vid, fid,*/ vxid1, vxid2, -1 ) << " (not found) -- " <<
				vxid1 << " / " << vxid2 << std::endl;
		assert( ee != NULL );
		return;
	}

	assert( ee->isequal( vxid1, vxid2 ) /*&& *e == *ee*/ );

	deleteEdge( ee );
}
Example #6
0
// returns true if lower found, otherwise false
int GraphState::enumerateSpanning () {
    if ( edgessize == (int) nodes.size () - 1 ) {
        // we have a tree
        if ( closecount == (int) closetuples->size () )
            // in this case we have already considered this tree as a separate tree
            return 0;
        return normalizetree ();
    }
    else {
        unsigned int bit = 1 << ( deletededges.size () - 1 );
        determineCycles ( bit );
        for ( int i = 0; i < (int) nodes.size (); i++ ) {
            vector<GSEdge>& edges = nodes[i].edges;
            for ( int j = 0; j < (int) edges.size (); j++ ) {
                if ( ( edges[j].cyclemark & bit ) &&
                        edges[j].tonode > i &&
                        ( i < deletededges.back ().fromnode ||
                          ( i == deletededges.back ().fromnode &&
                            edges[j].tonode < deletededges.back ().tonode ) ) ) {
                    deleteEdge ( edges[j] );
                    int b = enumerateSpanning ();
                    reinsertEdge ();
                    if ( b )
                        return b;
                }
            }
        }
    }
    return 0;
}
int main(void)
{
	int node_num, edge_num;
	double ans;
	struct Graph graph;

	while (scanf("%d %d", &node_num, &edge_num) != EOF) {
		initGraph(&graph, node_num);
		input(&graph, edge_num);

		printf("Boruvka:\n");
		ans = boruvka(&graph);
		printf("the MST weigths %2.1f\n", ans);
		clearChoosedEdge(&graph);

		printf("kruskal:\n");
		ans = kruskal(&graph);
		printf("the MST weights %.2lf\n", ans);
		clearChoosedEdge(&graph);

		printf("prim:\n");
		ans = prim(&graph);
		printf("the MST weights %.2lf\n", ans);
		deleteEdge(&graph);
	}

	return 0;
}
Example #8
0
void
NIXMLEdgesHandler::myStartElement(int element,
                                  const SUMOSAXAttributes& attrs) {
    switch (element) {
        case SUMO_TAG_EDGE:
            addEdge(attrs);
            break;
        case SUMO_TAG_LANE:
            addLane(attrs);
            break;
        case SUMO_TAG_NEIGH:
            myCurrentEdge->getLaneStruct((int)myCurrentEdge->getNumLanes() - 1).oppositeID = attrs.getString(SUMO_ATTR_LANE);
            break;
        case SUMO_TAG_SPLIT:
            addSplit(attrs);
            break;
        case SUMO_TAG_DELETE:
            deleteEdge(attrs);
            break;
        case SUMO_TAG_ROUNDABOUT:
            addRoundabout(attrs);
            break;
        default:
            break;
    }
}
Example #9
0
void
GNENet::deleteLane(GNELane* lane, GNEUndoList* undoList) {
    GNEEdge* edge = &lane->getParentEdge();
    if (edge->getNBEdge()->getNumLanes() == 1) {
        // remove the whole edge instead
        deleteEdge(edge, undoList);
    } else {
        undoList->p_begin("delete lane");
        const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
        const bool sidewalk = laneAttrs.permissions == SVC_PEDESTRIAN;
        undoList->add(new GNEChange_Lane(edge, lane, laneAttrs, false), true);
        if (gSelected.isSelected(GLO_LANE, lane->getGlID())) {
            std::set<GUIGlID> deselected;
            deselected.insert(lane->getGlID());
            undoList->add(new GNEChange_Selection(std::set<GUIGlID>(), deselected, true), true);
        }
        if (sidewalk) {
            edge->getSource()->removeFromCrossings(edge, undoList);
            edge->getDest()->removeFromCrossings(edge, undoList);
            edge->getSource()->setLogicValid(false, undoList);
            edge->getDest()->setLogicValid(false, undoList);
        }
        requireRecompute();
        undoList->p_end();
    }
}
Example #10
0
PolygonMesh<PointType>::~PolygonMesh(void)
	{
	/* Delete all faces and their associated half-edges: */
	Face* fPtr=faces;
	while(fPtr!=0)
		{
		/* Delete all the face's half-edges: */
		Edge* ePtr=fPtr->edge;
		do
			{
			Edge* next=ePtr->getFaceSucc();
			deleteEdge(ePtr);
			ePtr=next;
			}
		while(ePtr!=fPtr->edge);
		
		/* Delete the face: */
		Face* next=fPtr->succ;
		fPtr->~Face();
		faceAllocator.free(fPtr);
		
		fPtr=next;
		}
	
	/* Delete all vertices: */
	Vertex* vPtr=vertices;
	while(vPtr!=0)
		{
		Vertex* next=vPtr->succ;
		vPtr->~Vertex();
		vertexAllocator.free(vPtr);
		
		vPtr=next;
		}
	}
Example #11
0
int main(void)
{
	int node_num, edge_num, source;
	struct Graph graph;

	time = 0;
	source = 1;
	while (scanf("%d %d", &node_num, &edge_num) != EOF) {
		initGraph(&graph, node_num);
		input(&graph, edge_num);

		printf("source node of dfs and bfs is %d:\n", source);
		printf("depth first search:\n");
		for (source = 1; source <= graph.node_num; source++)
			dfs(&graph, source, visitNode);
		clearVisit(&graph);	

		printf("breadth first search:\n");
		for (source = 1; source <= graph.node_num; source++)
			bfs(&graph, source);
		clearVisit(&graph);

		printf("traverse by topological order:\n");
		topos(&graph);

		deleteEdge(&graph);
	}

	return 0;
}
void deleteEdge(Edge *thisEdge)
  {
  if (!(thisEdge == NULL))
    {
    deleteEdge(thisEdge->edge);
    free(thisEdge);
    }
  }
Example #13
0
void
GNENet::reverseEdge(GNEEdge* edge, GNEUndoList* undoList) {
    undoList->p_begin("reverse edge");
    deleteEdge(edge, undoList); // still exists. we delete it so we can reuse the name in case of resplit
    GNEEdge* reversed = createEdge(edge->getDest(), edge->getSource(), edge, undoList, edge->getID(), false, true);
    assert(reversed != 0);
    reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
    undoList->p_end();
}
Example #14
0
void deleteVidEdges(Graph* graph, int vId)
{
	 Node* head = graph->array[vId].head;
      while(head != NULL)
      {
         Node* deleteNode = head;
         head = head->next;
         deleteEdge(graph, vId, deleteNode->d); 
      }
}
Example #15
0
void ConnectivityGraph::disconnectVars( const VariablePtrVec & vars,
		const Factor * f ) {

	for ( auto vit = vars.rbegin(), vend = vars.rend(); vit != vend; ++vit ) {
		const Variable & v = **vit;
		if ( !v.isAssigned() ) {
			deleteEdge( vidToVertexID( v.getID() ),
					fidToVertexID( f->getID() ) );
		}
	}
}
Example #16
0
void
GNENet::replaceJunctionByGeometry(GNEJunction* junction, GNEUndoList* undoList) {
    undoList->p_begin("Replace junction by geometry");
    assert(junction->getNBNode()->checkIsRemovable());
    std::vector<std::pair<NBEdge*, NBEdge*> > toJoin = junction->getNBNode()->getEdgesToJoin();
    for (std::vector<std::pair<NBEdge*, NBEdge*> >::iterator j = toJoin.begin(); j != toJoin.end(); j++) {
        GNEEdge* begin = myEdges[(*j).first->getID()];
        GNEEdge* continuation = myEdges[(*j).second->getID()];
        deleteEdge(begin, undoList);
        deleteEdge(continuation, undoList);
        GNEEdge* newEdge = createEdge(begin->getSource(), continuation->getDest(), begin, undoList, begin->getMicrosimID(), false, true);
        PositionVector newShape = begin->getNBEdge()->getInnerGeometry();
        newShape.push_back(junction->getNBNode()->getPosition());
        newShape.append(continuation->getNBEdge()->getInnerGeometry());
        newEdge->setAttribute(SUMO_ATTR_SHAPE, toString(newShape), undoList);
        // @todo what about trafficlights at the end of oontinuation?
    }
    deleteJunction(junction, undoList);
    undoList->p_end();
}
Example #17
0
static void deleteNodeEdges(gctx_t *gctx, Agraph_t *g, Agnode_t *n)
{
    Agedge_t *e, *e1;

    e = agfstedge(g, n);
    while (e) {
	e1 = agnxtedge(g, e, n);
	deleteEdge(gctx, g, e);
	e = e1;
    }
}
main()
{
	int choice,u,origin,destin;
	
	while(1)
	{
		
		printf("1.Insert a Vertex\n");
		printf("2.Insert an Edge\n");
		printf("3.Delete a Vertex\n");
		printf("4.Delete an Edge\n");
		printf("5.Display\n");
		printf("6.Exit\n");
		printf("Enter your choice : ");
		scanf("%d",&choice);
		system("cls");
			
		switch(choice)
		{
		 case 1:
			printf("Enter a vertex to be inserted : ");
			scanf("%d",&u);
			insertVertex(u);
			break;
		 case 2:
			printf("Enter an Edge to be inserted : ");
			scanf("%d %d",&origin,&destin);
			insertEdge(origin,destin);
			break;
		 case 3:
			printf("Enter a vertex to be deleted : ");
			scanf("%d",&u);
			/*This function deletes all edges coming to this vertex*/
			deleteIncomingEdges(u);
			/*This function deletes the vertex from the vertex list*/
			deleteVertex(u);
			break;
		 case 4:
			printf("Enter an edge to be deleted : ");
			scanf("%d %d",&origin,&destin);
			deleteEdge(origin,destin);
			break;
		 case 5:
			display();
			break;
		 case 6:
			exit(1);
		 default:
			printf("Wrong choice\n");
			break;
		 }/*End of switch*/
	}/*End of while*/
}/*End of main()*/
Example #19
0
GNEJunction*
GNENet::splitEdge(GNEEdge* edge, const Position& pos, GNEUndoList* undoList, GNEJunction* newJunction) {
    undoList->p_begin("split edge");
    deleteEdge(edge, undoList); // still exists. we delete it so we can reuse the name in case of resplit
    // compute geometry
    const PositionVector& oldGeom = edge->getNBEdge()->getGeometry();
    const SUMOReal linePos = oldGeom.nearest_offset_to_point2D(pos, false);
    std::pair<PositionVector, PositionVector> newGeoms = oldGeom.splitAt(linePos);
    // figure out the new name
    int posBase = 0;
    std::string baseName = edge->getMicrosimID();
    if (edge->wasSplit()) {
        size_t sep_index = baseName.rfind('.');
        if (sep_index != std::string::npos) { // edge may have been renamed in between
            std::string posString = baseName.substr(sep_index + 1);
            try {
                posBase = TplConvert::_2int(posString.c_str());
                baseName = baseName.substr(0, sep_index); // includes the .
            } catch (NumberFormatException) {
            }
        }
    }
    baseName += '.';
    // create edges
    if (newJunction == 0) {
        newJunction = createJunction(pos, undoList);
    }
    GNEEdge* firstPart = createEdge(edge->getSource(), newJunction, edge,
                                    undoList, baseName + toString(posBase), true);
    GNEEdge* secondPart = createEdge(newJunction, edge->getDest(), edge,
                                     undoList, baseName + toString(posBase + (int)linePos), true);
    // fix geometry
    firstPart->setAttribute(GNE_ATTR_SHAPE_START, toString(newGeoms.first[0]), undoList);
    firstPart->setAttribute(GNE_ATTR_SHAPE_END, toString(newGeoms.first[-1]), undoList);
    newGeoms.first.pop_back();
    newGeoms.first.erase(newGeoms.first.begin());
    firstPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.first), undoList);

    secondPart->setAttribute(GNE_ATTR_SHAPE_START, toString(newGeoms.second[0]), undoList);
    secondPart->setAttribute(GNE_ATTR_SHAPE_END, toString(newGeoms.second[-1]), undoList);
    newGeoms.second.pop_back();
    newGeoms.second.erase(newGeoms.second.begin());
    secondPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.second), undoList);
    // fix connections
    std::vector<NBEdge::Connection>& connections = edge->getNBEdge()->getConnections();
    for (std::vector<NBEdge::Connection>::iterator con_it = connections.begin(); con_it != connections.end(); con_it++) {
        undoList->add(new GNEChange_Connection(
                          secondPart, con_it->fromLane, con_it->toEdge->getID(), con_it->toLane, false, true), true);
    }
    undoList->p_end();
    return newJunction;
}
Example #20
0
bool Graph::deleteNode(int index){
	Node *node = nodeList[index];
	map<Node*, float>::iterator it;
	for(it = node->neighbors.begin();it!=node->neighbors.end();it++){
		// delete the edge, which direct to this node
		if(!deleteEdge(it->first, node)){
			return false;
		}
	}
	nodeList.erase(nodeList.begin() + index);
	delete node;
	return true;
}
Example #21
0
void
GNENet::remapEdge(GNEEdge* oldEdge, GNEJunction* from, GNEJunction* to, GNEUndoList* undoList, bool keepEndpoints) {
    deleteEdge(oldEdge, undoList); // delete first so we can reuse the name, reference stays valid
    if (from != to) {
        GNEEdge* newEdge = createEdge(from, to, oldEdge, undoList, oldEdge->getMicrosimID(), false, true);
        newEdge->setAttribute(SUMO_ATTR_SHAPE, oldEdge->getAttribute(SUMO_ATTR_SHAPE), undoList);
        if (keepEndpoints) {
            newEdge->setAttribute(GNE_ATTR_SHAPE_START, oldEdge->getAttribute(GNE_ATTR_SHAPE_START), undoList);
            newEdge->setAttribute(GNE_ATTR_SHAPE_END, oldEdge->getAttribute(GNE_ATTR_SHAPE_END), undoList);
        }
    }
    // @todo remap connectivity as well
}
//do cleanup correctly in case code integrated later so no memory leaks.
void deleteGraph(Node *nodes)
  {
  for (int x = 0; x < nx; x++)
    {
    for (int y = 0; y < ny; y++)
      {
      for (int z = 0; z < nz; z++)
        {
        int index = calcIndexN(x,y,z);
        Edge *tempEdge = nodes[index].edge;
        deleteEdge(tempEdge);   
        }
      }
    }  
  free(nodes);
  }
Example #23
0
Vertex* Voronoi::InsertPoint(const Vec2& p)
{
	QuadEdge* e = LocateTriangleEdge(p);
	if (e == nullptr ||
		p == e->Org()->p || p == e->Dest()->p)
		return nullptr;
	else if (VoronoiMath::Collinear(e, p))
	{
		e = e->Oprev();
		QuadEdge* et = e->Onext();
		QuadEdge::Disconnect(et);
		deleteEdge(et->RootEdge());
	}
	Vertex* v = createVertex(p);
	v->e = e;
	
	QuadEdge* e_begin = createEdge();
	e_begin->SetEndPoints(e->Org(), v);
	QuadEdge* et = e_begin;
	QuadEdge::Splice(e_begin, e);
	do
	{
		QuadEdge* et2 = createEdge();
		QuadEdge::Connect(et2, e, et->Sym());
		et = et2;
		e = et->Oprev();
	} while (e->Lnext() != e_begin);

	do
	{
		et = e->Oprev();
		if (VoronoiMath::OnRight(e, et->Dest()->p) &&
			VoronoiMath::InCircle(e->Org()->p, et->Dest()->p, e->Dest()->p, p))
		{
			QuadEdge::Flip(e);
			e = e->Oprev();
		}
		else if (e->Onext() == e_begin)
			break;
		else
			e = e->Onext()->Lprev();
	} while (true);

	return v;
}
void
NIXMLEdgesHandler::myStartElement(int element,
                                  const SUMOSAXAttributes& attrs) {
    switch (element) {
        case SUMO_TAG_EDGE:
            addEdge(attrs);
            break;
        case SUMO_TAG_LANE:
            addLane(attrs);
            break;
        case SUMO_TAG_SPLIT:
            addSplit(attrs);
            break;
        case SUMO_TAG_DELETE:
            deleteEdge(attrs);
            break;
        default:
            break;
    }
}
Example #25
0
void
GNENet::deleteJunction(GNEJunction* junction, GNEUndoList* undoList) {
    // we have to delete all incident edges because they cannot exist without that junction
    // all deletions must be undone/redone together so we start a new command group
    // @todo if any of those edges are dead-ends should we remove their orphan junctions as well?
    undoList->p_begin("delete junction");

    // deleting edges changes in the underlying EdgeVector so we have to make a copy
    const EdgeVector incident = junction->getNBNode()->getEdges();
    for (EdgeVector::const_iterator it = incident.begin(); it != incident.end(); it++) {
        deleteEdge(myEdges[(*it)->getID()], undoList);
    }

    // remove any traffic lights from the traffic light container (avoids lots of warnings)
    junction->setAttribute(SUMO_ATTR_TYPE, toString(NODETYPE_PRIORITY), undoList);
    undoList->add(new GNEChange_Junction(this, junction, false), true);
    if (gSelected.isSelected(GLO_JUNCTION, junction->getGlID())) {
        std::set<GUIGlID> deselected;
        deselected.insert(junction->getGlID());
        undoList->add(new GNEChange_Selection(std::set<GUIGlID>(), deselected, true), true);
    }
    undoList->p_end();
}
Example #26
0
void ConnectivityGraph::onVariableAssigned( const Variable * v ) {
	// for each factor f that v is in and is not assigned
	// 		deleteEdge( v, f )

//	std::cout << "var " << v->getID() << " assigned (CG)" << std::endl;

#ifdef DEBUG
	assert( !assignedVars[v->getID()] );
	assignedVars.set( v->getID() );
#endif // DEBUG

	// note: we do assign/unassign in reverse order of each other, so we don't
	// get an inefficient chaining of edge replacements when all we really want
	// is a disconnect

	for ( auto fit = v->getFactors().begin(), fend = v->getFactors().end();
			fit != fend; ++fit ) {
		const Factor * f = *fit;
		if ( f->isAssigned() ) continue;
		if ( !f->containsVar( v->getID() ) ) continue;
//		std::cout << "delete edge v " << v->getID() << " to f " << f->getID() << std::endl;
		deleteEdge( vidToVertexID( v->getID() ), fidToVertexID( f->getID() ) );
	}
}
Example #27
0
void
GNENet::deleteGeometryOrEdge(GNEEdge* edge, const Position& pos, GNEUndoList* undoList) {
    if (!edge->deleteGeometry(pos, undoList)) {
        deleteEdge(edge, undoList);
    }
}
Example #28
0
bool Network::deleteEdge(const std::string& vertex_name1, const std::string& vertex_name2) {
	if (!isNamed()) throw OperationNotSupportedException("Cannot reference a named vertex in an unnamed network");
	if (!containsEdge(vertex_name1,vertex_name2)) return false;
	return deleteEdge(vertex_name_to_id.at(vertex_name1), vertex_name_to_id.at(vertex_name2));
}
Example #29
0
File: HMesh.cpp Project: 3dcv/3dcv
void HMesh::collapseEdge(Edge* edgy)
{
    Vertex* v1 = edgy->start;
    Vertex* v2 = edgy->end;

    if(v1 == v2) return;
    *v1 = (*v1 + *v2) * 0.5;
    edgy->start = v1;
    if (edgy->face)
    {   
		 if(edgy->next->next->pair != NULL)
		 {
			edgy->next->next->pair->pair = edgy->next->pair;
			if(edgy->next->pair != NULL)
			{
				edgy->next->pair->pair = edgy->next->next->pair;

				Edge* e1 = edgy->next->next;

				Edge* e2 = edgy->next;

				//delete old edges
				deleteEdge(e1, false);    
				deleteEdge(e2, false);
			}
		}
    }
    
    if(edgy->pair != NULL)
    {
		if (edgy->pair->face)
		{
			if(edgy->pair->next->next->pair != NULL)
			{	
				edgy->pair->next->next->pair->pair = edgy->pair->next->pair;
				if(edgy->pair->next->pair != NULL)
				{
					edgy->pair->next->pair->pair = edgy->pair->next->next->pair;
					//delete old edges
				
					Edge* e1 = edgy->pair->next->next;
					Edge* e2 = edgy->pair->next;

					deleteEdge(e1, false);    
					deleteEdge(e2, false);
				}
			}
		}

		// Now really delete faces
		if(edgy->pair->face)
		{
			deleteFace(edgy->pair->face);
			edgy->pair = 0;
		}
	}
	
	if(edgy->face)
	{
		deleteFace(edgy->face);
		edgy->face = 0;
	}

    deleteEdge(edgy);

    auto it =v2->out_edges.begin();

    while(it !=v2->out_edges.end())
    {
        (*it)->start = v1;
        v1->out_edges.push_back(*it);
        it++;
    }

    auto it2 = v2->in_edges.begin();
    while(it2 != v2->in_edges.end())
    {
        (*it2)->end = v1;
        v1->in_edges.push_back(*it2);
        it2++;
    }
    //v2->out_edges.clear();
    //v2->in_edges.clear();
    
}
Example #30
0
   VertexIter HalfedgeMesh::collapseEdge( EdgeIter e )
   {
      // TODO This method should collapse the given edge and return an iterator to the new vertex created by the collapse.
		 
		 //1. collect elements
		 EdgeIter e4 = e;

		 //Halfedges
		 HalfedgeIter h1 = e4->halfedge();
		 HalfedgeIter h5 = h1->twin();
		 
		 //Faces
		 FaceIter f0 = h1->face();
		 FaceIter f1 = h5->face();
		 
		 //Early Exit #1: Ignore requests to collapse boundary edges
		 if(f0->isBoundary() || f1->isBoundary())
			 return verticesEnd();
		 
		 //Halfedges, cont'
		 HalfedgeIter h2 = h1->next();
		 HalfedgeIter h0 = h2->next();
		 HalfedgeIter h3 = h5->next();
		 HalfedgeIter h4 = h3->next();
		 
		 HalfedgeIter h7 = h0->twin();
		 HalfedgeIter h12 = h3->twin();
		 
		 HalfedgeIter h20 = h2->twin();
		 HalfedgeIter h15 = h4->twin();
		 
		 //Edges
		 EdgeIter e0 = h0->edge();
		 EdgeIter e1 = h3->edge();
		 EdgeIter e2 = h4->edge();
		 EdgeIter e3 = h2->edge();
			//EdgeIter e4
		 
		 //Faces
		 
		 //Vertices
		 VertexIter v0 = h0->vertex();
		 VertexIter v1 = h3->vertex();
		 VertexIter v2 = h4->vertex();
		 VertexIter v3 = h2->vertex();
		 
		 //Early Exit #2: The number of the joint neighbor vertices of the two merging vertices
		 //must be EXACTLY TWO
		 std::vector<VertexIter> v1_neighbors;
		 std::vector<VertexIter> v3_neighbors;
		 HalfedgeIter h = h3;
		 do
		 {
			 h = h->twin();
			 if(h->vertex() != v1)
				 v1_neighbors.push_back(h->vertex());
			 h = h->next();
		 }
		 while(h != h3);
		 h = h2;
		 do
		 {
			 h = h->twin();
			 if(h->vertex() != v3)
				 v3_neighbors.push_back(h->vertex());
			 h = h->next();
		 }
		 while(h != h2);
		 std::sort(v1_neighbors.begin(), v1_neighbors.end());
		 std::sort(v3_neighbors.begin(), v3_neighbors.end());
		 std::vector<VertexIter> joint_neighbors;
		 std::set_intersection(v1_neighbors.begin(), v1_neighbors.end(),
													 v3_neighbors.begin(), v3_neighbors.end(),
													 std::back_inserter(joint_neighbors));
		 if(joint_neighbors.size() != 2)
			 return verticesEnd();
		 
		 //Early Exit #3: mesh must have more than 4 vertices if neither v1 nor v3 is boundary vertex,
		 //and more than 3 vertices if either v1 or v3 is boundary vertex
		 if(!v1->isBoundary() && !v3->isBoundary() && nVertices() <= 4)
			 return verticesEnd();
		 if((v1->isBoundary() || v3->isBoundary()) && nVertices() <= 3)
			 return verticesEnd();
		 
		 //Early Exit #4: v1, v3 cannot be both boundary vertex
		 if(v1->isBoundary() && v3->isBoundary())
			 return verticesEnd();
		 
		 //Early Exit #5: boundary vertex needs at least one triangle
		 //By convention, Vertex::degree() returns the face degree
		 if(v0->isBoundary() && v0->degree() <= 1)
			 return verticesEnd();
		 if(v1->isBoundary() && v1->degree() <= 1)
			 return verticesEnd();
		 if(v2->isBoundary() && v2->degree() <= 1)
			 return verticesEnd();
		 if(v3->isBoundary() && v3->degree() <= 1)
			 return verticesEnd();
		
		 //Early Exit #6: degenerated case: v0/v1/v2/v3 are duplicated
		 if(v0 == v1 || v0 == v2 || v0 == v3 || v1 == v2 || v1 == v3 || v2 == v3)
			 return verticesEnd();
		 

		 
		 VertexIter output = verticesEnd();
		 if(v3->isBoundary())
		 {
			 std::vector<HalfedgeIter> v1_out;
			 HalfedgeIter h = v1->halfedge();
			 do
			 {
				 v1_out.push_back(h);
				 h = h->next()->next()->twin();
			 }
			 while(h != v1->halfedge());
			 
			 //2. reassign elements
			 
			 //Halfedges
			 h7->twin() = h20; h7->edge() = e3;
			 h20->twin() = h7;
			 h12->twin() = h15; h12->edge() = e2;
			 h15->twin() = h12;
			 
			 for(auto h = v1_out.begin(); h!= v1_out.end(); ++h)
				 (*h)->vertex() = v3;
			 
			 //Vertices
			 v0->halfedge() = h20;
			 v3->halfedge() = h15;
			 v3->position = 0.5f * (v1->position + v3->position);
			 v2->halfedge() = h12;
			 
			 //Edges
			 e3->halfedge() = h20;
			 e2->halfedge() = h15;
			 
			 //Faces
			 
			 //3. delete elements
			 //Halfedges
			 deleteHalfedge(h0);
			 deleteHalfedge(h1);
			 deleteHalfedge(h2);
			 deleteHalfedge(h3);
			 deleteHalfedge(h4);
			 deleteHalfedge(h5);
			 
			 //Vertices
			 deleteVertex(v1);
			 
			 //Edges
			 deleteEdge(e0);
			 deleteEdge(e1);
			 deleteEdge(e4);
			 
			 //Faces
			 deleteFace(f0);
			 deleteFace(f1);
			 
			 output = v3;
		 }
		 else
		 {
			 std::vector<HalfedgeIter> v3_out;
			 HalfedgeIter h = v3->halfedge();
			 do
			 {
				 v3_out.push_back(h);
				 h = h->next()->next()->twin();
			 }
			 while(h != v3->halfedge());
			 
			 //2. reassign elements
			 
			 //Halfedges
			 h7->twin() = h20;
			 h20->twin() = h7; h20->edge() = e0;
			 h12->twin() = h15;
			 h15->twin() = h12; h15->edge() = e1;
			 
			 for(auto h = v3_out.begin(); h!= v3_out.end(); ++h)
				 (*h)->vertex() = v1;
			 
			 //Vertices
			 v0->halfedge() = h20;
			 v1->halfedge() = h15;
			 v1->position = 0.5f * (v1->position + v3->position);
			 v2->halfedge() = h12;
			 
			 //Edges
			 e0->halfedge() = h20;
			 e1->halfedge() = h15;
			 
			 //Faces
			 
			 //3. delete elements
			 //Halfedges
			 deleteHalfedge(h0);
			 deleteHalfedge(h1);
			 deleteHalfedge(h2);
			 deleteHalfedge(h3);
			 deleteHalfedge(h4);
			 deleteHalfedge(h5);
			 
			 //Vertices
			 deleteVertex(v3);
			 
			 //Edges
			 deleteEdge(e2);
			 deleteEdge(e3);
			 deleteEdge(e4);
			 
			 //Faces
			 deleteFace(f0);
			 deleteFace(f1);
			 
			 output = v1;
		 }
		 
		 return output;
   }