rapier3d/data/
graph.rs

1// This is basically a stripped down version of petgraph's UnGraph.
2// - It is not generic with respect to the index type (we always use u32).
3// - It preserves associated edge iteration order after Serialization/Deserialization.
4// - It is always undirected.
5//! A stripped-down version of petgraph's UnGraph.
6
7use std::cmp::max;
8use std::ops::{Index, IndexMut};
9
10/// Node identifier.
11#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
12#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
13pub struct NodeIndex(u32);
14
15impl NodeIndex {
16    #[inline]
17    pub fn new(x: u32) -> Self {
18        NodeIndex(x)
19    }
20
21    #[inline]
22    pub fn index(self) -> usize {
23        self.0 as usize
24    }
25
26    #[inline]
27    pub fn end() -> Self {
28        NodeIndex(crate::INVALID_U32)
29    }
30
31    fn _into_edge(self) -> EdgeIndex {
32        EdgeIndex(self.0)
33    }
34}
35
36impl From<u32> for NodeIndex {
37    fn from(ix: u32) -> Self {
38        NodeIndex(ix)
39    }
40}
41
42/// Edge identifier.
43#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
44#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
45pub struct EdgeIndex(u32);
46
47impl EdgeIndex {
48    #[inline]
49    pub fn new(x: u32) -> Self {
50        EdgeIndex(x)
51    }
52
53    #[inline]
54    pub fn index(self) -> usize {
55        self.0 as usize
56    }
57
58    /// An invalid `EdgeIndex` used to denote absence of an edge, for example
59    /// to end an adjacency list.
60    #[inline]
61    pub fn end() -> Self {
62        EdgeIndex(crate::INVALID_U32)
63    }
64
65    fn _into_node(self) -> NodeIndex {
66        NodeIndex(self.0)
67    }
68}
69
70impl From<u32> for EdgeIndex {
71    fn from(ix: u32) -> Self {
72        EdgeIndex(ix)
73    }
74}
75
76#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
77#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
78pub enum Direction {
79    Outgoing = 0,
80    Incoming = 1,
81}
82
83impl Direction {
84    fn opposite(self) -> Direction {
85        match self {
86            Direction::Outgoing => Direction::Incoming,
87            Direction::Incoming => Direction::Outgoing,
88        }
89    }
90}
91
92const DIRECTIONS: [Direction; 2] = [Direction::Outgoing, Direction::Incoming];
93
94/// The graph's node type.
95#[derive(Debug, Copy, Clone)]
96#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
97pub struct Node<N> {
98    /// Associated node data.
99    pub weight: N,
100    /// Next edge in outgoing and incoming edge lists.
101    next: [EdgeIndex; 2],
102}
103
104/// The graph's edge type.
105#[derive(Debug, Copy, Clone)]
106#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
107pub struct Edge<E> {
108    /// Associated edge data.
109    pub weight: E,
110    /// Next edge in outgoing and incoming edge lists.
111    next: [EdgeIndex; 2],
112    /// Start and End node index
113    node: [NodeIndex; 2],
114}
115
116impl<E> Edge<E> {
117    /// Return the source node index.
118    pub fn source(&self) -> NodeIndex {
119        self.node[0]
120    }
121
122    /// Return the target node index.
123    pub fn target(&self) -> NodeIndex {
124        self.node[1]
125    }
126}
127
128#[derive(Clone, Debug, Default)]
129#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
130pub struct Graph<N, E> {
131    pub(crate) nodes: Vec<Node<N>>,
132    pub(crate) edges: Vec<Edge<E>>,
133}
134
135enum Pair<T> {
136    Both(T, T),
137    One(T),
138    None,
139}
140
141/// Get mutable references at index `a` and `b`.
142fn index_twice<T>(arr: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
143    if max(a, b) >= arr.len() {
144        Pair::None
145    } else if a == b {
146        Pair::One(&mut arr[max(a, b)])
147    } else {
148        // safe because a, b are in bounds and distinct
149        unsafe {
150            let ar = &mut *(arr.get_unchecked_mut(a) as *mut _);
151            let br = &mut *(arr.get_unchecked_mut(b) as *mut _);
152            Pair::Both(ar, br)
153        }
154    }
155}
156
157impl<N, E> Graph<N, E> {
158    /// Create a new `Graph` with estimated capacity.
159    pub fn with_capacity(nodes: usize, edges: usize) -> Self {
160        Graph {
161            nodes: Vec::with_capacity(nodes),
162            edges: Vec::with_capacity(edges),
163        }
164    }
165
166    /// Add a node (also called vertex) with associated data `weight` to the graph.
167    ///
168    /// Computes in **O(1)** time.
169    ///
170    /// Return the index of the new node.
171    ///
172    /// **Panics** if the Graph is at the maximum number of nodes for its index
173    /// type (N/A if usize).
174    pub fn add_node(&mut self, weight: N) -> NodeIndex {
175        let node = Node {
176            weight,
177            next: [EdgeIndex::end(), EdgeIndex::end()],
178        };
179        assert!(self.nodes.len() != crate::INVALID_USIZE);
180        let node_idx = NodeIndex::new(self.nodes.len() as u32);
181        self.nodes.push(node);
182        node_idx
183    }
184
185    /// Access the weight for node `a`.
186    ///
187    /// Also available with indexing syntax: `&graph[a]`.
188    pub fn node_weight(&self, a: NodeIndex) -> Option<&N> {
189        self.nodes.get(a.index()).map(|n| &n.weight)
190    }
191
192    /// Access the weight for edge `a`.
193    ///
194    /// Also available with indexing syntax: `&graph[a]`.
195    pub fn edge_weight(&self, a: EdgeIndex) -> Option<&E> {
196        self.edges.get(a.index()).map(|e| &e.weight)
197    }
198
199    /// Access the weight for edge `a` mutably.
200    ///
201    /// Also available with indexing syntax: `&mut graph[a]`.
202    pub fn edge_weight_mut(&mut self, a: EdgeIndex) -> Option<&mut E> {
203        self.edges.get_mut(a.index()).map(|e| &mut e.weight)
204    }
205
206    /// Add an edge from `a` to `b` to the graph, with its associated
207    /// data `weight`.
208    ///
209    /// Return the index of the new edge.
210    ///
211    /// Computes in **O(1)** time.
212    ///
213    /// **Panics** if any of the nodes don't exist.<br>
214    /// **Panics** if the Graph is at the maximum number of edges for its index
215    /// type (N/A if usize).
216    ///
217    /// **Note:** `Graph` allows adding parallel (“duplicate”) edges. If you want
218    /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
219    pub fn add_edge(&mut self, a: NodeIndex, b: NodeIndex, weight: E) -> EdgeIndex {
220        assert!(self.edges.len() != crate::INVALID_USIZE);
221        let edge_idx = EdgeIndex::new(self.edges.len() as u32);
222        let mut edge = Edge {
223            weight,
224            node: [a, b],
225            next: [EdgeIndex::end(); 2],
226        };
227        match index_twice(&mut self.nodes, a.index(), b.index()) {
228            Pair::None => panic!("Graph::add_edge: node indices out of bounds"),
229            Pair::One(an) => {
230                edge.next = an.next;
231                an.next[0] = edge_idx;
232                an.next[1] = edge_idx;
233            }
234            Pair::Both(an, bn) => {
235                // a and b are different indices
236                edge.next = [an.next[0], bn.next[1]];
237                an.next[0] = edge_idx;
238                bn.next[1] = edge_idx;
239            }
240        }
241        self.edges.push(edge);
242        edge_idx
243    }
244
245    /// Access the source and target nodes for `e`.
246    pub fn edge_endpoints(&self, e: EdgeIndex) -> Option<(NodeIndex, NodeIndex)> {
247        self.edges
248            .get(e.index())
249            .map(|ed| (ed.source(), ed.target()))
250    }
251
252    /// Remove `a` from the graph if it exists, and return its weight.
253    /// If it doesn't exist in the graph, return `None`.
254    ///
255    /// Apart from `a`, this invalidates the last node index in the graph
256    /// (that node will adopt the removed node index). Edge indices are
257    /// invalidated as they would be following the removal of each edge
258    /// with an endpoint in `a`.
259    ///
260    /// Computes in **O(e')** time, where **e'** is the number of affected
261    /// edges, including *n* calls to `.remove_edge()` where *n* is the number
262    /// of edges with an endpoint in `a`, and including the edges with an
263    /// endpoint in the displaced node.
264    pub fn remove_node(&mut self, a: NodeIndex) -> Option<N> {
265        self.nodes.get(a.index())?;
266        for d in &DIRECTIONS {
267            let k = *d as usize;
268
269            // Remove all edges from and to this node.
270            loop {
271                let next = self.nodes[a.index()].next[k];
272                if next == EdgeIndex::end() {
273                    break;
274                }
275                let ret = self.remove_edge(next);
276                debug_assert!(ret.is_some());
277                let _ = ret;
278            }
279        }
280
281        // Use swap_remove -- only the swapped-in node is going to change
282        // NodeIndex, so we only have to walk its edges and update them.
283
284        let node = self.nodes.swap_remove(a.index());
285
286        // Find the edge lists of the node that had to relocate.
287        // It may be that no node had to relocate, then we are done already.
288        let swap_edges = match self.nodes.get(a.index()) {
289            None => return Some(node.weight),
290            Some(ed) => ed.next,
291        };
292
293        // The swapped element's old index
294        let old_index = NodeIndex::new(self.nodes.len() as u32);
295        let new_index = a;
296
297        // Adjust the starts of the out edges, and ends of the in edges.
298        for &d in &DIRECTIONS {
299            let k = d as usize;
300            let mut edges = edges_walker_mut(&mut self.edges, swap_edges[k], d);
301            while let Some(curedge) = edges.next_edge() {
302                debug_assert!(curedge.node[k] == old_index);
303                curedge.node[k] = new_index;
304            }
305        }
306        Some(node.weight)
307    }
308
309    /// For edge `e` with endpoints `edge_node`, replace links to it,
310    /// with links to `edge_next`.
311    fn change_edge_links(
312        &mut self,
313        edge_node: [NodeIndex; 2],
314        e: EdgeIndex,
315        edge_next: [EdgeIndex; 2],
316    ) {
317        for &d in &DIRECTIONS {
318            let k = d as usize;
319            let node = match self.nodes.get_mut(edge_node[k].index()) {
320                Some(r) => r,
321                None => {
322                    debug_assert!(
323                        false,
324                        "Edge's endpoint dir={:?} index={:?} not found",
325                        d, edge_node[k]
326                    );
327                    return;
328                }
329            };
330            let fst = node.next[k];
331            if fst == e {
332                //println!("Updating first edge 0 for node {}, set to {}", edge_node[0], edge_next[0]);
333                node.next[k] = edge_next[k];
334            } else {
335                let mut edges = edges_walker_mut(&mut self.edges, fst, d);
336                while let Some(curedge) = edges.next_edge() {
337                    if curedge.next[k] == e {
338                        curedge.next[k] = edge_next[k];
339                        break; // the edge can only be present once in the list.
340                    }
341                }
342            }
343        }
344    }
345
346    /// Remove an edge and return its edge weight, or `None` if it didn't exist.
347    ///
348    /// Apart from `e`, this invalidates the last edge index in the graph
349    /// (that edge will adopt the removed edge index).
350    ///
351    /// Computes in **O(e')** time, where **e'** is the size of four particular edge lists, for
352    /// the vertices of `e` and the vertices of another affected edge.
353    pub fn remove_edge(&mut self, e: EdgeIndex) -> Option<E> {
354        // every edge is part of two lists,
355        // outgoing and incoming edges.
356        // Remove it from both
357        let (edge_node, edge_next) = match self.edges.get(e.index()) {
358            None => return None,
359            Some(x) => (x.node, x.next),
360        };
361        // Remove the edge from its in and out lists by replacing it with
362        // a link to the next in the list.
363        self.change_edge_links(edge_node, e, edge_next);
364        self.remove_edge_adjust_indices(e)
365    }
366
367    fn remove_edge_adjust_indices(&mut self, e: EdgeIndex) -> Option<E> {
368        // swap_remove the edge -- only the removed edge
369        // and the edge swapped into place are affected and need updating
370        // indices.
371        let edge = self.edges.swap_remove(e.index());
372        let swap = match self.edges.get(e.index()) {
373            // no element needed to be swapped.
374            None => return Some(edge.weight),
375            Some(ed) => ed.node,
376        };
377        let swapped_e = EdgeIndex::new(self.edges.len() as u32);
378
379        // Update the edge lists by replacing links to the old index by references to the new
380        // edge index.
381        self.change_edge_links(swap, swapped_e, [e, e]);
382        Some(edge.weight)
383    }
384
385    /// Return an iterator of all edges of `a`.
386    ///
387    /// - `Directed`: Outgoing edges from `a`.
388    /// - `Undirected`: All edges connected to `a`.
389    ///
390    /// Produces an empty iterator if the node doesn't exist.<br>
391    /// Iterator element type is `EdgeReference<E, Ix>`.
392    pub fn edges(&self, a: NodeIndex) -> Edges<'_, E> {
393        self.edges_directed(a, Direction::Outgoing)
394    }
395
396    /// Return an iterator of all edges of `a`, in the specified direction.
397    ///
398    /// - `Directed`, `Outgoing`: All edges from `a`.
399    /// - `Directed`, `Incoming`: All edges to `a`.
400    /// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each
401    ///   edge.
402    /// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each
403    ///   edge.
404    ///
405    /// Produces an empty iterator if the node `a` doesn't exist.<br>
406    /// Iterator element type is `EdgeReference<E, Ix>`.
407    pub fn edges_directed(&self, a: NodeIndex, dir: Direction) -> Edges<'_, E> {
408        Edges {
409            skip_start: a,
410            edges: &self.edges,
411            direction: dir,
412            next: match self.nodes.get(a.index()) {
413                None => [EdgeIndex::end(), EdgeIndex::end()],
414                Some(n) => n.next,
415            },
416        }
417    }
418
419    /*
420    /// Return an iterator over all the edges connecting `a` and `b`.
421    ///
422    /// - `Directed`: Outgoing edges from `a`.
423    /// - `Undirected`: All edges connected to `a`.
424    ///
425    /// Iterator element type is `EdgeReference<E, Ix>`.
426    pub fn edges_connecting(&self, a: NodeIndex, b: NodeIndex) -> EdgesConnecting<E, Ty, Ix> {
427        EdgesConnecting {
428            target_node: b,
429            edges: self.edges_directed(a, Direction::Outgoing),
430            ty: PhantomData,
431        }
432    }
433    */
434
435    /// Lookup an edge from `a` to `b`.
436    ///
437    /// Computes in **O(e')** time, where **e'** is the number of edges
438    /// connected to `a` (and `b`, if the graph edges are undirected).
439    pub fn find_edge(&self, a: NodeIndex, b: NodeIndex) -> Option<EdgeIndex> {
440        self.find_edge_undirected(a, b).map(|(ix, _)| ix)
441    }
442
443    /// Lookup an edge between `a` and `b`, in either direction.
444    ///
445    /// If the graph is undirected, then this is equivalent to `.find_edge()`.
446    ///
447    /// Return the edge index and its directionality, with `Outgoing` meaning
448    /// from `a` to `b` and `Incoming` the reverse,
449    /// or `None` if the edge does not exist.
450    pub fn find_edge_undirected(
451        &self,
452        a: NodeIndex,
453        b: NodeIndex,
454    ) -> Option<(EdgeIndex, Direction)> {
455        match self.nodes.get(a.index()) {
456            None => None,
457            Some(node) => self.find_edge_undirected_from_node(node, b),
458        }
459    }
460
461    fn find_edge_undirected_from_node(
462        &self,
463        node: &Node<N>,
464        b: NodeIndex,
465    ) -> Option<(EdgeIndex, Direction)> {
466        for &d in &DIRECTIONS {
467            let k = d as usize;
468            let mut edix = node.next[k];
469            while let Some(edge) = self.edges.get(edix.index()) {
470                if edge.node[1 - k] == b {
471                    return Some((edix, d));
472                }
473                edix = edge.next[k];
474            }
475        }
476        None
477    }
478
479    /// Access the internal node array.
480    pub fn raw_nodes(&self) -> &[Node<N>] {
481        &self.nodes
482    }
483
484    /// Access the internal edge array.
485    pub fn raw_edges(&self) -> &[Edge<E>] {
486        &self.edges
487    }
488
489    /// Accessor for data structure internals: the first edge in the given direction.
490    pub fn first_edge(&self, a: NodeIndex, dir: Direction) -> Option<EdgeIndex> {
491        match self.nodes.get(a.index()) {
492            None => None,
493            Some(node) => {
494                let edix = node.next[dir as usize];
495                if edix == EdgeIndex::end() {
496                    None
497                } else {
498                    Some(edix)
499                }
500            }
501        }
502    }
503
504    /// Accessor for data structure internals: the next edge for the given direction.
505    pub fn next_edge(&self, e: EdgeIndex, dir: Direction) -> Option<EdgeIndex> {
506        match self.edges.get(e.index()) {
507            None => None,
508            Some(node) => {
509                let edix = node.next[dir as usize];
510                if edix == EdgeIndex::end() {
511                    None
512                } else {
513                    Some(edix)
514                }
515            }
516        }
517    }
518}
519
520struct EdgesWalkerMut<'a, E: 'a> {
521    edges: &'a mut [Edge<E>],
522    next: EdgeIndex,
523    dir: Direction,
524}
525
526fn edges_walker_mut<E>(
527    edges: &mut [Edge<E>],
528    next: EdgeIndex,
529    dir: Direction,
530) -> EdgesWalkerMut<'_, E> {
531    EdgesWalkerMut { edges, next, dir }
532}
533
534impl<E> EdgesWalkerMut<'_, E> {
535    fn next_edge(&mut self) -> Option<&mut Edge<E>> {
536        self.next().map(|t| t.1)
537    }
538
539    fn next(&mut self) -> Option<(EdgeIndex, &mut Edge<E>)> {
540        let this_index = self.next;
541        let k = self.dir as usize;
542        match self.edges.get_mut(self.next.index()) {
543            None => None,
544            Some(edge) => {
545                self.next = edge.next[k];
546                Some((this_index, edge))
547            }
548        }
549    }
550}
551
552/// Iterator over the edges of from or to a node
553pub struct Edges<'a, E: 'a> {
554    /// starting node to skip over
555    skip_start: NodeIndex,
556    edges: &'a [Edge<E>],
557
558    /// Next edge to visit.
559    next: [EdgeIndex; 2],
560
561    /// For directed graphs: the direction to iterate in
562    /// For undirected graphs: the direction of edges
563    direction: Direction,
564}
565
566impl<'a, E> Iterator for Edges<'a, E> {
567    type Item = EdgeReference<'a, E>;
568
569    fn next(&mut self) -> Option<Self::Item> {
570        //      type        direction    |    iterate over    reverse
571        //                               |
572        //    Directed      Outgoing     |      outgoing        no
573        //    Directed      Incoming     |      incoming        no
574        //   Undirected     Outgoing     |        both       incoming
575        //   Undirected     Incoming     |        both       outgoing
576
577        // For iterate_over, "both" is represented as None.
578        // For reverse, "no" is represented as None.
579        let (iterate_over, _reverse) = (None, Some(self.direction.opposite()));
580
581        if iterate_over.unwrap_or(Direction::Outgoing) == Direction::Outgoing {
582            let i = self.next[0].index();
583            if let Some(Edge {
584                node: _node,
585                weight,
586                next,
587            }) = self.edges.get(i)
588            {
589                self.next[0] = next[0];
590                return Some(EdgeReference {
591                    index: EdgeIndex(i as u32),
592                    // node: if reverse == Some(Direction::Outgoing) {
593                    //     swap_pair(*node)
594                    // } else {
595                    //     *node
596                    // },
597                    weight,
598                });
599            }
600        }
601
602        if iterate_over.unwrap_or(Direction::Incoming) == Direction::Incoming {
603            while let Some(Edge { node, weight, next }) = self.edges.get(self.next[1].index()) {
604                let edge_index = self.next[1];
605                self.next[1] = next[1];
606                // In any of the "both" situations, self-loops would be iterated over twice.
607                // Skip them here.
608                if iterate_over.is_none() && node[0] == self.skip_start {
609                    continue;
610                }
611
612                return Some(EdgeReference {
613                    index: edge_index,
614                    // node: if reverse == Some(Direction::Incoming) {
615                    //     swap_pair(*node)
616                    // } else {
617                    //     *node
618                    // },
619                    weight,
620                });
621            }
622        }
623
624        None
625    }
626}
627
628// fn swap_pair<T>(mut x: [T; 2]) -> [T; 2] {
629//     x.swap(0, 1);
630//     x
631// }
632
633impl<E> Clone for Edges<'_, E> {
634    fn clone(&self) -> Self {
635        Edges {
636            skip_start: self.skip_start,
637            edges: self.edges,
638            next: self.next,
639            direction: self.direction,
640        }
641    }
642}
643
644/// Index the `Graph` by `NodeIndex` to access node weights.
645///
646/// **Panics** if the node doesn't exist.
647impl<N, E> Index<NodeIndex> for Graph<N, E> {
648    type Output = N;
649    fn index(&self, index: NodeIndex) -> &N {
650        &self.nodes[index.index()].weight
651    }
652}
653
654/// Index the `Graph` by `NodeIndex` to access node weights.
655///
656/// **Panics** if the node doesn't exist.
657impl<N, E> IndexMut<NodeIndex> for Graph<N, E> {
658    fn index_mut(&mut self, index: NodeIndex) -> &mut N {
659        &mut self.nodes[index.index()].weight
660    }
661}
662
663/// Index the `Graph` by `EdgeIndex` to access edge weights.
664///
665/// **Panics** if the edge doesn't exist.
666impl<N, E> Index<EdgeIndex> for Graph<N, E> {
667    type Output = E;
668    fn index(&self, index: EdgeIndex) -> &E {
669        &self.edges[index.index()].weight
670    }
671}
672
673/// Index the `Graph` by `EdgeIndex` to access edge weights.
674///
675/// **Panics** if the edge doesn't exist.
676impl<N, E> IndexMut<EdgeIndex> for Graph<N, E> {
677    fn index_mut(&mut self, index: EdgeIndex) -> &mut E {
678        &mut self.edges[index.index()].weight
679    }
680}
681
682/// Reference to a `Graph` edge.
683#[derive(Debug)]
684pub struct EdgeReference<'a, E: 'a> {
685    index: EdgeIndex,
686    // node: [NodeIndex; 2],
687    weight: &'a E,
688}
689
690impl<'a, E: 'a> EdgeReference<'a, E> {
691    #[inline]
692    pub fn id(&self) -> EdgeIndex {
693        self.index
694    }
695
696    #[inline]
697    pub fn weight(&self) -> &'a E {
698        self.weight
699    }
700}
701
702impl<E> Clone for EdgeReference<'_, E> {
703    fn clone(&self) -> Self {
704        *self
705    }
706}
707
708impl<E> Copy for EdgeReference<'_, E> {}
709
710impl<E> PartialEq for EdgeReference<'_, E>
711where
712    E: PartialEq,
713{
714    fn eq(&self, rhs: &Self) -> bool {
715        self.index == rhs.index && self.weight == rhs.weight
716    }
717}