1 // Copyright 2018 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS-IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 
16 // Converted to D:  madric@gmail.com (Vijay Nayar)
17 
18 module s2.shapeutil.edge_iterator;
19 
20 import s2.s2shape;
21 import s2.s2shape_index;
22 import s2.shapeutil.shape_edge_id;
23 
24 import std.format;
25 
26 /**
27  * An iterator that advances through all edges in an S2ShapeIndex.
28  *
29  * Example usage:
30  *
31  * for (EdgeIterator it(index); !it.Done(); it.Next()) {
32  *   auto edge = it.edge();
33  *   //...
34  * }
35  */
36 struct EdgeIterator {
37 public:
38   this(S2ShapeIndex index) {
39     _index = index;
40     _shapeId = -1;
41     _numEdges = 0;
42     _edgeId = -1;
43     next();
44   }
45 
46   // Returns the current shape id.
47   int shapeId() const {
48     return _shapeId;
49   }
50 
51   // Returns the current edge id.
52   int edgeId() const {
53     return _edgeId;
54   }
55 
56   // Returns the current (shape_id, edge_id).
57   ShapeEdgeId shapeEdgeId() const {
58     return ShapeEdgeId(_shapeId, _edgeId);
59   }
60 
61   // Returns the current edge.
62   S2Shape.Edge edge() const
63   in {
64     assert(!done());
65   } do {
66     return _index.shape(_shapeId).edge(_edgeId);
67   }
68 
69   // Returns true if there are no more edges in the index.
70   bool done() const {
71     return shapeId() >= _index.numShapeIds();
72   }
73 
74   // Advances to the next edge.
75   void next() {
76     while (++_edgeId >= _numEdges) {
77       if (++_shapeId >= _index.numShapeIds()) break;
78       S2Shape shape = _index.shape(_shapeId);
79       _numEdges = (shape is null) ? 0 : shape.numEdges();
80       _edgeId = -1;
81     }
82   }
83 
84   bool opEquals(in EdgeIterator v) const {
85     return _index is v._index && _shapeId == v._shapeId && _edgeId == v._edgeId;
86   }
87 
88   string debugString() const {
89     return format("(shape=%d, edge=%d)", _shapeId, _edgeId);
90   }
91 
92  private:
93   S2ShapeIndex _index;
94   int _shapeId;
95   int _numEdges;
96   int _edgeId;
97 }