/[libvob]/libvob/include/vob/poly/Dicer.hxx
ViewVC logotype

Diff of /libvob/include/vob/poly/Dicer.hxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by tjl, Tue Apr 1 11:09:25 2003 UTC revision 1.3 by tjl, Wed May 7 12:00:42 2003 UTC
# Line 3  Line 3 
3  #ifndef VOB_POLY_DICER_HXX  #ifndef VOB_POLY_DICER_HXX
4  #define VOB_POLY_DICER_HXX  #define VOB_POLY_DICER_HXX
5    
6    #include <GL/gl.h>
7  #include <algorithm>  #include <algorithm>
8  #include <set>  #include <set>
9  #include <map>  #include <map>
10  #include <vector>  #include <vector>
11    #include <list>
12  #include <ext/slist>  #include <ext/slist>
13    
14  namespace Vob {  namespace Vob {
# Line 14  namespace Dicer { Line 16  namespace Dicer {
16    
17      PREDBGVAR(dbg);      PREDBGVAR(dbg);
18    
19        template<class Verts> struct Triangles {
20            Verts &verts;
21            struct Tri {
22                int v[3];
23                typename std::list<Tri>::iterator n[3];
24            };
25            std::list<Tri> tris;
26    
27            typedef typename std::list<Tri>::iterator Titer;
28            vector<Titer> vertFirst;
29    
30            void remove(Titer x) {
31                Tri &t = *x;
32                DBG(dbg) << "Triangler: remove "<<t.v[0]<<" "<<t.v[1]<<" "<<t.v[2]<<"\n";
33                // Remove from the edge list
34                for(int i=0; i<3; i++) {
35                    Titer v = vertFirst[t.v[i]];
36                    DBG(dbg) << "Titer: "<<(*v).v[0]<<" "<<(*v).v[1]<<" "<<(*v).v[2]<<"\n";
37                    if(v == x) {
38                        DBG(dbg) << "Was first\n";
39                        vertFirst[t.v[i]] = t.n[i];
40                    } else {
41                        Titer prev = v;
42                        int vind = 0;
43                        if((*v).v[0] == t.v[i]) vind = 0;
44                        if((*v).v[1] == t.v[i]) vind = 1;
45                        if((*v).v[2] == t.v[i]) vind = 2;
46                        v = (*v).n[vind];
47                        while(v != tris.end()) {
48                            DBG(dbg) << "Titer: "<<(*v).v[0]<<" "<<(*v).v[1]<<" "<<(*v).v[2]<<"\n";
49                            if(v == x) {
50                                (*prev).n[vind] = t.n[i];
51                                break;
52                            }
53                            if((*v).v[0] == t.v[i]) vind = 0;
54                            if((*v).v[1] == t.v[i]) vind = 1;
55                            if((*v).v[2] == t.v[i]) vind = 2;
56                            prev = v;
57                            v = (*v).n[vind];
58                        }
59                    }
60                }
61                DBG(dbg) << "Remove: realerase\n";
62                tris.erase(x);
63            }
64    
65            void splitEdge(int v1, int v2) {
66                DBG(dbg) << "Triangler: split "<<v1<<" "<<v2<<"\n";
67                vector<Titer> toremove;
68                for(Titer x = vertFirst[v1]; x != tris.end(); ) {
69                    int vind = 0;
70                    if((*x).v[0] == v1) vind = 0;
71                    if((*x).v[1] == v1) vind = 1;
72                    if((*x).v[2] == v1) vind = 2;
73                    if((*x).v[0] == v2 ||
74                       (*x).v[1] == v2 ||
75                       (*x).v[2] == v2) toremove.push_back(x);
76                    x = (*x).n[vind];
77                }
78                if(toremove.size() == 0) return;
79                int nvert = verts(v1, v2, .5);
80                DBG(dbg) << "Have new vert "<<nvert<<"\n";
81                for(unsigned i=0; i<toremove.size(); i++) {
82                    // Save to local
83                    Tri t = *toremove[i];
84                    remove(toremove[i]);
85                    int i = (t.v[0] == v1 ? nvert : t.v[0]);
86                    int j = (t.v[1] == v1 ? nvert : t.v[1]);
87                    int k = (t.v[2] == v1 ? nvert : t.v[2]);
88                    add(i, j, k);
89                    i = (t.v[0] == v2 ? nvert : t.v[0]);
90                    j = (t.v[1] == v2 ? nvert : t.v[1]);
91                    k = (t.v[2] == v2 ? nvert : t.v[2]);
92                    add(i, j, k);
93                }
94                DBG(dbg) << "Split finished\n";
95            }
96    
97        public:
98            void add(int i, int j, int k) {
99                DBG(dbg) << "Triangler: add "<<i<<" "<<j<<" "<<k<<"\n";
100                Tri t;
101                t.v[0] = i;
102                t.v[1] = j;
103                t.v[2] = k;
104                if(vertFirst.size() != verts.size())
105                    vertFirst.resize(verts.size(), tris.end());
106                t.n[0] = vertFirst[i];
107                t.n[1] = vertFirst[j];
108                t.n[2] = vertFirst[k];
109                vertFirst[i] = vertFirst[j] = vertFirst[k] =
110                    tris.insert(tris.begin(), t);
111            }
112    
113            template <class F> void dice(F criterion) {
114                DBG(dbg) << "Triangler: dice\n";
115                typedef std::pair<int, int> Edge;
116                vector<Edge> tosplit;
117                while(1) {
118                    DBG(dbg) << "Triangler: dice round\n";
119                    for(Titer t = tris.begin(); t != tris.end(); t++) {
120                        Tri &tri = *t;
121                        int spl = criterion(tri.v[0], tri.v[1], tri.v[2]);
122                        if(spl >= 0) {
123                            tosplit.push_back( Edge( tri.v[spl], tri.v[(spl+1) % 3]));
124                        }
125                    }
126                    if(!tosplit.size()) return;
127                    for(unsigned i=0; i<tosplit.size(); i++)
128                        splitEdge(tosplit[i].first, tosplit[i].second);
129                    tosplit.clear();
130                }
131            }
132            void draw() {
133                glBegin(GL_TRIANGLES);
134                for(Titer x = tris.begin(); x != tris.end(); x++) {
135                    glArrayElement((*x).v[0]);
136                    glArrayElement((*x).v[1]);
137                    glArrayElement((*x).v[2]);
138                }
139                glEnd();
140            }
141            Triangles(Verts &v) : verts(v) {
142            }
143        };
144    
145      /** Dice a line to pieces satisfying Criterion.      /** Dice a line to pieces satisfying Criterion.
146       * This is a generic method to dice a given edge recursively.       * This is a generic method to dice a given edge recursively.
# Line 34  namespace Dicer { Line 161  namespace Dicer {
161       * @return Number of new vertices added to the edge.       * @return Number of new vertices added to the edge.
162       */       */
163      template<class Verts, class Edge, class Criterion>      template<class Verts, class Edge, class Criterion>
164              int dice_line(Verts &verts, Edge &edge,              int dice_line2(Verts &verts, Edge &edge,
165                          typename Edge::iterator begin, typename Edge::iterator last,                          typename Edge::iterator begin, typename Edge::iterator last,
166                              Criterion split, int maxdepth, int depth=0) {                              Criterion split, int maxdepth, int depth=0) {
167          DBG(dbg) << "dice_line "<<depth<<"\n";          DBG(dbg) << "dice_line "<<depth<<"\n";
# Line 62  namespace Dicer { Line 189  namespace Dicer {
189          return ret;          return ret;
190      }      }
191    
192        template<class Verts, class Edge, class Criterion>
193                int dice_line3_h(Verts &verts, Edge &edge,
194                            typename Edge::iterator begin,
195                            typename Edge::iterator half,
196                            typename Edge::iterator last,
197                                Criterion split, int maxdepth, int depth) {
198            if(depth >= maxdepth) {
199                DBG(dbg) << "dice_line3_h STOPDEPTH\n";
200                return 0;
201            }
202            int splitflag = split(*begin, *half, *last);
203            int ret = 0;
204            if(splitflag == 1) {
205                int spv = verts(*begin, *half, .5);
206                ret ++;
207                typename Edge::iterator sp = edge.insert_after(begin, spv);
208                ret += dice_line3_h(verts, edge, begin, sp, half, split, maxdepth, depth+1);
209            }
210            int esplitflag = split(*last, *half, *begin);
211            if(esplitflag == 1) {
212                int espv = verts(*half, *last, .5);
213                ret ++;
214                typename Edge::iterator esp = edge.insert_after(half, espv);
215                ret += dice_line3_h(verts, edge, half, esp, last, split, maxdepth, depth+1);
216            }
217            return ret;
218            
219        }
220    
221        template<class Verts, class Edge, class Criterion>
222                int dice_line3(Verts &verts, Edge &edge,
223                            typename Edge::iterator begin, typename Edge::iterator last,
224                                Criterion split, int maxdepth, int depth=0) {
225            DBG(dbg) << "dice_line "<<depth<<"\n";
226            if(depth >= maxdepth) {
227                DBG(dbg) << "dice_line STOPDEPTH\n";
228                return 0;
229            }
230            int halfv = verts(*begin, *last, .5);
231    
232    
233            int splitflag = split(*begin, halfv, *last);
234            if(splitflag == -1) {
235                DBG(dbg) << "dice_line STOP FLAG\n";
236                return 0;
237            }
238            typename Edge::iterator half = edge.insert_after(begin, halfv);
239            int ret = 1;
240            ret += dice_line3_h(verts, edge, begin, half, last, split, maxdepth, depth + 1);
241    
242            DBG(dbg) << "RET dice_line "<<depth<<" "<<ret << "\n";
243            return ret;
244        }
245    
246    
247      /** A triangle whose edges have been diced.      /** A triangle whose edges have been diced.
248       */       */
249      template<class Edge> struct DicedTriangle {      template<class Edge> struct DicedTriangle {
# Line 118  namespace Dicer { Line 300  namespace Dicer {
300                  DicedTriangle start;                  DicedTriangle start;
301                  start.ebegins[0] = newEdge.begin();                  start.ebegins[0] = newEdge.begin();
302                  start.elasts[0] = newEdge.begin(); start.elasts[0] ++;                  start.elasts[0] = newEdge.begin(); start.elasts[0] ++;
303                  start.n[0] = dice_line(verts, newEdge, start.ebegins[0], start.elasts[0], split, maxdepth, depth);                  start.n[0] = dice_line3(verts, newEdge, start.ebegins[0], start.elasts[0], split, maxdepth, depth);
304    
305                  start.ebegins[1] = ebegins[thirdEdge];                  start.ebegins[1] = ebegins[thirdEdge];
306                  start.elasts[1] = elasts[thirdEdge];                  start.elasts[1] = elasts[thirdEdge];
# Line 175  namespace Dicer { Line 357  namespace Dicer {
357              for(int i=0; i<3; i++) {              for(int i=0; i<3; i++) {
358                  ebegins[i] = e[i].begin();                  ebegins[i] = e[i].begin();
359                  elasts[i] = ebegins[i]; elasts[i] ++;                  elasts[i] = ebegins[i]; elasts[i] ++;
360                  n[i] = dice_line(verts, e[i], ebegins[i], elasts[i], split, maxdepth);                  n[i] = dice_line3(verts, e[i], ebegins[i], elasts[i], split, maxdepth);
361              }              }
362          }          }
363      };      };

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26