예제 #1
0
파일: Graph.cpp 프로젝트: MIPT-ILab/ICDV
void Graph::DeleteNode(pNode p)
{
	while(!p->m_in_edges_list.empty()) {
		DeleteEdge(p->m_in_edges_list.front()->m_from,p);
	}
	while(!p->m_out_edges_list.empty()) {
		DeleteEdge(p,p->m_out_edges_list.front()->m_to);
	}
	m_nodes_list.remove(p);
	m_total_nodes_num--;
	FreeNode(p);
}
void pvdb::ConceptMap::DeleteNode(const boost::shared_ptr<pvdb::Node> node)
{
  #ifndef NDEBUG
  assert(node);
  assert(std::count(m_nodes.begin(),m_nodes.end(),node) == 1
    && "Every node is unique");
  const std::size_t n_nodes_before = m_nodes.size();
  #endif

  //Delete all edges going to this node
  std::vector<boost::shared_ptr<pvdb::Edge> > to_be_deleted;
  std::copy_if(m_edges.begin(),m_edges.end(),std::back_inserter(to_be_deleted),
    [node](boost::shared_ptr<pvdb::Edge> edge)
    {
      return edge->GetFrom() == node || edge->GetTo() == node;
    }
  );
  for (boost::shared_ptr<pvdb::Edge> edge: to_be_deleted)
  {
    DeleteEdge(edge);
  }

  //Delete the node itself
  //Copied from http://www.richelbilderbeek.nl/CppVector.htm
  m_nodes.erase(std::remove(m_nodes.begin(),m_nodes.end(),node),m_nodes.end());

  #ifndef NDEBUG
  const std::size_t n_nodes_after = m_nodes.size();
  assert(n_nodes_before - 1 == n_nodes_after);
  #endif
}
예제 #3
0
void ribi::cmap::QtConceptMap::DeleteNode(QtNode * const qtnode)
{
  #ifndef NDEBUG
  const int n_items_before = this->scene()->items().count();
  #endif

  //Delete the edges connected to this node
  {
    const std::vector<QtEdge *> qtedges = GetQtEdges();
    const std::size_t sz = qtedges.size();
    for (std::size_t i=0; i!=sz; ++i)
    {
      QtEdge * const qtedge = qtedges[i];
      assert(qtedge);
      if (qtedge->GetFrom() == qtnode || qtedge->GetTo() == qtnode)
      {
        DeleteEdge(qtedge);
      }
    }
  }

  //Remove from non-GUI, which removes the left-overs
  GetConceptMap()->DeleteNode(qtnode->GetNode());
  //Remove node from GUI
  this->scene()->removeItem(qtnode);

  #ifndef NDEBUG
  const int n_items_after = this->scene()->items().count();
  assert(n_items_before - n_items_after >= 1 && "At least one item is deleted: one node and x edges");
  assert(Collect<QtNode>(this->scene()).size() == this->GetConceptMap()->GetNodes().size()
    && "GUI and non-GUI concept map must match");
  #endif
}
예제 #4
0
    bool Graph::EdgeCollapse(long v1, long v2)
	{
		long edgeToDelete = GetEdgeID(v1, v2);
        if (edgeToDelete >= 0) 
		{
			// delete the edge (v1, v2)
			DeleteEdge(edgeToDelete);
			// add v2 to v1 ancestors
            m_vertices[v1].m_ancestors.push_back(v2);
			// add v2's ancestors to v1's ancestors
			m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(),
											  m_vertices[v2].m_ancestors.begin(), 
											  m_vertices[v2].m_ancestors.end());
			// update adjacency information
			SArray<long, SARRAY_DEFAULT_MIN_SIZE> & v1Edges =  m_vertices[v1].m_edges;
			long b = -1;
            long idEdge;
			for(size_t ed = 0; ed < m_vertices[v2].m_edges.Size(); ++ed) 
			{
                idEdge = m_vertices[v2].m_edges[ed];
				if (m_edges[idEdge].m_v1 == v2)
				{
					b = m_edges[idEdge].m_v2;
				}
				else
				{
					b = m_edges[idEdge].m_v1;
				}
				if (GetEdgeID(v1, b) >= 0)
				{
					m_edges[idEdge].m_deleted = true;
					m_vertices[b].DeleteEdge(idEdge);
					m_nE--;
				}
				else
				{
					m_edges[idEdge].m_v1 = v1;
					m_edges[idEdge].m_v2 = b;
					v1Edges.Insert(idEdge);
				}
			}
			// delete the vertex v2
            DeleteVertex(v2);			
            return true;
        }
		return false;
    }
예제 #5
0
    bool Graph::EdgeCollapse(long v1, long v2)
	{
		long edgeToDelete = GetEdgeID(v1, v2);
        if (edgeToDelete >= 0) 
		{
			// delete the edge (v1, v2)
			DeleteEdge(edgeToDelete);
			// add v2 to v1 ancestors
            m_vertices[v1].m_ancestors.push_back(v2);
			// add v2's ancestors to v1's ancestors
			m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(),
											  m_vertices[v2].m_ancestors.begin(), 
											  m_vertices[v2].m_ancestors.end());
			// update adjacency information
			std::set<long> & v1Edges =  m_vertices[v1].m_edges;
			std::set<long>::const_iterator ed(m_vertices[v2].m_edges.begin());
			std::set<long>::const_iterator itEnd(m_vertices[v2].m_edges.end());
			long b = -1;
			for(; ed != itEnd; ++ed) 
			{
				if (m_edges[*ed].m_v1 == v2)
				{
					b = m_edges[*ed].m_v2;
				}
				else
				{
					b = m_edges[*ed].m_v1;
				}
				if (GetEdgeID(v1, b) >= 0)
				{
					m_edges[*ed].m_deleted = true;
					m_vertices[b].DeleteEdge(*ed);
					m_nE--;
				}
				else
				{
					m_edges[*ed].m_v1 = v1;
					m_edges[*ed].m_v2 = b;
					v1Edges.insert(*ed);
				}
			}
			// delete the vertex v2
            DeleteVertex(v2);			
            return true;
        }
		return false;
    }
예제 #6
0
void Subdivision::InsertSite(const Point2d& x)
// Inserts a new point into a subdivision representing a Delaunay
// triangulation, and fixes the affected edges so that the result
// is still a Delaunay triangulation. This is based on the
// pseudocode from Guibas and Stolfi (1985) p.120, with slight
// modifications and a bug fix.
{
	Edge* e = Locate(x);
	if ((x == e->Org2d()) || (x == e->Dest2d()))  // point is already in
	    return;
	else if (OnEdge(x, e)) {
		e = e->Oprev();
		DeleteEdge(e->Onext());
	}

	// Connect the new point to the vertices of the containing
	// triangle (or quadrilateral, if the new point fell on an
	// existing edge.)
	Edge* base = MakeEdge();
	base->EndPoints(e->Org(), new Point2d(x));
	Splice(base, e);
	startingEdge = base;
	do {
		base = Connect(e, base->Sym());
		e = base->Oprev();
	} while (e->Lnext() != startingEdge);

	// Examine suspect edges to ensure that the Delaunay condition
	// is satisfied.
	do {
		Edge* t = e->Oprev();
		if (RightOf(t->Dest2d(), e) &&
			InCircle(e->Org2d(), t->Dest2d(), e->Dest2d(), x)) {
				Swap(e);
				e = e->Oprev();
		}
		else if (e->Onext() == startingEdge)  // no more suspect edges
			return;
		else  // pop a suspect edge
		    e = e->Onext()->Lprev();
	} while (TRUE);
}
예제 #7
0
파일: TopoAlgs.cpp 프로젝트: beauby/pigale
int TopologicalGraph::Simplify()
// returns the # o multiple edges + #  loops
  {if(Set().exist(PROP_SIMPLE))return 0;
  if(debug())DebugPrintf("  Executing Simplify");
  // Remove Loops
  int n = RemoveLoops();
  if(!ne()){Prop1<int> simple(Set(),PROP_SIMPLE);return n;}
  
  svector<tedge>link(0,ne()); link.clear(); link.SetName("TG:Simplify:link");
  svector<tedge>top1(1,nv()); top1.clear(); top1.SetName("TG:Simplify:top1");
  svector<tedge>top2(1,nv()); top2.clear(); top2.SetName("TG:Simplify:top2");
  tvertex u,v,w;
  tedge e,e0,next;
  //First sort with respect to biggest label
  for(e = ne();e >= 1;e--)
      {v = (vin[e] < vin[-e]) ? vin[-e] : vin[e];
      link[e] = top1[v];top1[v] = e;
      }
  // Then sort with respect to smallest label
  for(u = nv();u > 1;u--)
      {e = top1[u];
      while(e!=0)
          {next = link[e];     //as link is modified
          v = (vin[e] < vin[-e]) ? vin[e] : vin[-e];
          link[e] = top2[v]; top2[v] = e;
          e = next;
          }
      }
  // Erase Multiple edges, but backup multiplicity
  Prop<int> multiplicity(Set(tedge()),PROP_MULTIPLICITY);
  for (e=1; e<=ne(); ++e) multiplicity[e]=1;

  for(v = nv()-1;v >= 1;v--)
      {e0 = top2[v];
      u = vin[e0];if(u == v)u = vin[-e0];
      e=link[e0];
      link[e0]=0;
      while(e!=0)
          {next=link[e];
	  w = vin[e];if(w == v)w = vin[-e];
          if(u == w)
	    {++n; 
	    ++multiplicity[e0]; 
	    link[e] = 1;
	    }
          else
	    {u=w;
	    link[e0=e] = 0;
	    }
	  e=next;
          }
      }

  bool erased = false;
  for(e = ne();e >= 1;e--)
      if(link[e]!=0){DeleteEdge(e);erased = true;}

  if(!erased)Set(tedge()).erase(PROP_MULTIPLICITY);
  Prop1<int> simple(Set(),PROP_SIMPLE);  
  return n;
  }
예제 #8
0
SSHANDLE * CSSolid::MergeSameVertices(int& nDeleted)
{
	int nMerged = 0;
	nDeleted = 0;
	static SSHANDLE hDeletedList[128];

DoVertices:
	for(int v1 = 0; v1 < m_nVertices; v1++)
	{
		for(int v2 = 0; v2 < m_nVertices; v2++)
		{
			if(v1 == v2)
				continue;	// no!
			if(!VectorCompare(m_Vertices[v1].pos, m_Vertices[v2].pos))
			{	// no match
				continue;
			}

			++nMerged;

			// same vertices - kill v1, set edge refs to use v2.
			SSHANDLE hV1 = m_Vertices[v1].id;
			SSHANDLE hV2 = m_Vertices[v2].id;
			
			hDeletedList[nDeleted++] = hV1;
			
			DeleteVertex(v1);

			int nAffected;
			CSSEdge **ppEdges = FindAffectedEdges(&hV1, 1, nAffected);

			// run through edges and change references
			for(int e = 0; e < nAffected; e++)
			{
				if(ppEdges[e]->hvStart == hV1)
					ppEdges[e]->hvStart = hV2;
				if(ppEdges[e]->hvEnd == hV1)
					ppEdges[e]->hvEnd = hV2;
				CalcEdgeCenter(ppEdges[e]);
			}
			
			goto DoVertices;
		}
	}

	if(!nMerged)
		return NULL;

	int e;

	// kill edges that have same vertices
	for(e = 0; e < m_nEdges; e++)
	{
		CSSEdge &edge = m_Edges[e];

		if(edge.hvStart != edge.hvEnd)
			continue;	// edge is OK

		hDeletedList[nDeleted++] = edge.id;

		DeleteEdge(e);
		--e;
	}

	// kill similar edges (replace in faces too)
DoEdges:
	for(e = 0; e < m_nEdges; e++)
	{
		CSSEdge &edge = m_Edges[e];

		for(int e2 = 0; e2 < m_nEdges; e2++)
		{
			if(e == e2)
				continue;

			CSSEdge &edge2 = m_Edges[e2];

			if(!((edge2.hvStart == edge.hvStart && edge2.hvEnd == edge.hvEnd) || 
				(edge2.hvEnd == edge.hvStart && edge2.hvStart == edge.hvEnd)))
				continue;

			// we're going to delete edge2.
			SSHANDLE id2 = edge2.id;
			SSHANDLE id1 = edge.id;

			for(int f = 0; f < m_nFaces; f++)
			{
				CSSFace& face = m_Faces[f];
				for(int ef = 0; ef < face.nEdges; ef++)
				{
					if(face.Edges[ef] == id2)
					{
						face.Edges[ef] = id1;
						break;
					}
				}
			}

			hDeletedList[nDeleted++] = id2;
			DeleteEdge(e2);

			goto DoEdges;
		}
	}

	// delete concurrent edge references in face
	for(int f = 0; f < m_nFaces; f++)
	{
		CSSFace& face = m_Faces[f];

DoConcurrentEdges:
		for(int ef1 = 0; ef1 < face.nEdges; ef1++)
		{
			for(int ef2 = 0; ef2 < face.nEdges; ef2++)
			{
				if(ef2 == ef1)
					continue;

				if(face.Edges[ef1] != face.Edges[ef2])
					continue;
			
				// delete this ref
				memcpy(&face.Edges[ef2], &face.Edges[ef2+1], (face.nEdges-ef2) * 
					sizeof(face.Edges[0]));
				--face.nEdges;

				goto DoConcurrentEdges;
			}
		}

		if(face.nEdges < 3)
		{
			// kill this face
			hDeletedList[nDeleted++] = face.id;
			DeleteFace(f);
			--f;
		}
	}

	return hDeletedList;
}
예제 #9
0
BOOL CSSolid::SplitFaceByEdges(CSSEdge *pEdge1, CSSEdge *pEdge2)
{
	SSHANDLE hFace;

	// find the handle of the face
	if(pEdge1->Faces[0] == pEdge2->Faces[0] || 
		pEdge1->Faces[0] == pEdge2->Faces[1])
	{
		hFace = pEdge1->Faces[0];
	}
	else if(pEdge1->Faces[1] == pEdge2->Faces[0] || 
		pEdge1->Faces[1] == pEdge2->Faces[1])
	{
		hFace = pEdge1->Faces[1];
	}
	else return FALSE;	// not the same face

	// get pointer to face
	CSSFace *pFace = (CSSFace*) GetHandleData(hFace);

	// create new objects
	CSSFace *pNewFace = AddFace();
	CSSEdge *pNewEdgeMid = AddEdge();
	int iNewVertex1, iNewVertex2;
	CSSVertex *pNewVertex1 = AddVertex(&iNewVertex1);
	CSSVertex *pNewVertex2 = AddVertex(&iNewVertex2);

	// assign faces to new edge
	AssignFace(pNewEdgeMid, pFace->id);
	AssignFace(pNewEdgeMid, pNewFace->id);

	// copy texture info from one face to the other
	memcpy(&pNewFace->texture, &pFace->texture, sizeof(TEXTURE));

	// set vertex positions
	m_Vertices[iNewVertex1].pos = pEdge1->ptCenter;
	m_Vertices[iNewVertex2].pos = pEdge2->ptCenter;

	// set up middle edge
	pNewEdgeMid->hvStart = pNewVertex1->id;
	pNewEdgeMid->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pNewEdgeMid);

	// set up new side edges
	CSSEdge *pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge1->hvStart;
	pEdgeTmp->hvEnd = pNewVertex1->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge1->hvEnd;
	pEdgeTmp->hvEnd = pNewVertex1->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge2->hvStart;
	pEdgeTmp->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge2->hvEnd;
	pEdgeTmp->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pEdgeTmp);

/*
	FILE *fp = fopen("split", "w");
	for(i = 0; i < nVertices; i++)
	{
		fprintf(fp, "%lu\n", phVertexList[i]);
	}
	fclose(fp);
*/

	// set up edges - start with newvertex1 
	SSHANDLE hNewEdges[64];
	int nNewEdges;
	BOOL bFirst = TRUE;
	CSSFace *pStoreFace = pFace;

	// ** do two new faces first **

	int nv1index, nv2index;
	SSHANDLE *phVertexList = CreateNewVertexList(pFace, pEdge1, pEdge2, 
		nv1index, nv2index, pNewVertex1, pNewVertex2);
	int nVertices = pFace->nEdges;
	if(nv1index != -1)
		++nVertices;
	if(nv2index != -1)
		++nVertices;

	// kill face references in edges first
	for(int i = 0; i < nVertices; i++)
	{
		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], 
			phVertexList[iNextVertex]);
		CSSEdge *pEdge = &m_Edges[iEdgeIndex];
		ASSERT(pEdge->id != pEdge1->id);
		ASSERT(pEdge->id != pEdge2->id);
		AssignFace(pEdge, pFace->id, TRUE);
	}

DoNextFace:
	nNewEdges = 0;
	for(i = nv1index; ; i++)
	{
		if(i == nVertices)
			i = 0;

		if(i == nv2index)
			break;

		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
		ASSERT(iEdgeIndex != -1);

		hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;

		AssignFace(&m_Edges[iEdgeIndex], pStoreFace->id);
	}
	// now add the middle edge
	hNewEdges[nNewEdges++] = pNewEdgeMid->id;
	// now set up in face
	pStoreFace->nEdges = nNewEdges;
	memcpy(pStoreFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

	if(bFirst)
	{
		int tmp = nv1index;
		nv1index = nv2index;
		nv2index = tmp;
		pStoreFace = pNewFace;
		bFirst = FALSE;
		goto DoNextFace;
	}

	delete phVertexList;

	// ** now regular faces **
	for(int iFace = 0; iFace < m_nFaces; iFace++)
	{
		CSSFace *pUpdFace = &m_Faces[iFace];

		if(pUpdFace == pNewFace || pUpdFace == pFace)
			continue;
		
		SSHANDLE *phVertexList = CreateNewVertexList(pUpdFace, pEdge1, pEdge2,
			nv1index, nv2index, pNewVertex1, pNewVertex2);

		if(phVertexList == NULL)	// don't need to update this face
			continue;
	
		nNewEdges = 0;
		nVertices = pUpdFace->nEdges;
		if(nv1index != -1)
			++nVertices;
		if(nv2index != -1)
			++nVertices;
		for(i = 0; i < nVertices; i++)
		{
			int iNextVertex = GetNext(i, 1, nVertices);
			int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
			ASSERT(iEdgeIndex != -1);

			AssignFace(&m_Edges[iEdgeIndex], pUpdFace->id);
			hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;
		}

		// now set up in face
		pUpdFace->nEdges = nNewEdges;
		memcpy(pUpdFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

		delete phVertexList;
	}

	SSHANDLE id1 = pEdge1->id;
	SSHANDLE id2 = pEdge2->id;

	// delete old edges
	for(i = 0; i < m_nEdges; i++)
	{
		if(m_Edges[i].id == id1 || m_Edges[i].id == id2)
		{
			DeleteEdge(i);
			--i;
		}
	}

	return TRUE;
}