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