/[libvob]/libvob/include/vob/vobs/Fillet.hxx
ViewVC logotype

Diff of /libvob/include/vob/vobs/Fillet.hxx

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

revision 1.39 by jvk, Wed Jul 2 14:53:02 2003 UTC revision 1.40 by jvk, Thu Jul 3 13:18:59 2003 UTC
# Line 668  struct Fillet3DBlend { Line 668  struct Fillet3DBlend {
668      enum { NTrans = -1 };      enum { NTrans = -1 };
669    
670      int ndice;      int ndice;
671        float dicelen;
672    
673      template<class F> void params(F &f) {      template<class F> void params(F &f) {
674          f(ndice);          f(ndice, dicelen);
675      }      }
676    
677      template<class T> float crad(const T &t) const {      template<class T> float crad(const T &t) const {
# Line 683  struct Fillet3DBlend { Line 684  struct Fillet3DBlend {
684          StretchedCircleFillet f;          StretchedCircleFillet f;
685          ZVec dir;          ZVec dir;
686    
687            float da;
688            vector<float> rtbl;
689    
690          Conn(const CircularNode &node,          Conn(const CircularNode &node,
691               float d,               float d,
692               float th,               float th,
# Line 691  struct Fillet3DBlend { Line 695  struct Fillet3DBlend {
695              node(&node),              node(&node),
696              c(node, 0, d, th, -1, 0),              c(node, 0, d, th, -1, 0),
697              f(node, c, a), dir(dir) {              f(node, c, a), dir(dir) {
698                compute_rtbl(100);
699          }          }
700    
701          Vec trans(ZVec v) const {          Vec trans(ZVec v) const {
# Line 700  struct Fillet3DBlend { Line 705  struct Fillet3DBlend {
705          }          }
706    
707          float rad(ZVec v, bool &success) const {          float rad(ZVec v, bool &success) const {
708              Vec t = trans(v).normalized();              Vec t = trans(v);
709                if (rtbl.size()) {
710                    success = true;
711                    return rad_rtbl(t);
712                }
713              ZVec pt = f.point(t, success);              ZVec pt = f.point(t, success);
714              if (success) return pt.length();              if (success) return pt.length();
715              if (f.infillet(t)) {              if (f.infillet(t)) {
# Line 710  struct Fillet3DBlend { Line 719  struct Fillet3DBlend {
719              }              }
720              return node->r;              return node->r;
721          }          }
722    
723            void compute_rtbl(int n) {
724                rtbl.resize(n + 1);
725                for (int i = 0; i < n; i++) {
726                    float t = i * (1.0 / n);
727                    float a = (t * t) * f.tangentAngle;
728                    bool success;
729                    float fract;
730                    ZVec pt = f.point(dirVec(a), success, &fract, .001);
731                    if (success)
732                        rtbl[i] = pt.length();
733                    else
734                        rtbl[i] = c.d / cos(a);
735                    //cout << i << ": " << rtbl[i] << pt << fract << std::endl;
736                }
737                rtbl[n] = node->r;
738            }
739    
740            float rad_rtbl(Vec v) const {
741                int n = rtbl.size() - 1;
742                float a = v.atan();
743                float t = sqrt(a / f.tangentAngle);
744                unsigned i = (unsigned)(t * n);
745                float fract = t * n - i;
746                if (i >= n) return rtbl[n];
747                return (1 - fract) * rtbl[i] + fract * rtbl[i + 1];
748            }
749      };      };
750    
751      ZVec blend(Conn *conns[], int N, float r, ZVec pt) const {      ZVec blend(Conn *conns[], int N, float r, ZVec pt) const {
# Line 717  struct Fillet3DBlend { Line 753  struct Fillet3DBlend {
753          float sum = 0;          float sum = 0;
754          float x[N];          float x[N];
755    
756            pt = pt.normalized();
757    
758          // Compute distances from the node for each fillet surface          // Compute distances from the node for each fillet surface
759          for (i = 0; i < N; i++) {          for (i = 0; i < N; i++) {
760              bool success;              bool success;
761              float t = conns[i]->rad(pt, success);              float t = conns[i]->rad(pt, success);
762              if (success)              if (success)
763                  sum += x[num++] = (t - r) / r;                  sum += x[num++] = t - r;
764          }          }
765    
766          // Compute p for an l^p norm to be used as the blending function          // Compute p for an l^p norm to be used as the blending function
767          // p == 1: sum of distances,          // p == 1: sum of distances,
768          // p == \infty: maximum of distances          // p == \infty: maximum of distances
769          float p = 1.0 + sum;          float p = 1.0 + sum / r;
770    
771          sum = 0;          sum = 0;
772          for (i = 0; i < num; i++)          for (i = 0; i < num; i++)
773              sum += pow(x[i], p);              sum += pow(x[i], p);
774                    
775          return pt * (1 + pow(sum, 1 / p));          return pt * (r + pow(sum, 1 / p));
776    
777      }      }
778    
779      struct Vert : ZVec {      struct Vert : ZVec {
780          bool bound;          int id;
781          ZVec norm;          ZVec norm;
782          Vert(const ZVec &v, bool b = false) : ZVec(v), bound(b) {}          Vert(const ZVec &v, int id = 0) : ZVec(v), id(id) {}
783      };      };
784    
785      struct Verts : std::vector<Vert> {      struct Verts : std::vector<Vert> {
# Line 749  struct Fillet3DBlend { Line 787  struct Fillet3DBlend {
787          Conn **conns;          Conn **conns;
788          int N;          int N;
789          float r;          float r;
790            bool noblend;
791    
792          int append(ZVec v, bool b = false) {          int append(ZVec v, int id = 0) {
793              int ind = size();              int ind = size();
794              if (b)              if (id || noblend)
795                  push_back(Vert(v, b));                  push_back(Vert(v, id));
796              else              else
797                  push_back(f.blend(conns, N, r, v));                  push_back(f.blend(conns, N, r, v));
798    
# Line 761  struct Fillet3DBlend { Line 800  struct Fillet3DBlend {
800          }          }
801    
802          int operator() (int i, int j, float fract = .5) {          int operator() (int i, int j, float fract = .5) {
803              int ind = size();              return append(lerp(operator[](i), operator[](j), fract));
             push_back(f.blend(conns, N, r,  
                               lerp(operator[](i), operator[](j), fract)));  
             return ind;  
804          }          }
805    
806          Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) :          Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) :
807              f(f), conns(conns), N(N), r(r) {}              f(f), conns(conns), N(N), r(r), noblend(false) {}
808      };      };
809    
810      struct DiceCrit {      struct DiceCrit {
# Line 778  struct Fillet3DBlend { Line 814  struct Fillet3DBlend {
814          DiceCrit(const Verts &v, float dicelen) : v(v), dicelen(dicelen) {}          DiceCrit(const Verts &v, float dicelen) : v(v), dicelen(dicelen) {}
815    
816          int operator()(int i, int j, int k) {          int operator()(int i, int j, int k) {
817              float l0 = (v[i] - v[j]).length() * !(v[i].bound && v[j].bound);              if (dicelen >= 1000) return -1;
818              float l1 = (v[j] - v[k]).length() * !(v[j].bound && v[k].bound);  
819              float l2 = (v[k] - v[i]).length() * !(v[k].bound && v[i].bound);              if (v[i].id && v[j].id && v[i].id != v[j].id) return 0;
820                if (v[j].id && v[k].id && v[j].id != v[k].id) return 1;
821                if (v[k].id && v[i].id && v[k].id != v[i].id) return 2;
822    
823                float l0 = (v[i] - v[j]).length() * !(v[i].id && v[i].id == v[j].id);
824                float l1 = (v[j] - v[k]).length() * !(v[j].id && v[j].id == v[k].id);
825                float l2 = (v[k] - v[i]).length() * !(v[k].id && v[k].id == v[i].id);
826    
827              if (l0 < dicelen && l1 < dicelen && l2 < dicelen)              if (l0 < dicelen && l1 < dicelen && l2 < dicelen)
828                  return -1;                  return -1;
# Line 804  struct Fillet3DBlend { Line 846  struct Fillet3DBlend {
846          }          }
847    
848          i = k0;          i = k0;
849          do {          while (1) {
850              poly.push_back(i);              poly.push_back(i);
851                if (i == k1) break;
852              if (++i == i1) i = i0;              if (++i == i1) i = i0;
853          } while (i != k1);          }
854                    
855      }      }
856    
# Line 825  struct Fillet3DBlend { Line 868  struct Fillet3DBlend {
868          Conn* conns[N];          Conn* conns[N];
869    
870          std::vector<ZVec> dirs;          std::vector<ZVec> dirs;
         std::vector<int3> tri;  
   
871          int i, j;          int i, j;
872    
873          for (i = 0; i < N; i++) {          for (i = 0; i < N; i++) {
874              const Transform &t1 = *t[3 + i];              const Transform &t1 = *t[3 + i];
875              ZVec p1 = t1.transform(0.5 * t1.getSqSize());              ZVec p1 = t1.transform(0.5 * t1.getSqSize());
# Line 841  struct Fillet3DBlend { Line 883  struct Fillet3DBlend {
883              dirs.push_back((p1 - p0).normalized());              dirs.push_back((p1 - p0).normalized());
884          }          }
885    
886    #if 1 // Old  version without Dicer
887    
888            ZVec pt[ndice + 1][ndice*2];
889            ZVec norm[ndice + 1][ndice*2];
890    
891            for (i = 0; i <= ndice; i++) {
892                float a = i * M_PI / ndice;
893                float x = cos(a);
894                float R = sin(a);
895    
896                for (j = 0; j < ndice*2; j++) {
897                    float b = j * M_PI * 2 / (ndice*2);
898    
899                    float y = cos(b) * R;
900                    float z = sin(b) * R;
901    
902                    pt[i][j] = r * ZVec(x, y, z);
903                }
904            }
905    
906    
907            for (i = 0; i <= ndice; i++)
908                for (j = 0; j < ndice*2; j++)
909                    pt[i][j] = blend(conns, N, r, pt[i][j]) + p0;
910    
911                    
912            for (i = 0; i <= ndice; i++) {
913                for (j = 0; j < ndice*2; j++) {
914                    ZVec px0 = pt[i==0 ? 0 : i-1][j];
915                    ZVec px1 = pt[i==ndice ? ndice : i+1][j];
916                    ZVec py0 = pt[i][j==0 ? 0 : j-1];
917                    ZVec py1 = pt[i][j==ndice*2-1 ? ndice*2-1 : j+1];
918    
919                    norm[i][j] = (px1 - px0).crossp(py1 - py0).normalized();
920                }
921            }
922    
923            for (i = 0; i < ndice; i++) {
924                glBegin(GL_QUAD_STRIP);
925                for (j = 0; j < ndice*2-1; j++) {
926                    glNormal(norm[i][j]);
927                    glVertex(pt[i][j]);
928    
929                    glNormal(norm[i+1][j]);
930                    glVertex(pt[i+1][j]);
931                }
932                glNormal(norm[i][0]);
933                glVertex(pt[i][0]);
934    
935                glNormal(norm[i+1][0]);
936                glVertex(pt[i+1][0]);
937                glEnd();
938            }
939    
940    #else // use Dicer
941    
942            Verts verts(*this, conns, N, r);
943            ::Vob::Dicer::Triangles<Verts> triangler(verts);
944    
945    #if 0 // use Delaunay triangulation based topology
946    
947          if (dirs.size() == 2) {          if (dirs.size() == 2) {
948              ZVec sum = dirs[0] + dirs[1];              ZVec sum = dirs[0] + dirs[1];
949              ZVec dif = dirs[1] - dirs[0];              ZVec dif = dirs[1] - dirs[0];
# Line 851  struct Fillet3DBlend { Line 954  struct Fillet3DBlend {
954              dirs.push_back((v0 + v1).normalized());              dirs.push_back((v0 + v1).normalized());
955          }          }
956    
957            std::vector<int3> tri;
958          Triangulate(dirs, dirs.size(), tri);          Triangulate(dirs, dirs.size(), tri);
959    
960          {          {
# Line 873  struct Fillet3DBlend { Line 977  struct Fillet3DBlend {
977              }              }
978          }          }
979                            
980            /*
   
981          for (i = 0; i < (int)tri.size(); i++) {          for (i = 0; i < (int)tri.size(); i++) {
982              glBegin(GL_LINE_LOOP);              glBegin(GL_LINE_LOOP);
983              glVertex(p0 + 3 * r * dirs[tri[i][0]]);              glVertex(p0 + 3 * r * dirs[tri[i][0]]);
# Line 882  struct Fillet3DBlend { Line 985  struct Fillet3DBlend {
985              glVertex(p0 + 3 * r * dirs[tri[i][2]]);              glVertex(p0 + 3 * r * dirs[tri[i][2]]);
986              glEnd();              glEnd();
987          }          }
988            */
989    
990          // Add the vertices of the diced midsections of the connectors          // Add the vertices of the diced midsections of the connectors
         Verts verts(*this, conns, N, r);  
991          for (i = 0; i < N; i++) {          for (i = 0; i < N; i++) {
992              float t = 0.5 * conns[i]->c.t;              float t = 0.5 * conns[i]->c.t;
993              float d = conns[i]->c.d;              float d = conns[i]->c.d;
994    
995                ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0));
996              ZVec e0 = conns[i]->dir;              ZVec e0 = conns[i]->dir;
997              ZVec e1 = e0.crossp(ZVec(0,0,1));              ZVec e1 = e0.crossp(ref).normalized();
998              ZVec e2 = e0.crossp(e1);              ZVec e2 = e0.crossp(e1);
999    
1000              ZVec p0 = d * e0;              ZVec p0 = d * e0;
1001    
1002              for (j = 0; j < ndice; j++) {              for (j = 0; j < ndice; j++) {
1003                  float a = j * M_PI * 2 / ndice;                  float a = -j * M_PI * 2 / ndice;
1004                  verts.append(p0 + t * (e1 * cos(a) + e2 * sin(a)), true);                  verts.append(p0 + t * (e1 * cos(a) + e2 * sin(a)), i + 1);
1005              }              }
1006          }          }
1007    
# Line 909  struct Fillet3DBlend { Line 1012  struct Fillet3DBlend {
1012          }          }
1013    
1014          // Triangulate the surface          // Triangulate the surface
         ::Vob::Dicer::Triangles<Verts> triangler(verts);  
1015          for (i = 0; i < (int)tri.size(); i++) {          for (i = 0; i < (int)tri.size(); i++) {
1016              std::vector<int> poly;              std::vector<int> poly;
1017              for (j = 0; j < 3; j++) {              for (j = 0; j < 3; j++) {
# Line 919  struct Fillet3DBlend { Line 1021  struct Fillet3DBlend {
1021                  } else {                  } else {
1022                      int k0 = tri[i][(j+1)%3];                      int k0 = tri[i][(j+1)%3];
1023                      int k1 = tri[i][(j+2)%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  
1024                                                    
1025                      addSpan(poly, verts, ndice * k, ndice * (k + 1), dirs[k0], dirs[k1]);                      addSpan(poly, verts, ndice * k, ndice * (k + 1), dirs[k1], dirs[k0]);
1026                  }                  }
1027              }              }
1028    
1029              // Triangulate as a star polygon              // Triangulate as a star polygon
1030              ZVec sum(0,0,0);              ZVec sum(0,0,0);
1031              for (j = 0; j < (int)poly.size(); j++)              for (j = 0; j < (int)poly.size(); j++)
1032                  sum += verts[poly[j]];                  sum += verts[poly[j]].normalized();
1033    
1034                int nvert = verts.append(dirs[tri[i][0]] +
1035                                         dirs[tri[i][1]] +
1036                                         dirs[tri[i][2]]);
1037    
             int nvert = verts.append(sum);  
1038              for (j = 0; j < (int)poly.size(); j++)              for (j = 0; j < (int)poly.size(); j++)
1039                  triangler.add(nvert, poly[j], poly[(j+1) % poly.size()]);                  triangler.add(nvert, poly[j], poly[(j+1) % poly.size()]);
1040          }          }
           
   
   
         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);  
1041    
1042                  float y = cos(b) * R;  #else // Icosahedron topology
                 float z = sin(b) * R;  
1043    
1044                  pt[i][j] = r * ZVec(x, y, z);          // icosahedron code adapted from sphere.c found in
1045              }          // http://www.sgi.com/Technology/openGL/advanced/programs.html
         }  
1046    
1047    /* for icosahedron */
1048    #define CZ_ (0.89442719099991)   /*  2/sqrt(5) */
1049    #define SZ_ (0.44721359549995)   /*  1/sqrt(5) */
1050    #define C1_ (0.951056516)        /* cos(18),  */
1051    #define S1_ (0.309016994)        /* sin(18) */
1052    #define C2_ (0.587785252)        /* cos(54),  */
1053    #define S2_ (0.809016994)        /* sin(54) */
1054    #define X1_ (C1_*CZ_)
1055    #define Y1_ (S1_*CZ_)
1056    #define X2_ (C2_*CZ_)
1057    #define Y2_ (S2_*CZ_)
1058    
1059            verts.noblend = true;
1060            int Ip0 = verts.append(ZVec(  0.,    0.,    1.));
1061            int Ip1 = verts.append(ZVec(-X2_,  -Y2_,   SZ_));
1062            int Ip2 = verts.append(ZVec( X2_,  -Y2_,   SZ_));
1063            int Ip3 = verts.append(ZVec( X1_,   Y1_,   SZ_));
1064            int Ip4 = verts.append(ZVec(  0,    CZ_,   SZ_));
1065            int Ip5 = verts.append(ZVec(-X1_,   Y1_,   SZ_));
1066            
1067            int Im0 = verts.append(ZVec(-X1_,  -Y1_,  -SZ_));
1068            int Im1 = verts.append(ZVec(  0,   -CZ_,  -SZ_));
1069            int Im2 = verts.append(ZVec( X1_,  -Y1_,  -SZ_));
1070            int Im3 = verts.append(ZVec( X2_,   Y2_,  -SZ_));
1071            int Im4 = verts.append(ZVec(-X2_,   Y2_,  -SZ_));
1072            int Im5 = verts.append(ZVec(  0.,    0.,   -1.));
1073    
1074            /* front pole */
1075            triangler.add(Ip0, Ip1, Ip2);
1076            triangler.add(Ip0, Ip5, Ip1);
1077            triangler.add(Ip0, Ip4, Ip5);
1078            triangler.add(Ip0, Ip3, Ip4);
1079            triangler.add(Ip0, Ip2, Ip3);
1080    
1081            /* mid */
1082            triangler.add(Ip1, Im0, Im1);
1083            triangler.add(Im0, Ip1, Ip5);
1084            triangler.add(Ip5, Im4, Im0);
1085            triangler.add(Im4, Ip5, Ip4);
1086            triangler.add(Ip4, Im3, Im4);
1087            triangler.add(Im3, Ip4, Ip3);
1088            triangler.add(Ip3, Im2, Im3);
1089            triangler.add(Im2, Ip3, Ip2);
1090            triangler.add(Ip2, Im1, Im2);
1091            triangler.add(Im1, Ip2, Ip1);
1092    
1093            /* back pole */
1094            triangler.add(Im3, Im2, Im5);
1095            triangler.add(Im4, Im3, Im5);
1096            triangler.add(Im0, Im4, Im5);
1097            triangler.add(Im1, Im0, Im5);
1098            triangler.add(Im2, Im1, Im5);
1099    
1100          for (i = 0; i <= ndice; i++)  #endif
1101              for (j = 0; j < ndice*2; j++)          
                 pt[i][j] = blend(conns, N, r, pt[i][j]) + p0;  
1102    
1103                            triangler.dice(DiceCrit(verts, verts.noblend ? .01 * dicelen : dicelen));
         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];  
1104    
1105                  norm[i][j] = (px1 - px0).crossp(py1 - py0).normalized();          if (verts.noblend) {
1106              }              ZVec e0 = (t0.transform(ZVec(1,0,0)) - t0.transform(ZVec(0,0,0)));
1107                ZVec e1 = (t0.transform(ZVec(0,1,0)) - t0.transform(ZVec(0,0,0)));
1108                ZVec e2 = (t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)));
1109                for (i = 0; i < (int)verts.size(); i++)
1110                    verts[i] = blend(conns, N, r,
1111                                     e0 * verts[i].x + e1 * verts[i].y + e2 * verts[i].z);
1112            }
1113    
1114            // Compute normals
1115            for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin();
1116                x != triangler.tris.end(); x++) {
1117                ZVec v0 = verts[x->v[1]] - verts[x->v[0]];
1118                ZVec v1 = verts[x->v[2]] - verts[x->v[1]];
1119                ZVec norm = v0.crossp(v1).normalized();
1120                verts[x->v[0]].norm += norm;
1121                verts[x->v[1]].norm += norm;
1122                verts[x->v[2]].norm += norm;
1123          }          }
1124    
1125          for (i = 0; i < ndice; i++) {          for (i = 0; i < (int)verts.size(); i++)
1126              glBegin(GL_QUAD_STRIP);              verts[i] += p0;
1127              for (j = 0; j < ndice*2-1; j++) {          
1128                  glNormal(norm[i][j]);          glBegin(GL_TRIANGLES);
1129                  glVertex(pt[i][j]);          for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin();
1130                x != triangler.tris.end(); x++) {
1131                  glNormal(norm[i+1][j]);              glNormal(verts[x->v[0]].norm);
1132                  glVertex(pt[i+1][j]);              glVertex(verts[x->v[0]]);
1133              }              glNormal(verts[x->v[1]].norm);
1134              glNormal(norm[i][0]);              glVertex(verts[x->v[1]]);
1135              glVertex(pt[i][0]);              glNormal(verts[x->v[2]].norm);
1136                glVertex(verts[x->v[2]]);
             glNormal(norm[i+1][0]);  
             glVertex(pt[i+1][0]);  
             glEnd();  
1137          }          }
1138            glEnd();
1139    
1140    #endif // use Dicer
1141    
1142          for (i = 0; i < N; i++) {          for (i = 0; i < N; i++) {
1143              delete conns[i];              delete conns[i];

Legend:
Removed from v.1.39  
changed lines
  Added in v.1.40

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