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 ANIMATEDCYCLE_H
18 #define ANIMATEDCYCLE_H
19 
20 #include "Cell.h"
21 #include "CellList.h"
22 #include "../TimeDef.h"
23 #include "Eigen.h"
24 #include <QList>
25 
26 ////////////// Forward declare global serialization operators /////////////////
27 
28 namespace VectorAnimationComplex { class AnimatedCycle; }
29 QTextStream & operator<<(QTextStream &, const VectorAnimationComplex::AnimatedCycle &);
30 QTextStream & operator>>(QTextStream &, VectorAnimationComplex::AnimatedCycle &);
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 
34 namespace VectorAnimationComplex
35 {
36 
37 // A node of the animated cycle. Note: it is the AnimatedCycle responsibility
38 // to ensure consistency.
39 class AnimatedCycleNode
40 {
41 public:
42     AnimatedCycleNode(Cell * cell);
43 
44     // Type
45     enum NodeType
46     {
47         InvalidNode,
48         KeyVertexNode,
49         KeyOpenEdgeNode,
50         KeyClosedEdgeNode,
51         InbetweenVertexNode,
52         InbetweenOpenEdgeNode,
53         InbetweenClosedEdgeNode
54     };
55     NodeType nodeType() const;
56     enum CycleType
57     {
58         InvalidCycle,
59         SteinerCycle,
60         SimpleCycle,
61         NonSimpleCycle
62     };
63     CycleType cycleType(Time time) const;
64 
65     // Setters
66     void setCell(Cell * cell);
67     void setPrevious(AnimatedCycleNode * node);
68     void setNext(AnimatedCycleNode * node);
69     void setBefore(AnimatedCycleNode * node);
70     void setAfter(AnimatedCycleNode * node);
71 
72     // Getters
73     Cell * cell() const;
74     AnimatedCycleNode * previous() const;
75     AnimatedCycleNode * next() const;
76     AnimatedCycleNode * before() const;
77     AnimatedCycleNode * after() const;
78 
79     // Spatial cycling
80     AnimatedCycleNode * previous(Time time) const;
81     AnimatedCycleNode * next(Time time) const;
82 
83     // For halfedges
84     bool side() const;
85     void setSide(bool side);
86 
87 private:
88     Cell * cell_;
89     AnimatedCycleNode * previous_;
90     AnimatedCycleNode * next_;
91     AnimatedCycleNode * before_;
92     AnimatedCycleNode * after_;
93     bool side_;
94 };
95 
96 class AnimatedCycle
97 {
98 public:
99     AnimatedCycle();
100     AnimatedCycle(AnimatedCycleNode * first); // It's the caller responsibility to allocate and create the nodes
101                                               // node ownership is transfered to the cycle (unless you know what you're doing)
102     AnimatedCycle(const AnimatedCycle & other);
103     AnimatedCycle & operator=(const AnimatedCycle & other);
104     ~AnimatedCycle();
105 
106     // First node
107     AnimatedCycleNode  * first() const;
108     void setFirst(AnimatedCycleNode  * node);
109 
110     // Find a node at particular time
111     AnimatedCycleNode  * getNode(Time time);
112 
113     // Find all noded refering to particular cell
114     QSet<AnimatedCycleNode*> getNodes(Cell * cell);
115 
116     // Find all nodes
117     QSet<AnimatedCycleNode*> nodes() const; // Note: only return nodes connected to first_ (i.e., may not work if cycle is invalid)
118 
119     // Find all cells
120     CellSet cells() const;
121     KeyCellSet beforeCells() const; // temporal boundary of n->before == NULL
122     KeyCellSet afterCells() const; // temporal boundary of n->after == NULL
123 
124     // Geometry
125     void sample(Time time, QList<Eigen::Vector2d> & out);
126 
127     // Replace pointed vertex
128     void replaceVertex(KeyVertex * oldVertex, KeyVertex * newVertex);
129     void replaceHalfedge(const KeyHalfedge & oldHalfedge, const KeyHalfedge & newHalfedge);
130     void replaceEdges(KeyEdge * oldEdge, const KeyEdgeList & newEdges);
131     void replaceInbetweenVertex(InbetweenVertex * sv, // old
132                                 InbetweenVertex * sv1, KeyVertex * kv, InbetweenVertex * sv2); // new
133     void replaceInbetweenEdge(InbetweenEdge * se, // old
134                                 InbetweenEdge * se1, KeyEdge *ke, InbetweenEdge * se2); // new
135 
136     // serialization and copy
137     void remapPointers(VAC * newVAC);
138     friend QTextStream & ::operator<<(QTextStream & out, const AnimatedCycle & cycle);
139     friend QTextStream & ::operator>>(QTextStream & in, AnimatedCycle & cycle);
140     void convertTempIdsToPointers(VAC * vac);
141     QString toString() const;
142     void fromString(const QString & str);
143 
144     // Methods that can make the animated cycle invalid. Use with caution
145 
146 
147 private:
148     void clear();
149     void copyFrom(const AnimatedCycle & other);
150 
151     AnimatedCycleNode * first_;
152 
153     // for unserialization
154     friend class InbetweenFace;
155     struct TempNode { int cell, previous, next, before, after; bool side; };
156     QList<TempNode> tempNodes_;
157 };
158 
159 } // end namespace VectorAnimationComplex
160 
161 #endif // ANIMATEDCYCLE_H
162