MeshKit
1.0
|
00001 #ifndef EDGEFLIP_H 00002 #define EDGEFLIP_H 00003 00004 #include "meshkit/Mesh.hpp" 00005 00006 namespace Jaal 00007 { 00008 struct SwapEdges : public MeshOptimization 00009 { 00010 static const int DELAUNAY_RULE = 0; 00011 static const int DEGREE_REDUCTION_RULE = 1; 00012 static const int ADVANCE_FRONT_RULE = 2; 00013 00014 void setCreaseAngle(double a) { 00015 creaseAngle = a; 00016 } 00017 00018 void setConstraintEdges(vector<Edge*> &edges) { 00019 // constraint_edges.add(emesh); 00020 } 00021 00022 size_t get_number_of_edges_flipped() const { 00023 return num_edges_flipped; 00024 } 00025 00026 Mesh *mesh; 00027 double creaseAngle; 00028 size_t num_edges_flipped; 00029 00030 struct FlipEdge : public Edge { 00031 00032 FlipEdge() { 00033 } 00034 00035 FlipEdge(Vertex *v1, Vertex * v2) { 00036 process(v1, v2); 00037 } 00038 00039 ~FlipEdge() { 00040 } 00041 00042 bool isValid() const { 00043 if( faces[0] == NULL || faces[1] == NULL ) return 0; 00044 if( opposite_nodes[0] == NULL || opposite_nodes[1] == NULL ) return 0; 00045 return 1; 00046 } 00047 00048 bool isSharp(double creseAngle) const; 00049 bool isConcave() const; 00050 00051 Face * faces[2]; 00052 Vertex * opposite_nodes[2]; 00053 00054 FaceSequence oldFaces, newFaces; 00055 NodeSequence oldNodes, newNodes; 00056 private: 00057 void process(Vertex *v1, Vertex * v2); 00058 }; 00059 }; 00060 00062 00063 class SwapTriEdges : public SwapEdges { 00064 00065 public: 00066 00068 00069 SwapTriEdges(Mesh *m, double angle = 10.0) { 00070 mesh = m; 00071 creaseAngle = angle; 00072 } 00073 00074 ~SwapTriEdges() { } 00075 00076 int apply_rule(int r = DELAUNAY_RULE); 00077 00078 private: 00079 00080 int apply_advance_front_rule(); 00081 00082 bool isIdeal( const Vertex *v) const { 00083 int ideal_degree = v->get_ideal_face_degree(3); 00084 int curr_degree = v->getNumRelations(2); 00085 if( curr_degree == ideal_degree ) return 1; 00086 return 0; 00087 } 00088 00089 bool unchecked( const Face *f ) const { 00090 int lid = 0; 00091 for( int i = 0; i < 3; i++) { 00092 Vertex *v = f->getNodeAt(i); 00093 v->getAttribute("Layer", lid ); 00094 if( lid == std::numeric_limits< int >::max()) return 1; 00095 } 00096 return 0; 00097 } 00098 int one_sweep( int entity, int r); 00099 int atomicOp(const Face *face, int r); 00100 int atomicOp(Vertex *v, int r); 00101 00102 virtual int commit(const FlipEdge &edge); 00103 virtual bool is_edge_flip_allowed(const FlipEdge &edge, int r ) const; 00104 }; 00105 00106 00107 struct QuadEdge { 00108 00109 QuadEdge() { 00110 mesh = NULL; 00111 connect[0] = NULL; 00112 connect[1] = NULL; 00113 } 00114 00115 ~QuadEdge() { 00116 for( size_t i = 0; i < newNodes.size(); i++) 00117 if( newNodes[i] ) delete newNodes[i]; 00118 00119 for( size_t i = 0; i < newFaces.size(); i++) 00120 if( newFaces[i] ) delete newFaces[i]; 00121 } 00122 00123 bool isBoundary() const { 00124 if (adjFaces[0] == NULL || adjFaces[1] == NULL) return 1; 00125 return 0; 00126 } 00127 00128 Vertex* getNodeAt( int i ) const { 00129 if( i == 0) return connect[0]; 00130 if( i == 1) return connect[1]; 00131 return NULL; 00132 } 00133 00134 Vertex * connect[2]; 00135 protected: 00136 Mesh *mesh; 00137 FaceSequence adjFaces; 00138 NodeSequence newNodes; 00139 FaceSequence newFaces; 00140 int commit(); 00141 }; 00142 00143 00144 class SwapQuadEdge : public QuadEdge { 00145 public: 00146 static bool is_topologically_valid_swap(int d1, int d2, int d3, int d4); 00147 00148 SwapQuadEdge(Mesh *m, Vertex *v0, Vertex *v1, Face *firstface = NULL) { 00149 mesh = m; 00150 edge = NULL; 00151 connect[0] = v0; 00152 connect[1] = v1; 00153 firstFace = firstface; 00154 assert(mesh); 00155 check_fronts = 0; 00156 } 00157 00158 SwapQuadEdge(Mesh *m, Edge *e, Face *firstface = NULL) { 00159 mesh = m; 00160 edge = e; 00161 connect[0] = e->getNodeAt(0); 00162 connect[1] = e->getNodeAt(1); 00163 firstFace = firstface; 00164 assert(mesh); 00165 } 00166 00167 void clear() { 00168 if (newFaces[0] != NULL) delete newFaces[0]; 00169 if (newFaces[1] != NULL) delete newFaces[1]; 00170 } 00171 00172 void modify_fronts( int v ) { 00173 check_fronts = v; 00174 } 00175 00176 int apply_reduce_degree_rule(); 00177 int apply_concave_rule(); // Swap some concave edge 00178 int apply_bound_rule(); // Swap some boundary edge 00179 int apply_singlet_rule(Vertex *singlet); // Force creating diagonal at singlet.. 00180 int apply_deficient_rule(Vertex *v); // Force creating diagonal at deficient vertex.. 00181 int apply_advance_front_rule(); 00182 00183 private: 00184 bool check_fronts; 00185 Face *firstFace; // Which one of the two faces is the first one. It is needed 00186 Edge *edge; // Swapping edge. 00187 NodeSequence bound_nodes; // It is always going to be six nodes... 00188 00189 struct BackUpData { 00190 Vertex *diagonalConnect[2]; // Diagonal of the two quads. 00191 NodeSequence face1Connect, face2Connect; 00192 map<Vertex*, Point3D> pCoords; // Six Boundary node's coordinates. 00193 }; 00194 BackUpData bkp_data; 00195 00196 void backup(); 00197 void rollback(); 00198 00199 int getPosOf(const Vertex *v) const; 00200 int build_boundary(); 00201 int get_boundary_nodes_chain(); 00202 int make_new_diagonal_at(int pos, bool bound_check = 1); 00203 00204 // For front cleaning ops; 00205 int hasLessNodes(Vertex *vertex, int layerid); 00206 int hasExcessNodes(Vertex *vertex, int layerid); 00207 void update_front(); 00208 }; 00209 } 00210 00212 00213 /* 00214 struct RemeshTemplate { 00215 NodeSequence newnodes; 00216 FaceSequence newfaces; 00217 00218 void addNewElements( const NodeSequence &nnodes, const FaceSequence &nfaces) { 00219 size_t nSize; 00220 nSize = nnodes.size(); 00221 for (size_t i = 0; i < nSize; i++) 00222 newnodes.push_back(nnodes[i]); 00223 00224 nSize = nfaces.size(); 00225 for (size_t i = 0; i < nSize; i++) 00226 newfaces.push_back(nfaces[i]); 00227 } 00228 00229 void discard() { 00230 size_t nSize = newfaces.size(); 00231 for (size_t i = 0; i < nSize; i++) 00232 mesh->remove(newfaces[i]); 00233 00234 nSize = newnodes.size(); 00235 for (size_t i = 0; i < nSize; i++) 00236 mesh->remove(newnodes[i]); 00237 } 00238 00239 Mesh *mesh; 00240 }; 00241 */ 00242 00243 00244 00245 #endif