gzz-commits
[Top][All Lists]
Advanced

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

[Gzz-commits] libvob include/vob/Vec23.hxx include/vob/geom/F...


From: Tuomas J. Lukka
Subject: [Gzz-commits] libvob include/vob/Vec23.hxx include/vob/geom/F...
Date: Mon, 02 Jun 2003 14:18:42 -0400

CVSROOT:        /cvsroot/libvob
Module name:    libvob
Changes by:     Tuomas J. Lukka <address@hidden>        03/06/02 14:18:42

Modified files:
        include/vob    : Vec23.hxx 
        include/vob/geom: Fillets2.hxx Quadrics.hxx 
        include/vob/vobs: Fillet.hxx 
        vob/demo/multifil: multifil.py 

Log message:
        Fillets clearer implementation

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/Vec23.hxx.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/geom/Fillets2.hxx.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/geom/Quadrics.hxx.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/vobs/Fillet.hxx.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/vob/demo/multifil/multifil.py.diff?tr1=1.3&tr2=1.4&r1=text&r2=text

Patches:
Index: libvob/include/vob/Vec23.hxx
diff -u libvob/include/vob/Vec23.hxx:1.8 libvob/include/vob/Vec23.hxx:1.9
--- libvob/include/vob/Vec23.hxx:1.8    Thu May 29 04:00:20 2003
+++ libvob/include/vob/Vec23.hxx        Mon Jun  2 14:18:41 2003
@@ -104,7 +104,7 @@
        /** Cross this 2D vector with another - 
         * gives the sine of the angle between the two,
         * multiplied by the lengths.
-        * Useful for telling which side of a given vector you are.
+        * Useful for telling which side of a given vector you are on.
         */
        double cross(const Vector<T> &v) const {
            return x * v.y - y * v.x;
Index: libvob/include/vob/geom/Fillets2.hxx
diff -u libvob/include/vob/geom/Fillets2.hxx:1.1 
libvob/include/vob/geom/Fillets2.hxx:1.2
--- libvob/include/vob/geom/Fillets2.hxx:1.1    Sun Jun  1 07:49:15 2003
+++ libvob/include/vob/geom/Fillets2.hxx        Mon Jun  2 14:18:41 2003
@@ -14,7 +14,21 @@
     struct FilletSpanConcept {
        /** Get the point on this part of the edge.
         */
-       ZVec point(float fract, ZVec *intern = 0) {
+       ZVec point(float fract, ZVec *intern = 0) const {
+           return ZVec(0,0,0);
+       }
+    };
+
+    /** Concept: a blendable span of edge.
+     * Usually, the 0-side is the connection and 1 is
+     * return to circle (or other point).
+     */
+    struct BlendableFilletSpanConcept : public FilletSpanConcept{
+       /** Get the point on a given direction vector.
+        * @param dir The unit direction vector from the center.
+        * @param success Boolean into which to return whether there was 
something.
+        */
+       ZVec point(Vec dir, bool *success) {
            return ZVec(0,0,0);
        }
     };
@@ -22,18 +36,218 @@
     /** A circular node.
      */
     struct CircularNode {
+       /** The center of the node.
+        */
        ZVec ctr;
+       /** The radius of the node.
+        */
        float r;
+
+       CircularNode(ZVec ctr, float r) : ctr(ctr), r(r) { }
+
+       ZVec point(Vec dir) {
+           return ctr + r * dir;
+       }
     };
 
-    /** A connection  
+    /** A connection. The node is assumed to be known.
+     */
+    struct LinearConnectionHalf {
+       const CircularNode &node;
+
+       /** The compass angle of the connection.
+        */
+       float a;
+       /** The distance from the center to the middle of the connection.
+        */
+       float d;
+       /** The thickness of the connection at the middle.
+        */
+       float t;
+       /** Whether we're looking at the clockwise or counterclockwise side.
+        */
+       int sign;
+       /** The z coordinate of the middle.
+        */
+       float z;
+
+       /////////////////////////////////
+       // The following data members are derivable from the already mentioned 
ones.
+       // They are calculated here to be cached.
+
+       /** The direction (unit) vector.
+        */
+       Vec dir;
+
+       /** The normal (unit) vector.
+        */
+       Vec norm;
+
+       /** The endpoint of the edge.
+        */
+       ZVec endPoint;
+
+       LinearConnectionHalf(
+               const CircularNode &node,
+               float a, 
+               float d,
+               float t, 
+               int sign,
+               float z) :
+                   node(node),
+                   a(a),
+                   d(d),
+                   t(t),
+                   sign(sign),
+                   z(z) {
+           dir = dirVec(a);
+           norm = dir.cw90() * sign;
+           endPoint = node.ctr + d * dir + t/2 * norm;
+       }
+
+       /** Project a given point to the connecting line.
+        * If the point would go to the negative direction (or inside the 
circular
+        * node) on the connection
+        * line, it will be clamped to the center.
+        * Useful for generating internal points.
+        */
+       ZVec projectToConnLine(ZVec v) const {
+           v = v - norm.dot(v-node.ctr) * norm;
+           if(dir.dot(v-node.ctr) <= node.r) {
+               v = v - dir.dot(v-node.ctr) * dir;
+           }
+           v.z = lerp(node.ctr.z, z, (dir.dot(v-node.ctr) - node.r) / (d - 
node.r));
+           return v;
+       }
+
+    };
 
     /** A circular fillet edge span, for a circular node.
      */
     struct CircleCircleFillet {
+       const CircularNode &node;
+       const LinearConnectionHalf &conn;
+
+       Vec fcenter;
+       float frad;
+
+       /** The direction vector from the center of the node
+        * to the point where
+        * the two circles are tangent.
+        */
+       Vec dirtang;
+
+       float dtsign;
+
+       float astart;
+       float aend;
+
        CircleCircleFillet(
-               CircularNode &n,
+               const CircularNode &node,
+               const LinearConnectionHalf &conn) : node(node), conn(conn) {
+           this->fcenter = 
+               circle__point_norm_circle(conn.endPoint, conn.norm, node.ctr, 
node.r);
+           this->frad = 
+               (fcenter - conn.endPoint).length();
+           this->dirtang = (fcenter - node.ctr) . normalized();
+           this->dtsign = dirtang.cross(conn.dir);
+           this->astart = Vec(conn.endPoint - fcenter).atan();
+           this->aend = Vec(node.ctr - fcenter).atan();
+           while(aend - astart >= M_PI) aend -= 2 * M_PI;
+           while(astart - aend >= M_PI) aend += 2 * M_PI;
+       }
+
+       /** For blending, we want to stop the fillet halfway to avoid
+        * overdraw and strange shapes while cleaving.
+        */
+       void cutEnd(Vec dir) {
+           bool success;
+           ZVec in = project2circle(node.ctr + dir, node.ctr, fcenter,
+                       frad, -1, &success);
+           if(success) return;
+           this->aend = Vec(in-fcenter).atan();
+           while(aend - astart >= M_PI) aend -= 2 * M_PI;
+           while(astart - aend >= M_PI) aend += 2 * M_PI;
+       }
+
+       ZVec point(float fract, ZVec *intern = 0) const {
+           ZVec pt = fcenter + frad * dirVec(lerp(astart, aend, fract));
+           ZVec proj = conn.projectToConnLine(pt);
+           pt.z = proj.z;
+           if(intern) *intern = proj;
+           return pt;
+       }
+
+       ZVec point(Vec dir, bool &success) const {
+           if(dirtang.cross(dir) * dtsign < 0) {
+               success = false;
+               return ZVec(0,0,0);
+           }
+           ZVec in = project2circle(node.ctr + dir, node.ctr, fcenter,
+                       frad, -1, &success);
+           if(!success) return ZVec(0,0,0);
+           ZVec proj = conn.projectToConnLine(in);
+           in.z = proj.z;
+           return in;
+       }
+
+       bool infillet(Vec dir) const {
+           return dirtang.cross(conn.dir) * dirtang.cross(dir) >= 0 &&
+               conn.dir.cross(dirtang) * conn.dir.cross(dir) >= 0;
+       }
+       bool overlaps(const CircleCircleFillet &other) const {
+           return infillet(other.dirtang) || other.infillet(dirtang);
+       }
 
     };
+
+    /** A blend of two fillets.
+     * Note that this is only one side of the blend!
+     */
+    struct FilletBlend {
+       CircleCircleFillet main;
+       const CircleCircleFillet &other;
+
+       FilletBlend(const CircleCircleFillet &main0, 
+                   const CircleCircleFillet &other) :
+               main(main0), other(other) {
+           Vec cutdir = (main.dirtang + other.dirtang).normalized();
+           main.cutEnd(cutdir);
+       }
+
+       ZVec point(float fract, ZVec *intern = 0) const {
+           ZVec p = main.point(fract, intern);
+           bool success;
+           ZVec p2 = other.point(Vec(p-main.node.ctr).normalized(), success);
+           ZVec res;
+           if(success) {
+               ZVec edgep = .5 *(p + p2 - 2 * main.node.ctr);
+               edgep *= main.node.r / edgep.xylength();
+               edgep += main.node.ctr;
+               res = p + p2 - edgep;
+           } else {
+               res = p;
+           } 
+           return res;
+       }
+    };
+
+
+    struct CircularNodeSpan {
+       const CircularNode &node;
+       float astart;
+       float aend;
+       CircularNodeSpan(const CircularNode &node, 
+                       float astart, float aend)  :
+               node(node), astart(astart), aend(aend) {
+       }
+
+       ZVec point(float fract, ZVec *intern = 0) const {
+           if(intern) *intern = node.ctr;
+           return node.ctr + node.r * dirVec(lerp(astart, aend, fract));
+       }
+
+    };
+
 }
 }
Index: libvob/include/vob/geom/Quadrics.hxx
diff -u libvob/include/vob/geom/Quadrics.hxx:1.3 
libvob/include/vob/geom/Quadrics.hxx:1.4
--- libvob/include/vob/geom/Quadrics.hxx:1.3    Thu May 29 04:00:20 2003
+++ libvob/include/vob/geom/Quadrics.hxx        Mon Jun  2 14:18:42 2003
@@ -1,5 +1,8 @@
 // (c) Tuomas J. Lukka
 
+#ifndef VOB_GEOM_QUADRICS
+#define VOB_GEOM_QUADRICS
+
 #include <vob/Vec23.hxx>
 
 namespace Vob {
@@ -67,3 +70,6 @@
 
 }
 }
+
+
+#endif
Index: libvob/include/vob/vobs/Fillet.hxx
diff -u libvob/include/vob/vobs/Fillet.hxx:1.5 
libvob/include/vob/vobs/Fillet.hxx:1.6
--- libvob/include/vob/vobs/Fillet.hxx:1.5      Fri May 30 10:47:09 2003
+++ libvob/include/vob/vobs/Fillet.hxx  Mon Jun  2 14:18:42 2003
@@ -40,6 +40,7 @@
 #include <vob/glerr.hxx>
 
 #include <vob/geom/Fillets.hxx>
+#include <vob/geom/Fillets2.hxx>
 
 #ifndef VOB_DEFINED
 #define VOB_DEFINED(t)
@@ -174,8 +175,6 @@
        FilletSpan sp(ctr, csize,
                a1, d1, th1, lerp(p0.z, p1.z, .5),
                a2, d2, th2, lerp(p0.z, p2.z, .5));
-       // Render it. XXX -- jvk, you need to make this
-       // render the solid fillet.
        if(!(flags & 8)) {
            if(sp.split()) {
                if(flags & 1) {
@@ -257,7 +256,135 @@
     }
 };
 
+
 VOB_DEFINED(FilletSpan1);
+
+struct FilletSpan2 {
+    enum { NTrans = 3 };
+
+    int ndice;
+    int flags;
+
+    template<class T> float crad(const T &t) const {
+       return t.getSqSize().x;
+    }
+    template<class T> float th(const T &t0, const T &t1, float d) const {
+       float r0 = crad(t0);
+       float r1 = crad(t1);
+       float rmax = r0 >? r1;
+       float rmin = r0 <? r1;
+       if(d <= rmax - rmin) return .96 * rmin;
+       float dr = (d - (rmax-rmin)) / (r0 + r1);
+       return .96 * rmin *  1 / (1 + dr);
+    }
+    
+    template<class F> void params(F &f) {
+       f(ndice, flags);
+    }
+
+    void v(ZVec p) const {
+       if(flags & 4) {
+           glColor3f(1, p.z / 100, p.z / 100);
+       }
+       glVertex(p);
+    }
+
+    void vl(ZVec p) const {
+       if(flags & 4) {
+           glColor3f(0,p.z / 100, p.z / 100);
+       }
+       glVertex(p);
+    }
+
+    template<class G> void renderSpanSolid(const G &g) const {
+       glBegin(GL_QUAD_STRIP); 
+       for(int i=0; i<ndice; i++) {
+           float fract = i / (ndice-1.0);
+           ZVec intern;
+           ZVec pt = g.point(fract, &intern);
+           v(pt);
+           v(intern);
+       }
+       glEnd();
+    }
+
+    template<class G> void renderSpanLine(const G &g) const {
+       glBegin(GL_LINE_STRIP); 
+       for(int i=0; i<ndice; i++) {
+           float fract = i / (ndice-1.0);
+           ZVec pt = g.point(fract, 0);
+           vl(pt);
+       }
+       glEnd();
+    }
+
+    template<class G> void renderSpan(const G &g) const {
+       if(flags & 1) 
+           renderSpanSolid(g);
+       if(flags & 2) 
+           renderSpanLine(g);
+    }
+
+
+
+    template<class T> void render(const T &t0, const T &t1, const T &t2) 
+           const {
+       ZVec p0 = t0.transform(t0.getSqSize());
+       ZVec p1 = t1.transform(t1.getSqSize()) ;
+       ZVec p2 = t2.transform(t2.getSqSize()) ;
+
+       ZVec ctr = p0;
+       Vec v1 = p1 - ctr;
+       Vec v2 = p2 - ctr;
+
+       DBG(dbg_vfillets) << "FilletSpan "<<ctr<<" "<<v1<<" "<<v2<<"\n";
+
+       float a1 = v1.atan();
+       float a2 = v2.atan();
+       if(a2 < a1 || &t1 == &t2) a2 += 2*M_PI;
+
+       float d1 = v1.length() / 2;
+       float d2 = v2.length() / 2;
+
+       float th1 = th(t0, t1, d1);
+       float th2 = th(t0, t2, d2);
+
+       float csize = crad(t0);
+
+       DBG(dbg_vfillets) << "P: "<<ctr<<" "<<csize<<" "<<
+                   a1<<" "<<d1<<" "<<th1<<" "<<
+                   a2<<" "<<d2<<" "<<th2<<" "<<
+                   "\n";
+
+       CircularNode node(ctr, csize);
+       LinearConnectionHalf c1(node, a1, d1, th1, 1, lerp(p0.z, p1.z, .5));
+       LinearConnectionHalf c2(node, a2, d2, th2, -1, lerp(p0.z, p2.z, .5));
+
+       CircleCircleFillet f1(node, c1);
+       CircleCircleFillet f2(node, c2);
+
+       // Find out how close they are.
+/*     if(a2-a1 < M_PI &&
+               (f1.containsConnection(f2) ||
+                f2.containsConnection(f1))) {
+           // Cleaved case
+       } else */ if(f1.overlaps(f2)) {
+           renderSpan(FilletBlend(f1, f2));
+           renderSpan(FilletBlend(f2, f1));
+       } else {
+           renderSpan(f1);
+           float ta1 = f1.dirtang.atan();
+           float ta2 = f2.dirtang.atan();
+           if(ta2 < ta1) ta2 += 2*M_PI;
+           renderSpan(CircularNodeSpan(node, ta1, ta2));
+           renderSpan(f2);
+       }
+
+    }
+
+
+};
+VOB_DEFINED(FilletSpan2);
 
 }
 }
Index: libvob/vob/demo/multifil/multifil.py
diff -u libvob/vob/demo/multifil/multifil.py:1.3 
libvob/vob/demo/multifil/multifil.py:1.4
--- libvob/vob/demo/multifil/multifil.py:1.3    Fri May 30 10:47:09 2003
+++ libvob/vob/demo/multifil/multifil.py        Mon Jun  2 14:18:42 2003
@@ -39,9 +39,9 @@
 
        dice = 200
        conns = GLRen.createSortedConnections(
-           GLRen.createFilletSpan1(dice, 1 + 4*self.depthColor + 
8*(1-self.fillets)))
+           GLRen.createFilletSpan2(dice, 1 + 4*self.depthColor + 
8*(1-self.fillets)))
        conns_l = GLRen.createSortedConnections(
-           GLRen.createFilletSpan1(dice, 2 + 4*self.depthColor + 
8*(1-self.fillets)))
+           GLRen.createFilletSpan2(dice, 2 + 4*self.depthColor + 
8*(1-self.fillets)))
 
        size = 50
        




reply via email to

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