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 VAC_VAC_H
18 #define VAC_VAC_H
19 
20 #include <QSet>
21 #include <QMap>
22 #include <QColor>
23 
24 #include "../SceneObject.h"
25 
26 #include "ForwardDeclaration.h"
27 #include "CellList.h"
28 #include "Cell.h"
29 #include "ZOrderedCells.h"
30 #include "Eigen.h"
31 #include "TransformTool.h"
32 #include "EdgeSample.h"
33 
34 #include "../View3DSettings.h"
35 
36 class Scene;
37 class XmlStreamWriter;
38 class XmlStreamReader;
39 
40 namespace VectorAnimationComplex
41 {
42 
43 class EdgeGeometry;
44 class LinearSpline;
45 
46 class Operator;
47 class ProperCycle;
48 class Cycle;
49 class AnimatedCycle;
50 class Path;
51 class AnimatedVertex;
52 class KeyHalfedge;
53 class PreviewKeyFace;
54 class BoundingBox;
55 
56 class VAC: public SceneObject
57 {
58     Q_OBJECT
59 
60 public:
61     // Constructors and Destructor
62     VAC();
63     VAC(QTextStream & in);
64     ~VAC();
65     VAC * clone();
66     QString stringType();
67     void clear();
68 
69     // Serialization / Unserialization
70     void write(XmlStreamWriter & xml);
71     void read(XmlStreamReader & xml);
72 
73     // Initializations
74     void initNonCopyable();
75     void initCopyable();
76 
77     // VAC extraction and insertion
78     QMap<int, int> import(VAC * other, bool selectImportedCells = false); // insert a copy of other inside this
79     VAC * subcomplex(const CellSet & subcomplexCells); // Create a new VAC whose cells are cells
80 
81     // Drawing
82     void draw(Time time, ViewSettings & viewSettings);
83     void drawPick(Time time, ViewSettings & viewSettings);
84     void drawInbetweenCells3D(View3DSettings & viewSettings);
85     void drawOneFrame3D(Time time, View3DSettings & viewSettings, ViewSettings & view2DSettings, bool drawAsTopo = false);
86     void drawAllFrames3D(View3DSettings & viewSettings, ViewSettings & view2DSettings);
87     void drawKeyCells3D(View3DSettings & viewSettings, ViewSettings & view2DSettings);
88     void drawPick3D(View3DSettings & viewSettings);
89 
90     // Selecting and Highlighting
91     void setHoveredObject(Time time, int id);
92     void setNoHoveredObject();
93     void select(Time time, int id);
94     void deselect(Time time, int id);
95     void toggle(Time time, int id);
96     void deselectAll(Time time);
97     void deselectAll();
98     void invertSelection();
99 
100     // Get higlighted and selected state
101     Cell * hoveredCell() const;
102     const CellSet & selectedCells() const;
103     int numSelectedCells() const;
104 
105     // Get hovered transform widget id
106     int hoveredTransformWidgetId() const;
107 
108     // Modify highligthed and seleted state
109     void setHoveredCell(Cell * cell);
110     void setNoHoveredCell();
111     void addToSelection(Cell * cell, bool emitSignal = true);
112     void addToSelection(const CellSet & cells, bool emitSignal = true);
113     void setSelectedCell(Cell * cell, bool emitSignal = true);
114     void setSelectedCells(const CellSet & cells, bool emitSignal = true);
115     void removeFromSelection(Cell * cell, bool emitSignal = true);
116     void removeFromSelection(const CellSet & cells, bool emitSignal = true);
117     void toggleSelection(Cell * cell, bool emitSignal = true);
118     void toggleSelection(const CellSet & cells, bool emitSignal = true);
119     void informTimelineOfSelection();
120 
121     // Get element by ID: returns NULL if invalid ID or type.
122     Cell * getCell(int id);
123     KeyVertex * getKeyVertex(int id);
124     KeyEdge * getKeyEdge(int id);
125     KeyFace * getKeyFace(int id);
126     InbetweenVertex * getInbetweenVertex(int id);
127     InbetweenEdge * getInbetweenEdge(int id);
128     InbetweenFace * getInbetweenFace(int id);
129 
130     // Get all cells of a given type
131     CellSet cells();
132     VertexCellList vertices();
133     EdgeCellList edges();
134     FaceCellList faces();
135     KeyEdgeList instantEdges();
136     KeyVertexList instantVertices();
137 
138     // Get all cells of a given type existing at a given time
139     CellSet cells(Time time);
140     EdgeCellList edges(Time time);
141     KeyEdgeList instantEdges(Time time);
142     KeyVertexList instantVertices(Time time);
143 
144     // Get all cells, ordered
145     const ZOrderedCells & zOrdering() const;
146 
147     // Populate MainWindow toolbar (called once, when launching application)
148     static void populateToolBar(QToolBar * toolBar, Scene * scene);
149 
150     /////////////////////////////////////////////////////////////////
151     //                 MOUSE PMR ACTIONS                           //
152 
153     // -- Drag and drop --
154     void prepareDragAndDrop(double x0, double y0, Time time);
155     void performDragAndDrop(double x, double y);
156     void completeDragAndDrop();
157 
158     // -- Transform selection --
159     void beginTransformSelection(double x0, double y0, Time time);
160     void continueTransformSelection(double x, double y);
161     void endTransformSelection();
162 
163     // -- Temporal Drag and drop --
164     void prepareTemporalDragAndDrop(Time t0);
165     void performTemporalDragAndDrop(Time t);
166     void completeTemporalDragAndDrop();
167 
168     // -- Rectangle of selection --
169     void beginRectangleOfSelection(double x, double y, Time time);
170     void continueRectangleOfSelection(double x, double y);
171     void setSelectedCellsFromRectangleOfSelection();
172     void setSelectedCellsFromRectangleOfSelection(Qt::KeyboardModifiers modifiers);
173     void endRectangleOfSelection();
174 
175     // -- Sketch --
176     void beginSketchEdge(double x, double y, double w, Time time);
177     void continueSketchEdge(double x, double y, double w);
178     void endSketchEdge();
179 
180     // -- Sculpt --
181     void updateSculpt(double x, double y, Time time);
182     // Deform
183     void beginSculptDeform(double x, double y);
184     void continueSculptDeform(double x, double y);
185     void endSculptDeform();
186     // Change edge width
187     void beginSculptEdgeWidth(double x, double y);
188     void continueSculptEdgeWidth(double x, double y);
189     void endSculptEdgeWidth();
190     // Smooth
191     void beginSculptSmooth(double x, double y);
192     void continueSculptSmooth(double x, double y);
193     void endSculptSmooth();
194 
195     // -- Cut Face --
196     void beginCutFace(double x, double y, double w, KeyVertex * startVertex);
197     void continueCutFace(double x, double y, double w);
198     void endCutFace(KeyVertex * endVertex);
199 
200     /////////////////////////////////////////////////////////////////
201     //                 MOUSE CLIC ACTIONS                          //
202 
203     // -- Cut edge --
204     // This is actually more generic: if no edge is highlighted, it still creates a vertex
205     // It is more like a cutAt(x,y);
206     KeyVertex * split(double x, double y, Time time, bool interactive = true);
207 
208     // -- Paint Bucket tool --
209     // paint() returns the painted cell, if any. Might be an existing
210     // cell that has been re-colored, or a new face that has been created
211     void updateToBePaintedFace(double x, double y, Time time);
212     Cell * paint(double x, double y, Time time);
213 
214     /////////////////////////////////////////////////////////////////
215     //         SELECTION (MOUSE CLIC ACTIONS)                      //
216 
217 public slots:
218     void selectAll(bool emitSignal = true);
219     void selectAllAtTime(Time time, bool emitSignal = true);
220     void selectConnected(bool emitSignal = true);
221     void selectClosure(bool emitSignal = true);
222     void selectVertices(bool emitSignal = true);
223     void selectEdges(bool emitSignal = true);
224     void selectFaces(bool emitSignal = true);
225     void deselectVertices(bool emitSignal = true);
226     void deselectEdges(bool emitSignal = true);
227     void deselectFaces(bool emitSignal = true);
228 
229 
230     /////////////////////////////////////////////////////////////////
231     //     ONE-SHOT KEYBOARD OR INSTANT TOOL ACTIONS               //
232 
233 public slots:
234     void test();
235     void deleteSelectedCells();
236     void smartDelete();
237     void createFace();
238     void addCyclesToFace();
239     void removeCyclesFromFace();
240     void changeColor();
241     void raise();
242     void lower();
243     void raiseToTop();
244     void lowerToBottom();
245     void altRaise();
246     void altLower();
247     void altRaiseToTop();
248     void altLowerToBottom();
249     void changeEdgeWidth();
250     void glue();
251     void unglue();
252     void uncut();
253     void cut(VAC* & clipboard);
254     void copy(VAC* & clipboard);
255     void paste(VAC* & clipboard);
256     void resetCellsToConsiderForCutting();
257     void updateCellsToConsiderForCutting();
258     // -- animation --
259     void inbetweenSelection();
260     void keyframeSelection();
261     void motionPaste(VAC* & clipboard);
262 
263 public:
264     // Safely create cells given a valid boundary.
265     // These methods allocate the new cell and insert it in the VAC
266     // todo: move in private. // <- obsolete comment?
267     //       the only issue now is that InbetweenEdge uses newInbetweenVertex() to
268     //       automagically connect provided temporal boundary. But this has to be changed:
269     //       it is the responsibility of VAC to create the appropriate complete boundary
270     //       of any cell, and to give it to the constructor of the cell. Helpers boundary can
271     //       include algorithms if needed, but cells constructor must have valid boundary already
272     //       specified.
273     KeyVertex * newKeyVertex(Time time, const Eigen::Vector2d & pos = Eigen::Vector2d(0,0));
274     KeyVertex * newKeyVertex(Time time, const EdgeSample& sample);
275     KeyEdge * newKeyEdge(Time time,
276                KeyVertex * left,
277                KeyVertex * right,
278                EdgeGeometry * geometry = 0, double width = 0); // if geometry = 0, create a straight line
279     KeyEdge * newKeyEdge(Time time,
280                EdgeGeometry * geometry = 0);
281     InbetweenVertex * newInbetweenVertex(
282                KeyVertex * before = 0,
283                KeyVertex * after = 0);
284     InbetweenEdge * newInbetweenEdge(
285             const Path & beforePath,
286             const Path & afterPath,
287             const AnimatedVertex & startAnimatedVertex,
288             const AnimatedVertex & endAnimatedVertex);
289     InbetweenEdge * newInbetweenEdge(
290             const Cycle & beforeCycle,
291             const Cycle & afterCycle);
292     KeyFace * newKeyFace(const Time & t);
293     KeyFace * newKeyFace(const Cycle & cycle);
294     KeyFace * newKeyFace(const QList<Cycle> & cycles);
295     InbetweenFace * newInbetweenFace(const QList<AnimatedCycle> & cycles,
296                                      const QSet<KeyFace*> & beforeFaces,
297                                      const QSet<KeyFace*> & afterFaces);
298 
299 
300     // safely delete objects
301     void deleteCells(const QSet<int>  & cellIds);
302     void deleteCells(const CellSet & cells);
303     void deleteCell(Cell * cell);
304     void smartDeleteCell(Cell * cell);
305     bool atomicSimplifyAtCell(Cell * cell);
306     bool simplifyAtCell(Cell * cell);
307 
308     // Check the invariants of the VAC
309     bool check() const;
310     bool checkContains(const Cell * c) const;
311 
312 
313 protected:
314     // Save & Load
315     void save_(QTextStream & out);
316     virtual void exportSVG_(Time t, QTextStream & out);
317     void read2ndPass_();
318 
319 signals:
320     void selectionChanged();
321 
322 private:
323     // Trusting operators
324     friend class Operator;
325 
326     // All cells in vac, accessible by ID
327     QMap<int, Cell*> cells_;
328     void removeCell_(Cell * cell);
329     void insertCell_(Cell * cell);
330     void insertCellLast_(Cell * cell);
331 
332     // Managing IDs
333     int getAvailableID();
334     void deleteAllCells();
335     void setMaxID_(int maxID);
336     int maxID_;
337 
338     // User interactivity
339     Time timeInteractivity_;
340 
341     // Rectangle of selection
342     double rectangleOfSelectionStartX_;
343     double rectangleOfSelectionStartY_;
344     double rectangleOfSelectionEndX_;
345     double rectangleOfSelectionEndY_;
346     bool drawRectangleOfSelection_;
347     CellSet rectangleOfSelectionSelectedBefore_;
348     CellSet cellsInRectangleOfSelection_;
349 
350     // Drawing a new stroke
351     void insertSketchedEdgeInVAC();
352     void insertSketchedEdgeInVAC(double tolerance, bool useFaceToConsiderForCutting = true);
353     void drawSketchedEdge(Time time, ViewSettings & viewSettings) const;
354     void drawTopologySketchedEdge(Time time, ViewSettings & viewSettings) const;
355     LinearSpline * sketchedEdge_;
356     double ds_;
357     KeyFace * hoveredFaceOnMousePress_;
358     KeyFace * hoveredFaceOnMouseRelease_;
359     KeyFaceSet hoveredFacesOnMouseMove_;
360     KeyFaceSet facesToConsiderForCutting_;
361     KeyEdgeSet edgesToConsiderForCutting_;
362 
363     // Create a face, or inserting/removing cycles
364     QList<Cycle> createFace_computeCycles();
365 
366     // Splitting
367     struct SplitInfo
368     {
369         KeyEdge * oldEdge;
370         KeyEdgeList newEdges;
371         KeyVertexList newVertices;
372     };
373     KeyVertex * cutFaceAtVertex_(KeyFace * face, double x, double y);
374     KeyVertex * cutEdgeAtVertex_(KeyEdge * edge, double s);
375     SplitInfo cutEdgeAtVertices_(KeyEdge * edgeToSplit, const std::vector<double> & splitValues);
376 
377     // Gluing
378     void glue_(KeyVertex * v1, KeyVertex * v2);
379     void glue_(KeyEdge * e1, KeyEdge * e2);
380     void glue_(const KeyHalfedge & h1, const KeyHalfedge & h2);
381 
382     // Ungluing
383     int nUses_(KeyVertex * v);
384     int nUses_(KeyEdge * e);
385     void unglue_(KeyVertex * v);
386     void unglue_(KeyEdge * e);
387 
388     // Uncutting
389     bool uncut_(KeyVertex * v);
390     bool uncut_(KeyEdge * e);
391 
392     // Smart deleting
393     void smartDelete_(const CellSet & cellsToDelete);
394 
395     // Cut a face along an edge
396     KeyVertex * cut_startVertex_;
397     struct CutFaceFeedback
398     {
399         KeyFaceSet newFaces;
400         KeyFaceSet deletedFaces;
401     };
402     bool cutFace_(KeyFace * f, KeyEdge * edge, CutFaceFeedback * feedback = 0);
403 
404     // Inbetweening
405     InbetweenVertex * inbetweenVertices_(KeyVertex * v1, KeyVertex * v2);
406     InbetweenEdge * inbetweenEdges_(KeyEdge * e1, KeyEdge * e2);
407 
408     // Keyframing
409     KeyCellSet keyframe_(const CellSet & cells, Time time);
410     KeyVertex * keyframe_(InbetweenVertex * svertex, Time time);
411     KeyEdge * keyframe_(InbetweenEdge * sedge, Time time);
412     KeyFace * keyframe_(InbetweenFace * sface, Time time);
413 
414     // Sculpting
415     KeyEdge * sculptedEdge_;
416 
417     // Drag and drop
418     KeyVertexSet draggedVertices_;
419     KeyEdgeSet draggedEdges_;
420     double x0_, y0_;
421 
422     // Temporal drag and drop
423     KeyCellSet draggedKeyCells_;
424     QMap<KeyCell*, Time> draggedKeyCellTime_;
425     Time t0_;
426     Time deltaTMin_;
427     Time deltaTMax_;
428 
429     // Painting
430     PreviewKeyFace * toBePaintedFace_;
431 
432     // Cut-Copy-Paste
433     Time timeCopy_;
434 
435     // Selecting and highlighting
436     int hoveredTransformWidgetId_;
437     Cell * hoveredCell_;
438     CellSet selectedCells_;
439 
440     // Z-layering
441     ZOrderedCells zOrdering_;
442 
443     // Smart aggregation of signals
444     void emitSelectionChanged_();
445     void beginAggregateSignals_();
446     void endAggregateSignals_();
447     int signalCounter_;
448     bool shouldEmitSelectionChanged_;
449 
450     // Transform tool
451     TransformTool transformTool_;
452     friend class TransformTool;
453 };
454 
455 }
456 
457 #endif
458