MeshKit  1.0
SwapEdges.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines