You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
841 lines
29 KiB
C
841 lines
29 KiB
C
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkGraph.h
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
/*-------------------------------------------------------------------------
|
||
|
Copyright 2008 Sandia Corporation.
|
||
|
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||
|
the U.S. Government retains certain rights in this software.
|
||
|
-------------------------------------------------------------------------*/
|
||
|
/**
|
||
|
* @class vtkGraph
|
||
|
* @brief Base class for graph data types.
|
||
|
*
|
||
|
*
|
||
|
* vtkGraph is the abstract base class that provides all read-only API for graph
|
||
|
* data types. A graph consists of a collection of vertices and a
|
||
|
* collection of edges connecting pairs of vertices. The vtkDirectedGraph
|
||
|
* subclass represents a graph whose edges have inherent order from source
|
||
|
* vertex to target vertex, while vtkUndirectedGraph is a graph whose edges
|
||
|
* have no inherent ordering.
|
||
|
*
|
||
|
* Graph vertices may be traversed in two ways. In the current implementation,
|
||
|
* all vertices are assigned consecutive ids starting at zero, so they may
|
||
|
* be traversed in a simple for loop from 0 to graph->GetNumberOfVertices() - 1.
|
||
|
* You may alternately create a vtkVertexListIterator and call graph->GetVertices(it).
|
||
|
* it->Next() will return the id of the next vertex, while it->HasNext() indicates
|
||
|
* whether there are more vertices in the graph.
|
||
|
* This is the preferred method, since in the future graphs may support filtering
|
||
|
* or subsetting where the vertex ids may not be contiguous.
|
||
|
*
|
||
|
* Graph edges must be traversed through iterators. To traverse all edges
|
||
|
* in a graph, create an instance of vtkEdgeListIterator and call graph->GetEdges(it).
|
||
|
* it->Next() returns lightweight vtkEdgeType structures, which contain the public
|
||
|
* fields Id, Source and Target. Id is the identifier for the edge, which may
|
||
|
* be used to look up values in assiciated edge data arrays. Source and Target
|
||
|
* store the ids of the source and target vertices of the edge. Note that the
|
||
|
* edge list iterator DOES NOT necessarily iterate over edges in order of ascending
|
||
|
* id. To traverse edges from wrapper code (Python, Java), use
|
||
|
* it->NextGraphEdge() instead of it->Next(). This will return a heavyweight,
|
||
|
* wrappable vtkGraphEdge object, which has the same fields as vtkEdgeType
|
||
|
* accessible through getter methods.
|
||
|
*
|
||
|
* To traverse all edges outgoing from a vertex, create a vtkOutEdgeIterator and
|
||
|
* call graph->GetOutEdges(v, it). it->Next() returns a lightweight vtkOutEdgeType
|
||
|
* containing the fields Id and Target. The source of the edge is always the
|
||
|
* vertex that was passed as an argument to GetOutEdges().
|
||
|
* Incoming edges may be similarly traversed with vtkInEdgeIterator, which returns
|
||
|
* vtkInEdgeType structures with Id and Source fields.
|
||
|
* Both vtkOutEdgeIterator and vtkInEdgeIterator also provide the wrapper functions
|
||
|
* NextGraphEdge() which return vtkGraphEdge objects.
|
||
|
*
|
||
|
* An additional iterator, vtkAdjacentVertexIterator can traverse outgoing vertices
|
||
|
* directly, instead needing to parse through edges. Initialize the iterator by
|
||
|
* calling graph->GetAdjacentVertices(v, it).
|
||
|
*
|
||
|
* vtkGraph has two instances of vtkDataSetAttributes for associated
|
||
|
* vertex and edge data. It also has a vtkPoints instance which may store
|
||
|
* x,y,z locations for each vertex. This is populated by filters such as
|
||
|
* vtkGraphLayout and vtkAssignCoordinates.
|
||
|
*
|
||
|
* All graph types share the same implementation, so the structure of one
|
||
|
* may be shared among multiple graphs, even graphs of different types.
|
||
|
* Structures from vtkUndirectedGraph and vtkMutableUndirectedGraph may be
|
||
|
* shared directly. Structures from vtkDirectedGraph, vtkMutableDirectedGraph,
|
||
|
* and vtkTree may be shared directly with the exception that setting a
|
||
|
* structure to a tree requires that a "is a tree" test passes.
|
||
|
*
|
||
|
* For graph types that are known to be compatible, calling ShallowCopy()
|
||
|
* or DeepCopy() will work as expected. When the outcome of a conversion
|
||
|
* is unknown (i.e. setting a graph to a tree), CheckedShallowCopy() and
|
||
|
* CheckedDeepCopy() exist which are identical to ShallowCopy() and DeepCopy(),
|
||
|
* except that instead of emitting an error for an incompatible structure,
|
||
|
* the function returns false. This allows you to programmatically check
|
||
|
* structure compatibility without causing error messages.
|
||
|
*
|
||
|
* To construct a graph, use vtkMutableDirectedGraph or
|
||
|
* vtkMutableUndirectedGraph. You may then use CheckedShallowCopy
|
||
|
* to set the contents of a mutable graph type into one of the non-mutable
|
||
|
* types vtkDirectedGraph, vtkUndirectedGraph.
|
||
|
* To construct a tree, use vtkMutableDirectedGraph, with directed edges
|
||
|
* which point from the parent to the child, then use CheckedShallowCopy
|
||
|
* to set the structure to a vtkTree.
|
||
|
*
|
||
|
* @warning
|
||
|
* All copy operations implement copy-on-write. The structures are initially
|
||
|
* shared, but if one of the graphs is modified, the structure is copied
|
||
|
* so that to the user they function as if they were deep copied. This means
|
||
|
* that care must be taken if different threads are accessing different graph
|
||
|
* instances that share the same structure. Race conditions may develop if
|
||
|
* one thread is modifying the graph at the same time that another graph is
|
||
|
* copying the structure.
|
||
|
*
|
||
|
* @par Vertex pedigree IDs:
|
||
|
* The vertices in a vtkGraph can be associated with pedigree IDs
|
||
|
* through GetVertexData()->SetPedigreeIds. In this case, there is a
|
||
|
* 1-1 mapping between pedigree Ids and vertices. One can query the
|
||
|
* vertex ID based on the pedigree ID using FindVertex, add new
|
||
|
* vertices by pedigree ID with AddVertex, and add edges based on the
|
||
|
* pedigree IDs of the source and target vertices. For example,
|
||
|
* AddEdge("Here", "There") will find (or add) vertices with pedigree
|
||
|
* ID "Here" and "There" and then introduce an edge from "Here" to
|
||
|
* "There".
|
||
|
*
|
||
|
* @par Vertex pedigree IDs:
|
||
|
* To configure the vtkGraph with a pedigree ID mapping, create a
|
||
|
* vtkDataArray that will store the pedigree IDs and set that array as
|
||
|
* the pedigree ID array for the vertices via
|
||
|
* GetVertexData()->SetPedigreeIds().
|
||
|
*
|
||
|
*
|
||
|
* @par Distributed graphs:
|
||
|
* vtkGraph instances can be distributed across multiple machines, to
|
||
|
* allow the construction and manipulation of graphs larger than a
|
||
|
* single machine could handle. A distributed graph will typically be
|
||
|
* distributed across many different nodes within a cluster, using the
|
||
|
* Message Passing Interface (MPI) to allow those cluster nodes to
|
||
|
* communicate.
|
||
|
*
|
||
|
* @par Distributed graphs:
|
||
|
* An empty vtkGraph can be made into a distributed graph by attaching
|
||
|
* an instance of a vtkDistributedGraphHelper via the
|
||
|
* SetDistributedGraphHelper() method. To determine whether a graph is
|
||
|
* distributed or not, call GetDistributedGraphHelper() and check
|
||
|
* whether the result is non-nullptr. For a distributed graph, the number
|
||
|
* of processors across which the graph is distributed can be
|
||
|
* retrieved by extracting the value for the DATA_NUMBER_OF_PIECES key
|
||
|
* in the vtkInformation object (retrieved by GetInformation())
|
||
|
* associated with the graph. Similarly, the value corresponding to
|
||
|
* the DATA_PIECE_NUMBER key of the vtkInformation object describes
|
||
|
* which piece of the data this graph instance provides.
|
||
|
*
|
||
|
* @par Distributed graphs:
|
||
|
* Distributed graphs behave somewhat differently from non-distributed
|
||
|
* graphs, and will require special care. In a distributed graph, each
|
||
|
* of the processors will contain a subset of the vertices in the
|
||
|
* graph. That subset of vertices can be accessed via the
|
||
|
* vtkVertexListIterator produced by GetVertices().
|
||
|
* GetNumberOfVertices(), therefore, returns the number of vertices
|
||
|
* stored locally: it does not account for vertices stored on other
|
||
|
* processors. A vertex (or edge) is identified by both the rank of
|
||
|
* its owning processor and by its index within that processor, both
|
||
|
* of which are encoded within the vtkIdType value that describes that
|
||
|
* vertex (or edge). The owning processor is a value between 0 and
|
||
|
* P-1, where P is the number of processors across which the vtkGraph
|
||
|
* has been distributed. The local index will be a value between 0 and
|
||
|
* GetNumberOfVertices(), for vertices, or GetNumberOfEdges(), for
|
||
|
* edges, and can be used to access the local parts of distributed
|
||
|
* data arrays. When given a vtkIdType identifying a vertex, one can
|
||
|
* determine the owner of the vertex with
|
||
|
* vtkDistributedGraphHelper::GetVertexOwner() and the local index
|
||
|
* with vtkDistributedGraphHelper::GetVertexIndex(). With edges, the
|
||
|
* appropriate methods are vtkDistributedGraphHelper::GetEdgeOwner()
|
||
|
* and vtkDistributedGraphHelper::GetEdgeIndex(), respectively. To
|
||
|
* construct a vtkIdType representing either a vertex or edge given
|
||
|
* only its owner and local index, use
|
||
|
* vtkDistributedGraphHelper::MakeDistributedId().
|
||
|
*
|
||
|
* @par Distributed graphs:
|
||
|
* The edges in a distributed graph are always stored on the
|
||
|
* processors that own the vertices named by the edge. For example,
|
||
|
* given a directed edge (u, v), the edge will be stored in the
|
||
|
* out-edges list for vertex u on the processor that owns u, and in
|
||
|
* the in-edges list for vertex v on the processor that owns v. This
|
||
|
* "row-wise" decomposition of the graph means that, for any vertex
|
||
|
* that is local to a processor, that processor can look at all of the
|
||
|
* incoming and outgoing edges of the graph. Processors cannot,
|
||
|
* however, access the incoming or outgoing edge lists of vertex owned
|
||
|
* by other processors. Vertices owned by other processors will not be
|
||
|
* encountered when traversing the vertex list via GetVertices(), but
|
||
|
* may be encountered by traversing the in- and out-edge lists of
|
||
|
* local vertices or the edge list.
|
||
|
*
|
||
|
* @par Distributed graphs:
|
||
|
* Distributed graphs can have pedigree IDs for the vertices in the
|
||
|
* same way that non-distributed graphs can. In this case, the
|
||
|
* distribution of the vertices in the graph is based on pedigree
|
||
|
* ID. For example, a vertex with the pedigree ID "Here" might land on
|
||
|
* processor 0 while a vertex pedigree ID "There" would end up on
|
||
|
* processor 3. By default, the pedigree IDs themselves are hashed to
|
||
|
* give a random (and, hopefully, even) distribution of the
|
||
|
* vertices. However, one can provide a different vertex distribution
|
||
|
* function by calling
|
||
|
* vtkDistributedGraphHelper::SetVertexPedigreeIdDistribution. Once a
|
||
|
* distributed graph has pedigree IDs, the no-argument AddVertex()
|
||
|
* method can no longer be used. Additionally, once a vertex has a
|
||
|
* pedigree ID, that pedigree ID should not be changed unless the user
|
||
|
* can guarantee that the vertex distribution will still map that
|
||
|
* vertex to the same processor where it already resides.
|
||
|
*
|
||
|
* @sa
|
||
|
* vtkDirectedGraph vtkUndirectedGraph vtkMutableDirectedGraph
|
||
|
* vtkMutableUndirectedGraph vtkTree vtkDistributedGraphHelper
|
||
|
*
|
||
|
* @par Thanks:
|
||
|
* Thanks to Brian Wylie, Timothy Shead, Ken Moreland of Sandia National
|
||
|
* Laboratories and Douglas Gregor of Indiana University for designing these
|
||
|
* classes.
|
||
|
*/
|
||
|
|
||
|
#ifndef vtkGraph_h
|
||
|
#define vtkGraph_h
|
||
|
|
||
|
#include "vtkCommonDataModelModule.h" // For export macro
|
||
|
#include "vtkDataObject.h"
|
||
|
|
||
|
class vtkAdjacentVertexIterator;
|
||
|
class vtkCellArray;
|
||
|
class vtkEdgeListIterator;
|
||
|
class vtkDataSetAttributes;
|
||
|
class vtkDirectedGraph;
|
||
|
class vtkGraphEdge;
|
||
|
class vtkGraphEdgePoints;
|
||
|
class vtkDistributedGraphHelper;
|
||
|
class vtkGraphInternals;
|
||
|
class vtkIdTypeArray;
|
||
|
class vtkInEdgeIterator;
|
||
|
class vtkOutEdgeIterator;
|
||
|
class vtkPoints;
|
||
|
class vtkUndirectedGraph;
|
||
|
class vtkVertexListIterator;
|
||
|
class vtkVariant;
|
||
|
class vtkVariantArray;
|
||
|
|
||
|
// Forward declare some boost stuff even if boost wrappers
|
||
|
// are turned off.
|
||
|
namespace boost
|
||
|
{
|
||
|
class vtk_edge_iterator;
|
||
|
class vtk_out_edge_pointer_iterator;
|
||
|
class vtk_in_edge_pointer_iterator;
|
||
|
}
|
||
|
|
||
|
// Edge structures.
|
||
|
struct vtkEdgeBase
|
||
|
{
|
||
|
vtkEdgeBase() {}
|
||
|
vtkEdgeBase(vtkIdType id)
|
||
|
: Id(id)
|
||
|
{
|
||
|
}
|
||
|
vtkIdType Id;
|
||
|
};
|
||
|
|
||
|
struct vtkOutEdgeType : vtkEdgeBase
|
||
|
{
|
||
|
vtkOutEdgeType() {}
|
||
|
vtkOutEdgeType(vtkIdType t, vtkIdType id)
|
||
|
: vtkEdgeBase(id)
|
||
|
, Target(t)
|
||
|
{
|
||
|
}
|
||
|
vtkIdType Target;
|
||
|
};
|
||
|
|
||
|
struct vtkInEdgeType : vtkEdgeBase
|
||
|
{
|
||
|
vtkInEdgeType() {}
|
||
|
vtkInEdgeType(vtkIdType s, vtkIdType id)
|
||
|
: vtkEdgeBase(id)
|
||
|
, Source(s)
|
||
|
{
|
||
|
}
|
||
|
vtkIdType Source;
|
||
|
};
|
||
|
|
||
|
struct vtkEdgeType : vtkEdgeBase
|
||
|
{
|
||
|
vtkEdgeType() {}
|
||
|
vtkEdgeType(vtkIdType s, vtkIdType t, vtkIdType id)
|
||
|
: vtkEdgeBase(id)
|
||
|
, Source(s)
|
||
|
, Target(t)
|
||
|
{
|
||
|
}
|
||
|
vtkIdType Source;
|
||
|
vtkIdType Target;
|
||
|
};
|
||
|
|
||
|
class VTKCOMMONDATAMODEL_EXPORT vtkGraph : public vtkDataObject
|
||
|
{
|
||
|
public:
|
||
|
vtkTypeMacro(vtkGraph, vtkDataObject);
|
||
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get the vertex or edge data.
|
||
|
*/
|
||
|
vtkGetObjectMacro(VertexData, vtkDataSetAttributes);
|
||
|
vtkGetObjectMacro(EdgeData, vtkDataSetAttributes);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Return what type of dataset this is.
|
||
|
*/
|
||
|
int GetDataObjectType() override { return VTK_GRAPH; }
|
||
|
|
||
|
/**
|
||
|
* Initialize to an empty graph.
|
||
|
*/
|
||
|
void Initialize() override;
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* These methods return the point (0,0,0) until the points structure
|
||
|
* is created, when it returns the actual point position. In a
|
||
|
* distributed graph, only the points for local vertices can be
|
||
|
* retrieved.
|
||
|
*/
|
||
|
double* GetPoint(vtkIdType ptId);
|
||
|
void GetPoint(vtkIdType ptId, double x[3]);
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Returns the points array for this graph.
|
||
|
* If points is not yet constructed, generates and returns
|
||
|
* a new points array filled with (0,0,0) coordinates. In a
|
||
|
* distributed graph, only the points for local vertices can be
|
||
|
* retrieved or modified.
|
||
|
*/
|
||
|
vtkPoints* GetPoints();
|
||
|
virtual void SetPoints(vtkPoints* points);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Compute the bounds of the graph. In a distributed graph, this
|
||
|
* computes the bounds around the local part of the graph.
|
||
|
*/
|
||
|
void ComputeBounds();
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Return a pointer to the geometry bounding box in the form
|
||
|
* (xmin,xmax, ymin,ymax, zmin,zmax). In a distributed graph, this
|
||
|
* computes the bounds around the local part of the graph.
|
||
|
*/
|
||
|
double* GetBounds();
|
||
|
void GetBounds(double bounds[6]);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* The modified time of the graph.
|
||
|
*/
|
||
|
vtkMTimeType GetMTime() override;
|
||
|
|
||
|
/**
|
||
|
* Initializes the out edge iterator to iterate over
|
||
|
* all outgoing edges of vertex v. For an undirected graph,
|
||
|
* returns all incident edges. In a distributed graph, the vertex
|
||
|
* v must be local to this processor.
|
||
|
*/
|
||
|
virtual void GetOutEdges(vtkIdType v, vtkOutEdgeIterator* it);
|
||
|
|
||
|
/**
|
||
|
* The total of all incoming and outgoing vertices for vertex v.
|
||
|
* For undirected graphs, this is simply the number of edges incident
|
||
|
* to v. In a distributed graph, the vertex v must be local to this
|
||
|
* processor.
|
||
|
*/
|
||
|
virtual vtkIdType GetDegree(vtkIdType v);
|
||
|
|
||
|
/**
|
||
|
* The number of outgoing edges from vertex v.
|
||
|
* For undirected graphs, returns the same as GetDegree(). In a
|
||
|
* distributed graph, the vertex v must be local to this processor.
|
||
|
*/
|
||
|
virtual vtkIdType GetOutDegree(vtkIdType v);
|
||
|
|
||
|
/**
|
||
|
* Random-access method for retrieving outgoing edges from vertex v.
|
||
|
*/
|
||
|
virtual vtkOutEdgeType GetOutEdge(vtkIdType v, vtkIdType index);
|
||
|
|
||
|
/**
|
||
|
* Random-access method for retrieving outgoing edges from vertex v.
|
||
|
* The method fills the vtkGraphEdge instance with the id, source, and
|
||
|
* target of the edge. This method is provided for wrappers,
|
||
|
* GetOutEdge(vtkIdType, vtkIdType) is preferred.
|
||
|
*/
|
||
|
virtual void GetOutEdge(vtkIdType v, vtkIdType index, vtkGraphEdge* e);
|
||
|
|
||
|
/**
|
||
|
* Initializes the in edge iterator to iterate over
|
||
|
* all incoming edges to vertex v. For an undirected graph,
|
||
|
* returns all incident edges. In a distributed graph, the vertex
|
||
|
* v must be local to this processor.
|
||
|
*/
|
||
|
virtual void GetInEdges(vtkIdType v, vtkInEdgeIterator* it);
|
||
|
|
||
|
/**
|
||
|
* The number of incoming edges to vertex v.
|
||
|
* For undirected graphs, returns the same as GetDegree(). In a
|
||
|
* distributed graph, the vertex v must be local to this processor.
|
||
|
*/
|
||
|
virtual vtkIdType GetInDegree(vtkIdType v);
|
||
|
|
||
|
/**
|
||
|
* Random-access method for retrieving incoming edges to vertex v.
|
||
|
*/
|
||
|
virtual vtkInEdgeType GetInEdge(vtkIdType v, vtkIdType index);
|
||
|
|
||
|
/**
|
||
|
* Random-access method for retrieving incoming edges to vertex v.
|
||
|
* The method fills the vtkGraphEdge instance with the id, source, and
|
||
|
* target of the edge. This method is provided for wrappers,
|
||
|
* GetInEdge(vtkIdType, vtkIdType) is preferred.
|
||
|
*/
|
||
|
virtual void GetInEdge(vtkIdType v, vtkIdType index, vtkGraphEdge* e);
|
||
|
|
||
|
/**
|
||
|
* Initializes the adjacent vertex iterator to iterate over
|
||
|
* all outgoing vertices from vertex v. For an undirected graph,
|
||
|
* returns all adjacent vertices. In a distributed graph, the vertex
|
||
|
* v must be local to this processor.
|
||
|
*/
|
||
|
virtual void GetAdjacentVertices(vtkIdType v, vtkAdjacentVertexIterator* it);
|
||
|
|
||
|
/**
|
||
|
* Initializes the edge list iterator to iterate over all
|
||
|
* edges in the graph. Edges may not be traversed in order of
|
||
|
* increasing edge id. In a distributed graph, this returns edges
|
||
|
* that are stored locally.
|
||
|
*/
|
||
|
virtual void GetEdges(vtkEdgeListIterator* it);
|
||
|
|
||
|
/**
|
||
|
* The number of edges in the graph. In a distributed graph,
|
||
|
* this returns the number of edges stored locally.
|
||
|
*/
|
||
|
virtual vtkIdType GetNumberOfEdges();
|
||
|
|
||
|
/**
|
||
|
* Initializes the vertex list iterator to iterate over all
|
||
|
* vertices in the graph. In a distributed graph, the iterator
|
||
|
* traverses all local vertices.
|
||
|
*/
|
||
|
virtual void GetVertices(vtkVertexListIterator* it);
|
||
|
|
||
|
/**
|
||
|
* The number of vertices in the graph. In a distributed graph,
|
||
|
* returns the number of local vertices in the graph.
|
||
|
*/
|
||
|
virtual vtkIdType GetNumberOfVertices();
|
||
|
|
||
|
/**
|
||
|
* Sets the distributed graph helper of this graph, turning it into a
|
||
|
* distributed graph. This operation can only be executed on an empty
|
||
|
* graph.
|
||
|
*/
|
||
|
void SetDistributedGraphHelper(vtkDistributedGraphHelper* helper);
|
||
|
|
||
|
/**
|
||
|
* Retrieves the distributed graph helper for this graph
|
||
|
*/
|
||
|
vtkDistributedGraphHelper* GetDistributedGraphHelper();
|
||
|
|
||
|
/**
|
||
|
* Retrieve the vertex with the given pedigree ID. If successful,
|
||
|
* returns the ID of the vertex. Otherwise, either the vertex data
|
||
|
* does not have a pedigree ID array or there is no vertex with the
|
||
|
* given pedigree ID, so this function returns -1.
|
||
|
* If the graph is a distributed graph, this method will return the
|
||
|
* Distributed-ID of the vertex.
|
||
|
*/
|
||
|
vtkIdType FindVertex(const vtkVariant& pedigreeID);
|
||
|
|
||
|
/**
|
||
|
* Shallow copies the data object into this graph.
|
||
|
* If it is an incompatible graph, reports an error.
|
||
|
*/
|
||
|
void ShallowCopy(vtkDataObject* obj) override;
|
||
|
|
||
|
/**
|
||
|
* Deep copies the data object into this graph.
|
||
|
* If it is an incompatible graph, reports an error.
|
||
|
*/
|
||
|
void DeepCopy(vtkDataObject* obj) override;
|
||
|
|
||
|
/**
|
||
|
* Does a shallow copy of the topological information,
|
||
|
* but not the associated attributes.
|
||
|
*/
|
||
|
virtual void CopyStructure(vtkGraph* g);
|
||
|
|
||
|
/**
|
||
|
* Performs the same operation as ShallowCopy(),
|
||
|
* but instead of reporting an error for an incompatible graph,
|
||
|
* returns false.
|
||
|
*/
|
||
|
virtual bool CheckedShallowCopy(vtkGraph* g);
|
||
|
|
||
|
/**
|
||
|
* Performs the same operation as DeepCopy(),
|
||
|
* but instead of reporting an error for an incompatible graph,
|
||
|
* returns false.
|
||
|
*/
|
||
|
virtual bool CheckedDeepCopy(vtkGraph* g);
|
||
|
|
||
|
/**
|
||
|
* Reclaim unused memory.
|
||
|
*/
|
||
|
virtual void Squeeze();
|
||
|
|
||
|
/**
|
||
|
* Return the actual size of the data in kibibytes (1024 bytes). This number
|
||
|
* is valid only after the pipeline has updated. The memory size
|
||
|
* returned is guaranteed to be greater than or equal to the
|
||
|
* memory required to represent the data (e.g., extra space in
|
||
|
* arrays, etc. are not included in the return value).
|
||
|
*/
|
||
|
unsigned long GetActualMemorySize() override;
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Retrieve a graph from an information vector.
|
||
|
*/
|
||
|
static vtkGraph* GetData(vtkInformation* info);
|
||
|
static vtkGraph* GetData(vtkInformationVector* v, int i = 0);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Reorder the outgoing vertices of a vertex.
|
||
|
* The vertex list must have the same elements as the current out edge
|
||
|
* list, just in a different order.
|
||
|
* This method does not change the topology of the graph.
|
||
|
* In a distributed graph, the vertex v must be local.
|
||
|
*/
|
||
|
void ReorderOutVertices(vtkIdType v, vtkIdTypeArray* vertices);
|
||
|
|
||
|
/**
|
||
|
* Returns true if both graphs point to the same adjacency structure.
|
||
|
* Can be used to test the copy-on-write feature of the graph.
|
||
|
*/
|
||
|
bool IsSameStructure(vtkGraph* other);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Retrieve the source and target vertices for an edge id.
|
||
|
* NOTE: The first time this is called, the graph will build
|
||
|
* a mapping array from edge id to source/target that is the
|
||
|
* same size as the number of edges in the graph. If you have
|
||
|
* access to a vtkOutEdgeType, vtkInEdgeType, vtkEdgeType, or
|
||
|
* vtkGraphEdge, you should directly use these structures
|
||
|
* to look up the source or target instead of this method.
|
||
|
*/
|
||
|
vtkIdType GetSourceVertex(vtkIdType e);
|
||
|
vtkIdType GetTargetVertex(vtkIdType e);
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get/Set the internal edge control points associated with each edge.
|
||
|
* The size of the pts array is 3*npts, and holds the x,y,z
|
||
|
* location of each edge control point.
|
||
|
*/
|
||
|
void SetEdgePoints(vtkIdType e, vtkIdType npts, const double pts[]) VTK_SIZEHINT(pts, 3 * npts);
|
||
|
void GetEdgePoints(vtkIdType e, vtkIdType& npts, double*& pts) VTK_SIZEHINT(pts, 3 * npts);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Get the number of edge points associated with an edge.
|
||
|
*/
|
||
|
vtkIdType GetNumberOfEdgePoints(vtkIdType e);
|
||
|
|
||
|
/**
|
||
|
* Get the x,y,z location of a point along edge e.
|
||
|
*/
|
||
|
double* GetEdgePoint(vtkIdType e, vtkIdType i) VTK_SIZEHINT(3);
|
||
|
|
||
|
/**
|
||
|
* Clear all points associated with an edge.
|
||
|
*/
|
||
|
void ClearEdgePoints(vtkIdType e);
|
||
|
|
||
|
/**
|
||
|
* Set an x,y,z location of a point along an edge.
|
||
|
* This assumes there is already a point at location i, and simply
|
||
|
* overwrites it.
|
||
|
*/
|
||
|
void SetEdgePoint(vtkIdType e, vtkIdType i, const double x[3]);
|
||
|
void SetEdgePoint(vtkIdType e, vtkIdType i, double x, double y, double z)
|
||
|
{
|
||
|
double p[3] = { x, y, z };
|
||
|
this->SetEdgePoint(e, i, p);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds a point to the end of the list of edge points for a certain edge.
|
||
|
*/
|
||
|
void AddEdgePoint(vtkIdType e, const double x[3]);
|
||
|
void AddEdgePoint(vtkIdType e, double x, double y, double z)
|
||
|
{
|
||
|
double p[3] = { x, y, z };
|
||
|
this->AddEdgePoint(e, p);
|
||
|
}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Copy the internal edge point data from another graph into this graph.
|
||
|
* Both graphs must have the same number of edges.
|
||
|
*/
|
||
|
void ShallowCopyEdgePoints(vtkGraph* g);
|
||
|
void DeepCopyEdgePoints(vtkGraph* g);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Returns the internal representation of the graph. If modifying is
|
||
|
* true, then the returned vtkGraphInternals object will be unique to
|
||
|
* this vtkGraph object.
|
||
|
*/
|
||
|
vtkGraphInternals* GetGraphInternals(bool modifying);
|
||
|
|
||
|
/**
|
||
|
* Fills a list of edge indices with the edges contained in the induced
|
||
|
* subgraph formed by the vertices in the vertex list.
|
||
|
*/
|
||
|
void GetInducedEdges(vtkIdTypeArray* verts, vtkIdTypeArray* edges);
|
||
|
|
||
|
/**
|
||
|
* Returns the attributes of the data object as a vtkFieldData.
|
||
|
* This returns non-null values in all the same cases as GetAttributes,
|
||
|
* in addition to the case of FIELD, which will return the field data
|
||
|
* for any vtkDataObject subclass.
|
||
|
*/
|
||
|
vtkFieldData* GetAttributesAsFieldData(int type) override;
|
||
|
|
||
|
/**
|
||
|
* Get the number of elements for a specific attribute type (VERTEX, EDGE, etc.).
|
||
|
*/
|
||
|
vtkIdType GetNumberOfElements(int type) override;
|
||
|
|
||
|
/**
|
||
|
* Dump the contents of the graph to standard output.
|
||
|
*/
|
||
|
void Dump();
|
||
|
|
||
|
/**
|
||
|
* Returns the Id of the edge between vertex a and vertex b.
|
||
|
* This is independent of directionality of the edge, that is,
|
||
|
* if edge A->B exists or if edge B->A exists, this function will
|
||
|
* return its Id. If multiple edges exist between a and b, here is no guarantee
|
||
|
* about which one will be returned.
|
||
|
* Returns -1 if no edge exists between a and b.
|
||
|
*/
|
||
|
vtkIdType GetEdgeId(vtkIdType a, vtkIdType b);
|
||
|
|
||
|
/**
|
||
|
* Convert the graph to a directed graph.
|
||
|
*/
|
||
|
bool ToDirectedGraph(vtkDirectedGraph* g);
|
||
|
|
||
|
/**
|
||
|
* Convert the graph to an undirected graph.
|
||
|
*/
|
||
|
bool ToUndirectedGraph(vtkUndirectedGraph* g);
|
||
|
|
||
|
protected:
|
||
|
vtkGraph();
|
||
|
~vtkGraph() override;
|
||
|
|
||
|
/**
|
||
|
* Protected method for adding vertices, optionally with properties,
|
||
|
* used by mutable subclasses. If vertex is non-null, it will be set
|
||
|
* to the newly-added (or found) vertex. Note that if propertyArr is
|
||
|
* non-null and the vertex data contains pedigree IDs, a vertex will
|
||
|
* only be added if there is no vertex with that pedigree ID.
|
||
|
*/
|
||
|
void AddVertexInternal(vtkVariantArray* propertyArr = nullptr, vtkIdType* vertex = nullptr);
|
||
|
|
||
|
/**
|
||
|
* Adds a vertex with the given pedigree ID to the graph. If a vertex with
|
||
|
* this pedigree ID already exists, no new vertex is added, but the vertex
|
||
|
* argument is set to the ID of the existing vertex. Otherwise, a
|
||
|
* new vertex is added and its ID is provided.
|
||
|
*/
|
||
|
void AddVertexInternal(const vtkVariant& pedigree, vtkIdType* vertex);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Protected method for adding edges of a certain directedness used
|
||
|
* by mutable subclasses. If propertyArr is non-null, it specifies
|
||
|
* the properties to be attached to the newly-created edge. If
|
||
|
* non-null, edge will receive the newly-added edge.
|
||
|
*/
|
||
|
void AddEdgeInternal(
|
||
|
vtkIdType u, vtkIdType v, bool directed, vtkVariantArray* propertyArr, vtkEdgeType* edge);
|
||
|
void AddEdgeInternal(const vtkVariant& uPedigree, vtkIdType v, bool directed,
|
||
|
vtkVariantArray* propertyArr, vtkEdgeType* edge);
|
||
|
void AddEdgeInternal(vtkIdType u, const vtkVariant& vPedigree, bool directed,
|
||
|
vtkVariantArray* propertyArr, vtkEdgeType* edge);
|
||
|
void AddEdgeInternal(const vtkVariant& uPedigree, const vtkVariant& vPedigree, bool directed,
|
||
|
vtkVariantArray* propertyArr, vtkEdgeType* edge);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Removes a vertex from the graph, along with any adjacent edges.
|
||
|
* This invalidates the id of the last vertex, since it is reassigned to v.
|
||
|
*/
|
||
|
void RemoveVertexInternal(vtkIdType v, bool directed);
|
||
|
|
||
|
/**
|
||
|
* Removes an edge from the graph.
|
||
|
* This invalidates the id of the last edge, since it is reassigned to e.
|
||
|
*/
|
||
|
void RemoveEdgeInternal(vtkIdType e, bool directed);
|
||
|
|
||
|
/**
|
||
|
* Removes a collection of vertices from the graph, along with any adjacent edges.
|
||
|
*/
|
||
|
void RemoveVerticesInternal(vtkIdTypeArray* arr, bool directed);
|
||
|
|
||
|
/**
|
||
|
* Removes a collection of edges from the graph.
|
||
|
*/
|
||
|
void RemoveEdgesInternal(vtkIdTypeArray* arr, bool directed);
|
||
|
|
||
|
/**
|
||
|
* Subclasses override this method to accept the structure
|
||
|
* based on their requirements.
|
||
|
*/
|
||
|
virtual bool IsStructureValid(vtkGraph* g) = 0;
|
||
|
|
||
|
/**
|
||
|
* Copy internal data structure.
|
||
|
*/
|
||
|
virtual void CopyInternal(vtkGraph* g, bool deep);
|
||
|
|
||
|
/**
|
||
|
* The adjacency list internals of this graph.
|
||
|
*/
|
||
|
vtkGraphInternals* Internals;
|
||
|
|
||
|
/**
|
||
|
* The distributed graph helper. Only non-nullptr for distributed graphs.
|
||
|
*/
|
||
|
vtkDistributedGraphHelper* DistributedHelper;
|
||
|
|
||
|
/**
|
||
|
* Private method for setting internals.
|
||
|
*/
|
||
|
void SetInternals(vtkGraphInternals* internals);
|
||
|
|
||
|
/**
|
||
|
* The structure for holding the edge points.
|
||
|
*/
|
||
|
vtkGraphEdgePoints* EdgePoints;
|
||
|
|
||
|
/**
|
||
|
* Private method for setting edge points.
|
||
|
*/
|
||
|
void SetEdgePoints(vtkGraphEdgePoints* edgePoints);
|
||
|
|
||
|
/**
|
||
|
* If this instance does not own its internals, it makes a copy of the
|
||
|
* internals. This is called before any write operation.
|
||
|
*/
|
||
|
void ForceOwnership();
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Fast access functions for iterators.
|
||
|
*/
|
||
|
virtual void GetOutEdges(vtkIdType v, const vtkOutEdgeType*& edges, vtkIdType& nedges);
|
||
|
virtual void GetInEdges(vtkIdType v, const vtkInEdgeType*& edges, vtkIdType& nedges);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Builds a mapping from edge id to source/target vertex id.
|
||
|
*/
|
||
|
void BuildEdgeList();
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Friend iterator classes.
|
||
|
*/
|
||
|
friend class vtkAdjacentVertexIterator;
|
||
|
friend class vtkEdgeListIterator;
|
||
|
friend class vtkInEdgeIterator;
|
||
|
friend class vtkOutEdgeIterator;
|
||
|
friend class boost::vtk_edge_iterator;
|
||
|
friend class boost::vtk_in_edge_pointer_iterator;
|
||
|
friend class boost::vtk_out_edge_pointer_iterator;
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* The vertex and edge data.
|
||
|
*/
|
||
|
vtkDataSetAttributes* VertexData;
|
||
|
vtkDataSetAttributes* EdgeData;
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* (xmin,xmax, ymin,ymax, zmin,zmax) geometric bounds.
|
||
|
*/
|
||
|
double Bounds[6];
|
||
|
|
||
|
/**
|
||
|
* Time at which bounds were computed.
|
||
|
*/
|
||
|
vtkTimeStamp ComputeTime;
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* The vertex locations.
|
||
|
*/
|
||
|
vtkPoints* Points;
|
||
|
static double DefaultPoint[3];
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* The optional mapping from edge id to source/target ids.
|
||
|
*/
|
||
|
vtkGetObjectMacro(EdgeList, vtkIdTypeArray);
|
||
|
virtual void SetEdgeList(vtkIdTypeArray* list);
|
||
|
vtkIdTypeArray* EdgeList;
|
||
|
//@}
|
||
|
|
||
|
private:
|
||
|
vtkGraph(const vtkGraph&) = delete;
|
||
|
void operator=(const vtkGraph&) = delete;
|
||
|
};
|
||
|
|
||
|
bool VTKCOMMONDATAMODEL_EXPORT operator==(vtkEdgeBase e1, vtkEdgeBase e2);
|
||
|
bool VTKCOMMONDATAMODEL_EXPORT operator!=(vtkEdgeBase e1, vtkEdgeBase e2);
|
||
|
VTKCOMMONDATAMODEL_EXPORT ostream& operator<<(ostream& out, vtkEdgeBase e);
|
||
|
|
||
|
#endif
|