gzz-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gzz-commits] libvob include/vob/geom/Fillets2.hxx include/vo...


From: Janne V. Kujala
Subject: [Gzz-commits] libvob include/vob/geom/Fillets2.hxx include/vo...
Date: Thu, 03 Jul 2003 09:18:59 -0400

CVSROOT:        /cvsroot/libvob
Module name:    libvob
Branch:         
Changes by:     Janne V. Kujala <address@hidden>        03/07/03 09:18:59

Modified files:
        include/vob/geom: Fillets2.hxx 
        include/vob/vobs: Fillet.hxx 
        vob/fillet     : light3d.py 

Log message:
        fillet code

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/geom/Fillets2.hxx.diff?tr1=1.25&tr2=1.26&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/vobs/Fillet.hxx.diff?tr1=1.39&tr2=1.40&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/vob/fillet/light3d.py.diff?tr1=1.26&tr2=1.27&r1=text&r2=text

Patches:
Index: libvob/include/vob/geom/Fillets2.hxx
diff -u libvob/include/vob/geom/Fillets2.hxx:1.25 
libvob/include/vob/geom/Fillets2.hxx:1.26
--- libvob/include/vob/geom/Fillets2.hxx:1.25   Wed Jul  2 09:23:51 2003
+++ libvob/include/vob/geom/Fillets2.hxx        Thu Jul  3 09:18:58 2003
@@ -664,14 +664,18 @@
        for (i = 0; i < n; i++)
            for (j = i + 1; j < n; j++)
                for (k = j + 1; k < n; k++) {
-                   ZVec d = (v[i] - v[k]).crossp(v[j] - v[k]).normalized();
-                   d /= d.dot(v[k]);
+                   ZVec d = (v[j] - v[i]).crossp(v[k] - v[j]).normalized();
+                   float dot = d.dot(v[k]);
+                   d /= dot;
                    for (l = 0; l < n; l++) {
                        if (l == i || l == j || l == k) continue;
                        if (d.dot(v[l]) >= 1) break;
                    }
                    if (l == n)
-                       tri.push_back(int3(i,j,k));
+                       if (dot < 0)
+                           tri.push_back(int3(j,i,k));
+                       else
+                           tri.push_back(int3(i,j,k));
                }
        
     }
Index: libvob/include/vob/vobs/Fillet.hxx
diff -u libvob/include/vob/vobs/Fillet.hxx:1.39 
libvob/include/vob/vobs/Fillet.hxx:1.40
--- libvob/include/vob/vobs/Fillet.hxx:1.39     Wed Jul  2 10:53:02 2003
+++ libvob/include/vob/vobs/Fillet.hxx  Thu Jul  3 09:18:59 2003
@@ -668,9 +668,10 @@
     enum { NTrans = -1 };
 
     int ndice;
+    float dicelen;
 
     template<class F> void params(F &f) {
-       f(ndice);
+       f(ndice, dicelen);
     }
 
     template<class T> float crad(const T &t) const {
@@ -683,6 +684,9 @@
        StretchedCircleFillet f;
        ZVec dir;
 
+       float da;
+       vector<float> rtbl;
+
        Conn(const CircularNode &node,
             float d,
             float th,
@@ -691,6 +695,7 @@
            node(&node),
            c(node, 0, d, th, -1, 0), 
            f(node, c, a), dir(dir) {
+           compute_rtbl(100);
        }
 
        Vec trans(ZVec v) const {
@@ -700,7 +705,11 @@
        }
 
        float rad(ZVec v, bool &success) const {
-           Vec t = trans(v).normalized();
+           Vec t = trans(v);
+           if (rtbl.size()) {
+               success = true;
+               return rad_rtbl(t);
+           }
            ZVec pt = f.point(t, success);
            if (success) return pt.length();
            if (f.infillet(t)) {
@@ -710,6 +719,33 @@
            }
            return node->r;
        }
+
+       void compute_rtbl(int n) {
+           rtbl.resize(n + 1);
+           for (int i = 0; i < n; i++) {
+               float t = i * (1.0 / n);
+               float a = (t * t) * f.tangentAngle;
+               bool success;
+               float fract;
+               ZVec pt = f.point(dirVec(a), success, &fract, .001);
+               if (success)
+                   rtbl[i] = pt.length();
+               else
+                   rtbl[i] = c.d / cos(a);
+               //cout << i << ": " << rtbl[i] << pt << fract << std::endl;
+           }
+           rtbl[n] = node->r;
+       }
+
+       float rad_rtbl(Vec v) const {
+           int n = rtbl.size() - 1;
+           float a = v.atan();
+           float t = sqrt(a / f.tangentAngle);
+           unsigned i = (unsigned)(t * n);
+           float fract = t * n - i;
+           if (i >= n) return rtbl[n];
+           return (1 - fract) * rtbl[i] + fract * rtbl[i + 1];
+       }
     };
 
     ZVec blend(Conn *conns[], int N, float r, ZVec pt) const {
@@ -717,31 +753,33 @@
        float sum = 0;
        float x[N];
 
+       pt = pt.normalized();
+
        // Compute distances from the node for each fillet surface
        for (i = 0; i < N; i++) {
            bool success;
            float t = conns[i]->rad(pt, success);
            if (success)
-               sum += x[num++] = (t - r) / r;
+               sum += x[num++] = t - r;
        }
 
        // Compute p for an l^p norm to be used as the blending function
        // p == 1: sum of distances, 
        // p == \infty: maximum of distances
-       float p = 1.0 + sum;
+       float p = 1.0 + sum / r;
 
        sum = 0;
        for (i = 0; i < num; i++) 
            sum += pow(x[i], p);
        
-       return pt * (1 + pow(sum, 1 / p));
+       return pt * (r + pow(sum, 1 / p));
 
     }
 
     struct Vert : ZVec {
-       bool bound;
+       int id;
        ZVec norm;
-       Vert(const ZVec &v, bool b = false) : ZVec(v), bound(b) {}
+       Vert(const ZVec &v, int id = 0) : ZVec(v), id(id) {}
     };
 
     struct Verts : std::vector<Vert> {
@@ -749,11 +787,12 @@
        Conn **conns;
        int N;
        float r;
+       bool noblend;
 
-       int append(ZVec v, bool b = false) {
+       int append(ZVec v, int id = 0) {
            int ind = size();
-           if (b)
-               push_back(Vert(v, b));
+           if (id || noblend)
+               push_back(Vert(v, id));
            else
                push_back(f.blend(conns, N, r, v));
 
@@ -761,14 +800,11 @@
        }
 
        int operator() (int i, int j, float fract = .5) {
-           int ind = size();
-           push_back(f.blend(conns, N, r,
-                             lerp(operator[](i), operator[](j), fract)));
-           return ind;
+           return append(lerp(operator[](i), operator[](j), fract));
        }
 
        Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) : 
-           f(f), conns(conns), N(N), r(r) {}
+           f(f), conns(conns), N(N), r(r), noblend(false) {}
     };
 
     struct DiceCrit {
@@ -778,9 +814,15 @@
        DiceCrit(const Verts &v, float dicelen) : v(v), dicelen(dicelen) {}
 
        int operator()(int i, int j, int k) {
-           float l0 = (v[i] - v[j]).length() * !(v[i].bound && v[j].bound);
-           float l1 = (v[j] - v[k]).length() * !(v[j].bound && v[k].bound);
-           float l2 = (v[k] - v[i]).length() * !(v[k].bound && v[i].bound);
+           if (dicelen >= 1000) return -1;
+
+           if (v[i].id && v[j].id && v[i].id != v[j].id) return 0;
+           if (v[j].id && v[k].id && v[j].id != v[k].id) return 1;
+           if (v[k].id && v[i].id && v[k].id != v[i].id) return 2;
+
+           float l0 = (v[i] - v[j]).length() * !(v[i].id && v[i].id == 
v[j].id);
+           float l1 = (v[j] - v[k]).length() * !(v[j].id && v[j].id == 
v[k].id);
+           float l2 = (v[k] - v[i]).length() * !(v[k].id && v[k].id == 
v[i].id);
 
            if (l0 < dicelen && l1 < dicelen && l2 < dicelen)
                return -1;
@@ -804,10 +846,11 @@
        }
 
        i = k0;
-       do {
+       while (1) {
            poly.push_back(i);
+           if (i == k1) break;
            if (++i == i1) i = i0;
-       } while (i != k1);
+       } 
        
     }
 
@@ -825,9 +868,8 @@
        Conn* conns[N];
 
        std::vector<ZVec> dirs;
-       std::vector<int3> tri;
-
        int i, j;
+
        for (i = 0; i < N; i++) {
            const Transform &t1 = *t[3 + i];
            ZVec p1 = t1.transform(0.5 * t1.getSqSize());
@@ -841,6 +883,67 @@
            dirs.push_back((p1 - p0).normalized());
        }
 
+#if 1 // Old  version without Dicer
+
+       ZVec pt[ndice + 1][ndice*2];
+       ZVec norm[ndice + 1][ndice*2];
+
+       for (i = 0; i <= ndice; i++) {
+           float a = i * M_PI / ndice;
+           float x = cos(a);
+           float R = sin(a);
+
+           for (j = 0; j < ndice*2; j++) {
+               float b = j * M_PI * 2 / (ndice*2);
+
+               float y = cos(b) * R;
+               float z = sin(b) * R;
+
+               pt[i][j] = r * ZVec(x, y, z);
+           }
+       }
+
+
+       for (i = 0; i <= ndice; i++)
+           for (j = 0; j < ndice*2; j++)
+               pt[i][j] = blend(conns, N, r, pt[i][j]) + p0;
+
+               
+       for (i = 0; i <= ndice; i++) {
+           for (j = 0; j < ndice*2; j++) {
+               ZVec px0 = pt[i==0 ? 0 : i-1][j];
+               ZVec px1 = pt[i==ndice ? ndice : i+1][j];
+               ZVec py0 = pt[i][j==0 ? 0 : j-1];
+               ZVec py1 = pt[i][j==ndice*2-1 ? ndice*2-1 : j+1];
+
+               norm[i][j] = (px1 - px0).crossp(py1 - py0).normalized();
+           }
+       }
+
+       for (i = 0; i < ndice; i++) {
+           glBegin(GL_QUAD_STRIP);
+           for (j = 0; j < ndice*2-1; j++) {
+               glNormal(norm[i][j]);
+               glVertex(pt[i][j]);
+
+               glNormal(norm[i+1][j]);
+               glVertex(pt[i+1][j]);
+           }
+           glNormal(norm[i][0]);
+           glVertex(pt[i][0]);
+
+           glNormal(norm[i+1][0]);
+           glVertex(pt[i+1][0]);
+           glEnd();
+       }
+
+#else // use Dicer
+
+       Verts verts(*this, conns, N, r);
+       ::Vob::Dicer::Triangles<Verts> triangler(verts);
+
+#if 0 // use Delaunay triangulation based topology
+
        if (dirs.size() == 2) {
            ZVec sum = dirs[0] + dirs[1];
            ZVec dif = dirs[1] - dirs[0];
@@ -851,6 +954,7 @@
            dirs.push_back((v0 + v1).normalized());
        }
 
+       std::vector<int3> tri;
        Triangulate(dirs, dirs.size(), tri);
 
        {
@@ -873,8 +977,7 @@
            }
        }
            
-
-
+       /*
        for (i = 0; i < (int)tri.size(); i++) {
            glBegin(GL_LINE_LOOP);
            glVertex(p0 + 3 * r * dirs[tri[i][0]]);
@@ -882,23 +985,23 @@
            glVertex(p0 + 3 * r * dirs[tri[i][2]]);
            glEnd();
        }
-
+       */
 
        // Add the vertices of the diced midsections of the connectors
-       Verts verts(*this, conns, N, r);
        for (i = 0; i < N; i++) {
            float t = 0.5 * conns[i]->c.t;
            float d = conns[i]->c.d;
 
+           ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0));
            ZVec e0 = conns[i]->dir;
-           ZVec e1 = e0.crossp(ZVec(0,0,1));
+           ZVec e1 = e0.crossp(ref).normalized();
            ZVec e2 = e0.crossp(e1);
 
            ZVec p0 = d * e0;
 
            for (j = 0; j < ndice; j++) {
-               float a = j * M_PI * 2 / ndice;
-               verts.append(p0 + t * (e1 * cos(a) + e2 * sin(a)), true);
+               float a = -j * M_PI * 2 / ndice;
+               verts.append(p0 + t * (e1 * cos(a) + e2 * sin(a)), i + 1);
            }
        }
 
@@ -909,7 +1012,6 @@
        }
 
        // Triangulate the surface
-       ::Vob::Dicer::Triangles<Verts> triangler(verts);
        for (i = 0; i < (int)tri.size(); i++) {
            std::vector<int> poly;
            for (j = 0; j < 3; j++) {
@@ -919,77 +1021,123 @@
                } else {
                    int k0 = tri[i][(j+1)%3];
                    int k1 = tri[i][(j+2)%3];
-                   if ((dirs[k0] - dirs[k]).crossp(dirs[k1] - 
dirs[k]).dot(dirs[k]) < 0)
-                       k0 ^= k1 ^= k0 ^= k1; // Swap
                        
-                   addSpan(poly, verts, ndice * k, ndice * (k + 1), dirs[k0], 
dirs[k1]);
+                   addSpan(poly, verts, ndice * k, ndice * (k + 1), dirs[k1], 
dirs[k0]);
                }
            }
 
            // Triangulate as a star polygon
            ZVec sum(0,0,0);
            for (j = 0; j < (int)poly.size(); j++)
-               sum += verts[poly[j]];
+               sum += verts[poly[j]].normalized();
+
+           int nvert = verts.append(dirs[tri[i][0]] +
+                                    dirs[tri[i][1]] +
+                                    dirs[tri[i][2]]);
 
-           int nvert = verts.append(sum);
            for (j = 0; j < (int)poly.size(); j++)
                triangler.add(nvert, poly[j], poly[(j+1) % poly.size()]);
        }
-       
-
-
-       ZVec pt[ndice + 1][ndice*2];
-       ZVec norm[ndice + 1][ndice*2];
-
-       for (i = 0; i <= ndice; i++) {
-           float a = i * M_PI / ndice;
-           float x = cos(a);
-           float R = sin(a);
-
-           for (j = 0; j < ndice*2; j++) {
-               float b = j * M_PI * 2 / (ndice*2);
 
-               float y = cos(b) * R;
-               float z = sin(b) * R;
+#else // Icosahedron topology
 
-               pt[i][j] = r * ZVec(x, y, z);
-           }
-       }
+       // icosahedron code adapted from sphere.c found in
+       // http://www.sgi.com/Technology/openGL/advanced/programs.html
 
+/* for icosahedron */
+#define CZ_ (0.89442719099991)   /*  2/sqrt(5) */
+#define SZ_ (0.44721359549995)   /*  1/sqrt(5) */
+#define C1_ (0.951056516)        /* cos(18),  */
+#define S1_ (0.309016994)        /* sin(18) */
+#define C2_ (0.587785252)        /* cos(54),  */
+#define S2_ (0.809016994)        /* sin(54) */
+#define X1_ (C1_*CZ_)
+#define Y1_ (S1_*CZ_)
+#define X2_ (C2_*CZ_)
+#define Y2_ (S2_*CZ_)
+
+       verts.noblend = true;
+       int Ip0 = verts.append(ZVec(  0.,    0.,    1.));
+       int Ip1 = verts.append(ZVec(-X2_,  -Y2_,   SZ_));
+       int Ip2 = verts.append(ZVec( X2_,  -Y2_,   SZ_));
+       int Ip3 = verts.append(ZVec( X1_,   Y1_,   SZ_));
+       int Ip4 = verts.append(ZVec(  0,    CZ_,   SZ_));
+       int Ip5 = verts.append(ZVec(-X1_,   Y1_,   SZ_));
+       
+       int Im0 = verts.append(ZVec(-X1_,  -Y1_,  -SZ_));
+       int Im1 = verts.append(ZVec(  0,   -CZ_,  -SZ_));
+       int Im2 = verts.append(ZVec( X1_,  -Y1_,  -SZ_));
+       int Im3 = verts.append(ZVec( X2_,   Y2_,  -SZ_));
+       int Im4 = verts.append(ZVec(-X2_,   Y2_,  -SZ_));
+       int Im5 = verts.append(ZVec(  0.,    0.,   -1.));
+
+        /* front pole */
+        triangler.add(Ip0, Ip1, Ip2);
+        triangler.add(Ip0, Ip5, Ip1);
+        triangler.add(Ip0, Ip4, Ip5);
+        triangler.add(Ip0, Ip3, Ip4);
+        triangler.add(Ip0, Ip2, Ip3);
+
+        /* mid */
+        triangler.add(Ip1, Im0, Im1);
+        triangler.add(Im0, Ip1, Ip5);
+        triangler.add(Ip5, Im4, Im0);
+        triangler.add(Im4, Ip5, Ip4);
+        triangler.add(Ip4, Im3, Im4);
+        triangler.add(Im3, Ip4, Ip3);
+        triangler.add(Ip3, Im2, Im3);
+        triangler.add(Im2, Ip3, Ip2);
+        triangler.add(Ip2, Im1, Im2);
+        triangler.add(Im1, Ip2, Ip1);
+
+        /* back pole */
+        triangler.add(Im3, Im2, Im5);
+        triangler.add(Im4, Im3, Im5);
+        triangler.add(Im0, Im4, Im5);
+        triangler.add(Im1, Im0, Im5);
+        triangler.add(Im2, Im1, Im5);
 
-       for (i = 0; i <= ndice; i++)
-           for (j = 0; j < ndice*2; j++)
-               pt[i][j] = blend(conns, N, r, pt[i][j]) + p0;
+#endif
+       
 
-               
-       for (i = 0; i <= ndice; i++) {
-           for (j = 0; j < ndice*2; j++) {
-               ZVec px0 = pt[i==0 ? 0 : i-1][j];
-               ZVec px1 = pt[i==ndice ? ndice : i+1][j];
-               ZVec py0 = pt[i][j==0 ? 0 : j-1];
-               ZVec py1 = pt[i][j==ndice*2-1 ? ndice*2-1 : j+1];
+       triangler.dice(DiceCrit(verts, verts.noblend ? .01 * dicelen : 
dicelen));
 
-               norm[i][j] = (px1 - px0).crossp(py1 - py0).normalized();
-           }
+       if (verts.noblend) {
+           ZVec e0 = (t0.transform(ZVec(1,0,0)) - t0.transform(ZVec(0,0,0)));
+           ZVec e1 = (t0.transform(ZVec(0,1,0)) - t0.transform(ZVec(0,0,0)));
+           ZVec e2 = (t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)));
+           for (i = 0; i < (int)verts.size(); i++)
+               verts[i] = blend(conns, N, r, 
+                                e0 * verts[i].x + e1 * verts[i].y + e2 * 
verts[i].z);
+       }
+
+       // Compute normals
+       for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin(); 
+           x != triangler.tris.end(); x++) {
+           ZVec v0 = verts[x->v[1]] - verts[x->v[0]];
+           ZVec v1 = verts[x->v[2]] - verts[x->v[1]];
+           ZVec norm = v0.crossp(v1).normalized();
+           verts[x->v[0]].norm += norm;
+           verts[x->v[1]].norm += norm;
+           verts[x->v[2]].norm += norm;
        }
 
-       for (i = 0; i < ndice; i++) {
-           glBegin(GL_QUAD_STRIP);
-           for (j = 0; j < ndice*2-1; j++) {
-               glNormal(norm[i][j]);
-               glVertex(pt[i][j]);
-
-               glNormal(norm[i+1][j]);
-               glVertex(pt[i+1][j]);
-           }
-           glNormal(norm[i][0]);
-           glVertex(pt[i][0]);
-
-           glNormal(norm[i+1][0]);
-           glVertex(pt[i+1][0]);
-           glEnd();
+       for (i = 0; i < (int)verts.size(); i++)
+           verts[i] += p0;
+       
+       glBegin(GL_TRIANGLES);
+       for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin(); 
+           x != triangler.tris.end(); x++) {
+           glNormal(verts[x->v[0]].norm);
+           glVertex(verts[x->v[0]]);
+           glNormal(verts[x->v[1]].norm);
+           glVertex(verts[x->v[1]]);
+           glNormal(verts[x->v[2]].norm);
+           glVertex(verts[x->v[2]]);
        }
+       glEnd();
 
+#endif // use Dicer
 
        for (i = 0; i < N; i++) {
            delete conns[i];
Index: libvob/vob/fillet/light3d.py
diff -u libvob/vob/fillet/light3d.py:1.26 libvob/vob/fillet/light3d.py:1.27
--- libvob/vob/fillet/light3d.py:1.26   Tue Jul  1 10:32:56 2003
+++ libvob/vob/fillet/light3d.py        Thu Jul  3 09:18:59 2003
@@ -150,6 +150,7 @@
            SlideLin("linewidth", 2, 1, "line width", "B", "b"),
            Toggle("perspective", 0, "perspective", "F"),
            Toggle("texture", 0, "texture", "x"),
+           SlideLin("dicelen", 100, 5, "Dice length", "G", "g"),
 ]
 
 width = 0
@@ -231,7 +232,7 @@
            GLRen.createFillet3D(border, self.dice, 1),
            2)
 
-        conns3dblend = GLRen.createFillet3DBlend(self.dice);
+        conns3dblend = GLRen.createFillet3DBlend(self.dice, self.dicelen);
 
         thick = vs.coords.rational1D22(0, self.thick, 0, 0,  1, 1, 0);
         angle = vs.coords.rational1D22(0, self.angle, 0, 0,  1, 0, 0);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]