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_INSTANT_EDGE_H 18 #define VAC_INSTANT_EDGE_H 19 20 #include "EdgeCell.h" 21 #include "KeyCell.h" 22 #include "Eigen.h" 23 #include "Triangles.h" 24 25 namespace VectorAnimationComplex 26 { 27 class EdgeGeometry; 28 class EdgeInter; 29 class IntersectionList; 30 31 class KeyEdge: public KeyCell, public EdgeCell 32 { 33 public: 34 35 // Constructor. Geometry must be a valid non-null pointer. 36 // KeyEdge takes ownership of geometry. The rationale is to let the 37 // caller specify the actual derived class used for geometry, for instance: 38 // new InstanceEdge(this, time, left, right, new LinearSpline(...)); 39 // non loop 40 KeyEdge(VAC * vac, Time time, 41 KeyVertex * startVertex, 42 KeyVertex * endVertex, 43 EdgeGeometry * geometry); 44 // loop 45 KeyEdge(VAC * vac, Time time, 46 EdgeGeometry * geometry); 47 48 // Drawing 49 virtual void drawPickTopology(Time time, ViewSettings & viewSettings); 50 void draw3DSmall(); 51 void drawRaw3D(View3DSettings & viewSettings); 52 53 // Topology startVertex()54 KeyVertex * startVertex() const { return startVertex_; } endVertex()55 KeyVertex * endVertex() const { return endVertex_; } isSplittedLoop()56 bool isSplittedLoop() const 57 { return (!isClosed()) && (startVertex_ == endVertex_); } isClosed()58 bool isClosed() const { return !startVertex_; } 59 60 // reimplements 61 VertexCellSet startVertices() const; 62 VertexCellSet endVertices() const; 63 64 65 // Geometry geometry()66 EdgeGeometry * geometry() const { return geometry_; } 67 void correctGeometry(); 68 void setWidth(double newWidth); 69 QList<EdgeSample> getSampling(Time time) const; 70 71 72 // Sculpting 73 // prepare edge for potential sculpting: 74 // - (x,y) is mouse position 75 // - radius is the radius of influence of the sculpt tool 76 // - must return the distance from (x,y) to the point where it would be sculpted. 77 // - may store all relevant info to provide sculptVertex() later. 78 double updateSculpt(double x, double y, double radius); 79 // Deform 80 void beginSculptDeform(double x, double y); 81 void continueSculptDeform(double x, double y); 82 void endSculptDeform(); 83 // Change edge width 84 void beginSculptEdgeWidth(double x, double y); 85 void continueSculptEdgeWidth(double x, double y); 86 void endSculptEdgeWidth(); 87 // Change edge width 88 void beginSculptSmooth(double x, double y); 89 void continueSculptSmooth(double x, double y); 90 void endSculptSmooth(); 91 // Affine transform 92 void prepareAffineTransform(); 93 void performAffineTransform(const Eigen::Affine2d & xf); 94 95 private: 96 friend class VAC; 97 98 ~KeyEdge(); 99 KeyVertex * startVertex_; 100 KeyVertex * endVertex_; 101 EdgeGeometry * geometry_; 102 103 // Trusting operators 104 friend class Operator; 105 bool check_() const; 106 107 // Update Boundary 108 void updateBoundary_impl(KeyVertex * oldVertex, KeyVertex * newVertex); 109 110 // Note: topFace or bottom can be either instant or 111 // animated, at the contrary of InbetweenEdge where it is 112 // necessarily animated, and hence have a specific member 113 // to store it, in addition to the one stored in 114 // EdgeObject base class 115 116 // for sculpting 117 void prepareSculptPreserveTangents_(); 118 void continueSculptPreserveTangents_(); 119 KeyEdgeSet sculpt_keepRightAsLeft_; 120 KeyEdgeSet sculpt_keepLeftAsLeft_; 121 KeyEdgeSet sculpt_keepLeftAsRight_; 122 KeyEdgeSet sculpt_keepRightAsRight_; 123 Eigen::Vector2d sculpt_beginLeftDer_; 124 Eigen::Vector2d sculpt_beginRightDer_; 125 bool sculpt_keepMyselfTangent_; 126 double sculptRadius_; 127 double remainingRadiusLeft_; 128 double remainingRadiusRight_; 129 130 // Implementation of triangulate 131 void triangulate_(Time time, Triangles & out) const; 132 void triangulate_(double width, Time time, Triangles & out) const; 133 134 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 135 136 137 // --------- Cloning, Assigning, Copying, Serializing ---------- 138 139 protected: 140 // Cloning 141 KeyEdge(KeyEdge * other); 142 virtual KeyEdge * clone(); 143 virtual void remapPointers(VAC * newVAC); 144 145 // Serializing 146 virtual void save_(QTextStream & out); stringType()147 QString stringType() const {return "Edge";} 148 virtual QString xmlType_() const; 149 virtual void write_(XmlStreamWriter & xml) const; 150 151 152 // Unserializing 153 KeyEdge(VAC * vac, XmlStreamReader & xml); 154 KeyEdge(VAC * vac, QTextStream & in); 155 public: class Read1stPass { 156 friend Cell * Cell::read1stPass(VAC * vac, QTextStream & in); create(VAC * g,QTextStream & in)157 static KeyEdge * create(VAC * g, QTextStream & in) 158 {return new KeyEdge(g, in);} }; 159 protected: virtual void read2ndPass(); 160 private: 161 struct TempRead { int left, right; }; 162 TempRead * tmp_; 163 }; 164 165 } 166 167 #endif 168