00001 /********************************************************************** 00002 * edge_strip.H: 00003 **********************************************************************/ 00004 #ifndef EDGE_STRIP_H_IS_INCLUDED 00005 #define EDGE_STRIP_H_IS_INCLUDED 00006 00007 #include "bvert.H" 00008 00009 class StripCB; 00010 /********************************************************************** 00011 * EdgeStrip: 00012 * 00013 * Builds and stores edge strips -- sequences of mesh edges 00014 * that can be drawn, e.g. as OpenGL line strips. A single 00015 * EdgeStrip can encode several disconnected line strips. 00016 * 00017 * Each vertex represents the starting vertex of the 00018 * corresponding edge. Like TriStrips, uses a StripCB 00019 * for the actual graphics calls. 00020 **********************************************************************/ 00021 #define CEdgeStrip const EdgeStrip 00022 class EdgeStrip { 00023 public: 00024 //******** MANAGERS ******** 00025 00026 // Create an empty strip: 00027 EdgeStrip() : _patch(0), _index(-1) {} 00028 00029 // Given a list of edges to search, build a strip of 00030 // edges that satisfy a given property. 00031 EdgeStrip(CBedge_list& list, CSimplexFilter& filter) : 00032 _patch(0), 00033 _index(-1) { 00034 build(list, filter); 00035 } 00036 virtual ~EdgeStrip() {} 00037 00038 // Assignment operator: 00039 virtual EdgeStrip& operator=(CEdgeStrip& strip) { 00040 reset(); // In LedgeStrip: deletes subdiv strips 00041 _verts = strip._verts; 00042 _edges = strip._edges; 00043 return *this; 00044 } 00045 00046 //******** BUILDING ******** 00047 00048 // Given a list of edges to search, build the strip from edges 00049 // that satisfy a given property. The given filter should 00050 // screen for edges of the desired kind that have ALSO not yet 00051 // been "reached" in the search (e.g. their flag is not set). 00052 void build(CBedge_list&, CSimplexFilter&); 00053 00054 // Build the strip from the given pool of edges, with the 00055 // given filter. Try to start the edge strip at the "tips" of 00056 // chains of edges of the desired type. The given filter 00057 // should just screen for edges of the desired kind; 00058 // internally this method further screens for edges that have 00059 // not yet been reached, by setting edge flags. 00060 void build_with_tips(CBedge_list&, CSimplexFilter&); 00061 00062 // Similar to above, but builds the edge strip along the boundary 00063 // between faces accepted by the filter and those not accepted. 00064 // The different pieces each run CCW around the faces of interest. 00065 void build_ccw_boundaries(CBedge_list& edges, CSimplexFilter& face_filter); 00066 00067 // Continue building the strip from a given edge type, 00068 // starting at the given edge and one of its vertices. 00069 // If the vertex is nil a vertex is chosen from the edge 00070 // arbitrarily. 00071 void build(Bvert* v, Bedge* e, CSimplexFilter&); 00072 00073 // Add another segment to the strip: 00074 void add(Bvert* v, Bedge* e) { 00075 if (v && e) { 00076 _verts += v; _edges += e; 00077 } 00078 } 00079 00080 // Clear the strip: 00081 virtual void reset() { _verts.clear(); _edges.clear(); } 00082 00083 //******** ACCESSORS ******** 00084 00085 // Patch and mesh that own the strip: 00086 Patch* patch() const { return _patch; } 00087 BMESH* mesh() const { return _verts.mesh(); } 00088 00089 // Returns edge and vert lists of this strip: 00090 CBedge_list& edges() const { return _edges; } 00091 CBvert_list& verts() const { return _verts; } 00092 00093 // Convenience accessors for edge or vert number i: 00094 Bedge* edge(int i) const { return _edges[i]; } 00095 Bvert* vert(int i) const { return _verts[i]; } 00096 Bvert* next_vert(int i) const { return _edges[i]->other_vertex(_verts[i]); } 00097 00098 Bvert* first() const { return _verts[0]; } 00099 Bvert* last() const { return next_vert(num()-1); } 00100 00101 bool empty() const { return _verts.empty(); } 00102 int num() const { return _verts.num(); } 00103 00104 // Returns true if the line strip is broken at vert i 00105 // (or if it's the first or last vert): 00106 bool has_break(int i) const; 00107 00108 // Returns number of distinct (disconnected) line strips: 00109 int num_line_strips() const; 00110 00111 // Return a list of distinct chains of edges, in the form 00112 // of a set of Bvert_lists. 00113 void get_chains(ARRAY<Bvert_list>& chains) const; 00114 00115 // Return the chain starting at index k, 00116 // and advance k to the start of the next chain. 00117 bool get_chain(int& k, Bvert_list& chain) const; 00118 00119 // Diagnostic, for the paranoid 00120 bool same_mesh() const { 00121 return (_verts.same_mesh() && 00122 _edges.same_mesh() && 00123 _verts.mesh() == _edges.mesh() 00124 ); 00125 } 00126 00127 // Generate the reversed edge strip: 00128 EdgeStrip get_reverse() const; 00129 00130 // Reverse the direction of this one: 00131 void reverse() { *this = get_reverse(); } 00132 00133 // Return a strip of edges from this strip that are accepted 00134 // by the given filter: 00135 EdgeStrip get_filtered(CSimplexFilter& filter) const; 00136 00137 // In case the edge strip has breaks, return an equivalent strip 00138 // (same edges) eliminating breaks where possible: 00139 EdgeStrip get_unified() const; 00140 00141 //******** VIRTUAL METHODS ******** 00142 00143 // draw the strip 00144 virtual void draw(StripCB* cb); 00145 00146 // Subdivision strips: 00147 // For an EdgeStrip, cur_strip() returns the strip itself. 00148 // For an LedgeStrip, returns the child strip at the current 00149 // subdivision level: 00150 virtual CEdgeStrip* cur_strip() const { return this; } 00151 00152 // Returns the child strip at the given subdivision level. 00153 // The specified level is relative to this strip, so level 0 00154 // refers to this strip, level 1 is its child strip, etc.: 00155 virtual CEdgeStrip* sub_strip(int k) const { return k==0 ? this : 0; } 00156 00157 // Returns edge and vert lists of the "current" strip: 00158 // (see comment above about the virtual cur_strip() method): 00159 CBvert_list& cur_verts() const { return cur_strip()->verts(); } 00160 CBedge_list& cur_edges() const { return cur_strip()->edges(); } 00161 00162 CBvert_list& verts(int k) const { return sub_strip(k)->verts(); } 00163 CBedge_list& edges(int k) const { return sub_strip(k)->edges(); } 00164 00165 protected: 00166 friend class Patch; 00167 00168 //******** DATA ******** 00169 Bvert_list _verts; // the sequence of verts 00170 Bedge_list _edges; // each edge follows the corresponding vert 00171 Patch* _patch; // patch this is assigned to 00172 int _index; // index in patch's list 00173 00174 //******** PROTECTED METHODS ******** 00175 00176 // Used internally when generating strips of edges of a given type. 00177 // The filter should accept edges of the correct type that have not 00178 // already been checked -- details in EdgeStrip::build(): 00179 static Bedge* next_edge(Bvert*, Bvert_list&, CSimplexFilter&); 00180 00181 // Run a strip from v thru e and continuing on to other edges 00182 // accepted by the filter. Incompletely explored vertices are 00183 // saved in the list so they can be revisited another time. 00184 void build_line_strip(Bvert* v, Bedge* e, CSimplexFilter&, Bvert_list&); 00185 00186 // setting the Patch -- nobody's bizness but the Patch's: 00187 // (to set it call Patch::add(EdgeStrip*)) 00188 void set_patch(Patch* p) { _patch = p; } 00189 void set_patch_index(int k) { _index = k; } 00190 int patch_index() const { return _index; } 00191 }; 00192 00193 #endif // EDGE_STRIP_H_IS_INCLUDED 00194 00195 /* end of file edge_strip.H */