1 // Copyright (C) 2012-2019 The VPaint Developers. 2 // See the COPYRIGHT file at the top-level directory of this distribution 3 // and at https://github.com/dalboris/vpaint/blob/master/COPYRIGHT 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #ifndef SMARTINSTANTEDGESET_H 18 #define SMARTINSTANTEDGESET_H 19 20 #include "KeyEdge.h" 21 #include "ProperPath.h" 22 #include "ProperCycle.h" 23 #include "CycleHelper.h" 24 #include "CellList.h" 25 26 namespace VectorAnimationComplex 27 { 28 29 // Assumes edgeSet is connected 30 class SmartConnectedKeyEdgeSet 31 { 32 public: 33 SmartConnectedKeyEdgeSet(const KeyEdgeSet & edgeSet); 34 35 // Get type 36 enum EdgeSetType { 37 EMPTY, 38 39 CLOSED_EDGE, // A single closed edge 40 41 OPEN_EDGE_PATH, // A single open edge with start() != end() 42 OPEN_EDGE_LOOP, // A single open edge with start() == end() 43 44 SIMPLE_PATH, // N >= 2 consecutive halfedges with h[0].start() != h[N-1].end() 45 // (i != j) => (h[i].edge() != h[j].edge()) 46 // (i != j) => (h[i].start() != h[j].start()) 47 SIMPLE_LOOP, // N >= 2 consecutive halfedges with h[0].startVertex() == h[N-1].endVertex() 48 // (i != j) => (h[i].edge() != h[j].edge()) 49 // (i != j) => (h[i].start() != h[j].start()) 50 51 PATH_LOOP_DECOMPOSITION, // None of the above, but the edges can be partitionned 52 // into simple paths and simple loops such that its intersection 53 // graph is a tree. The intersection graph is defined as: 54 // - each (edge-disjoint) path or loop is a node 55 // - each pair of nodes n1 and n2 are connected by exactly K edges, 56 // where K is the number of vertices in the intersection between n1 and n2 57 58 GENERAL // None of the above 59 }; 60 EdgeSetType type() const; 61 62 // Get decomposition 63 64 // Edge 65 // If type() is not one of: 66 // - CLOSED_EDGE 67 // - OPEN_EDGE_PATH 68 // - OPEN_EDGE_LOOP 69 // Then it returns a NULL pointer 70 KeyEdge * edge() const; 71 72 // Simple path 73 // If type() is not one of: 74 // - OPEN_EDGE_PATH 75 // - SIMPLE_PATH 76 // Then it returns an invalid path 77 ProperPath path() const; 78 79 // Simple loop 80 // If type() is not one of: 81 // - CLOSED_EDGE 82 // - OPEN_EDGE_LOOP 83 // - SIMPLE_LOOP 84 // Then it returns an invalid loop 85 ProperCycle loop() const; 86 87 // Path-loop decomposition 88 // If type() is not one of: 89 // - CLOSED_EDGE 90 // - OPEN_EDGE_PATH 91 // - OPEN_EDGE_LOOP 92 // - SIMPLE_PATH 93 // - SIMPLE_LOOP 94 // - PATH_LOOP_DECOMPOSITION 95 // Then it returns an invalid hole 96 CycleHelper hole() const; 97 98 // In any cases, you can still get the original set of edges 99 KeyEdgeSet edgeSet() const; 100 101 private: 102 KeyEdgeSet edgeSet_; 103 ProperPath path_; 104 ProperCycle loop_; 105 CycleHelper hole_; 106 }; 107 108 class SmartKeyEdgeSet 109 { 110 public: 111 SmartKeyEdgeSet(const KeyEdgeSet & edgeSet); 112 113 int numConnectedComponents() const; 114 SmartConnectedKeyEdgeSet & operator [] (int i); 115 116 private: 117 KeyEdgeSet edgeSet_; 118 QList<SmartConnectedKeyEdgeSet> connectedComponents_; 119 }; 120 121 } 122 123 #endif // SMARTINSTANTEDGESET_H 124