608 |
|
|
609 |
ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)); |
ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)); |
610 |
ZVec e0 = (p1 - p0).normalized(); |
ZVec e0 = (p1 - p0).normalized(); |
611 |
ZVec e1 = e0.crossp(ref).normalized(); |
ZVec e1 = ref.crossp(e0).normalized(); |
612 |
ZVec e2 = e0.crossp(e1); |
ZVec e2 = e0.crossp(e1); |
613 |
|
|
614 |
float mat[16] = { |
float mat[16] = { |
670 |
|
|
671 |
int ndice; |
int ndice; |
672 |
float dicelen; |
float dicelen; |
673 |
|
int tblsize; |
674 |
|
|
675 |
template<class F> void params(F &f) { |
template<class F> void params(F &f) { |
676 |
f(ndice, dicelen); |
f(ndice, dicelen, tblsize); |
677 |
} |
} |
678 |
|
|
679 |
template<class T> float crad(const T &t) const { |
template<class T> float crad(const T &t) const { |
682 |
|
|
683 |
typedef Filletoid<StretchedCircleFillet> Conn; |
typedef Filletoid<StretchedCircleFillet> Conn; |
684 |
|
|
685 |
ZVec blend(Conn *conns[], int N, float r, ZVec pt) const { |
ZVec blend(Conn *conns[], int N, float r, ZVec pt, |
686 |
|
int *maxi = NULL) const { |
687 |
int i, num = 0; |
int i, num = 0; |
688 |
float sum = 0; |
double sum = 0; |
689 |
float x[N]; |
float x[N]; |
690 |
|
float maxt = 0; |
691 |
|
|
692 |
pt = pt.normalized(); |
pt = pt.normalized(); |
693 |
|
|
694 |
|
//cout << "Blending " << pt << ": "; |
695 |
// Compute distances from the node for each fillet surface |
// Compute distances from the node for each fillet surface |
696 |
for (i = 0; i < N; i++) { |
for (i = 0; i < N; i++) { |
697 |
bool success; |
bool success; |
698 |
float t = conns[i]->rad(pt, success); |
float t = conns[i]->rad(pt, success); |
699 |
if (success) |
if (success) { |
700 |
sum += x[num++] = t - r; |
//cout << t << " "; |
701 |
|
sum += x[num++] = (t - r) / r; |
702 |
|
if (maxi) { |
703 |
|
if (t > maxt) maxt = t, *maxi = i; |
704 |
|
} |
705 |
|
} |
706 |
} |
} |
707 |
|
|
708 |
// 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 |
709 |
// p == 1: sum of distances, |
// p == 1: sum of distances, |
710 |
// p == \infty: maximum of distances |
// p == \infty: maximum of distances |
711 |
float p = 1.0 + sum / r; |
float p = 1.0 + sum; |
712 |
|
if (p > 100) p = 100; |
713 |
|
|
714 |
|
//cout << "p=" << p << " "; |
715 |
|
|
716 |
sum = 0; |
sum = 0; |
717 |
for (i = 0; i < num; i++) |
for (i = 0; i < num; i++) { |
718 |
sum += pow(x[i], p); |
sum += pow(x[i], p); |
719 |
|
} |
720 |
|
|
721 |
return pt * (r + pow(sum, 1 / p)); |
//cout << "->" << pow(sum, 1 / p) << std::endl; |
722 |
|
|
723 |
|
return pt * (r + r * pow(sum, 1 / p)); |
724 |
|
|
725 |
} |
} |
726 |
|
|
802 |
|
|
803 |
} |
} |
804 |
|
|
805 |
void renderGrid(const std::vector<ZVec> &pt, int n, int m) const { |
void renderCylinder(const std::vector<ZVec> &pt, int n, int m) const { |
806 |
std::vector<ZVec> norm(n * m); |
std::vector<ZVec> norm(n * m); |
807 |
int i, j; |
int i, j; |
808 |
|
|
810 |
for (j = 0; j < m; j++) { |
for (j = 0; j < m; j++) { |
811 |
ZVec px0 = pt[(i== 0 ? 0 : i-1) * m + j]; |
ZVec px0 = pt[(i== 0 ? 0 : i-1) * m + j]; |
812 |
ZVec px1 = pt[(i==n-1 ? n-1 : i+1) * m + j]; |
ZVec px1 = pt[(i==n-1 ? n-1 : i+1) * m + j]; |
813 |
ZVec py0 = pt[i * m + (j== 0 ? 0 : j-1)]; |
ZVec py0 = pt[i * m + (j== 0 ? m-1 : j-1)]; |
814 |
ZVec py1 = pt[i * m + (j==m-1 ? m-1 : j+1)]; |
ZVec py1 = pt[i * m + (j==m-1 ? 0 : j+1)]; |
815 |
|
|
816 |
norm[i * m + j] = (px1 - px0).crossp(py1 - py0).normalized(); |
norm[i * m + j] = (px1 - px0).crossp(py1 - py0).normalized(); |
817 |
} |
} |
835 |
} |
} |
836 |
} |
} |
837 |
|
|
838 |
|
void renderCylinder2(const std::vector<ZVec> &pt, |
839 |
|
const std::vector<bool> &clip, |
840 |
|
int n, int m) const { |
841 |
|
std::vector<ZVec> norm(n * m); |
842 |
|
int i, j; |
843 |
|
|
844 |
|
for (i = 0; i < n; i++) { |
845 |
|
for (j = 0; j < m; j++) { |
846 |
|
ZVec px0 = pt[(i== 0 ? 0 : i-1) * m + j]; |
847 |
|
ZVec px1 = pt[(i==n-1 ? n-1 : i+1) * m + j]; |
848 |
|
ZVec py0 = pt[i * m + (j== 0 ? m-1 : j-1)]; |
849 |
|
ZVec py1 = pt[i * m + (j==m-1 ? 0 : j+1)]; |
850 |
|
|
851 |
|
norm[i * m + j] = (px1 - px0).crossp(py1 - py0).normalized(); |
852 |
|
} |
853 |
|
} |
854 |
|
|
855 |
|
for (j = 0; j < m; j++) { |
856 |
|
|
857 |
|
glBegin(GL_QUAD_STRIP); |
858 |
|
for (i = 0; i < n; i++) { |
859 |
|
glNormal(norm[i * m + j]); |
860 |
|
glVertex(pt[i * m + j]); |
861 |
|
|
862 |
|
glNormal(norm[i * m + (j + 1) % m]); |
863 |
|
glVertex(pt[i * m + (j + 1) % m]); |
864 |
|
|
865 |
|
if (clip[i * m + j] && |
866 |
|
clip[i * m + (j + 1)]) break; |
867 |
|
} |
868 |
|
glEnd(); |
869 |
|
} |
870 |
|
} |
871 |
|
|
872 |
void render(const Transform **t, int n) const { |
void render(const Transform **t, int n) const { |
873 |
const Transform &thick_t = *t[0]; |
const Transform &thick_t = *t[0]; |
874 |
const Transform &angle_t = *t[1]; |
const Transform &angle_t = *t[1]; |
893 |
FilletSpan2::Conn conn(thick_t, angle_t, t0, t1, d); |
FilletSpan2::Conn conn(thick_t, angle_t, t0, t1, d); |
894 |
|
|
895 |
conns[i] = new Conn(node, d, conn.th, conn.a, |
conns[i] = new Conn(node, d, conn.th, conn.a, |
896 |
(p1 - p0).normalized()); |
(p1 - p0).normalized(), tblsize); |
897 |
|
|
898 |
dirs.push_back((p1 - p0).normalized()); |
dirs.push_back((p1 - p0).normalized()); |
899 |
} |
} |
900 |
|
|
901 |
#if 0 |
#if 1 |
902 |
|
|
903 |
for (int k = 0; k < N; k++) { |
for (int k = 0; k < N; k++) { |
904 |
std::vector<ZVec> pt((ndice + 1) * ndice); |
std::vector<ZVec> pt((ndice + 1) * ndice); |
905 |
|
|
906 |
|
ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)); |
907 |
|
ZVec e0 = conns[k]->dir; |
908 |
|
ZVec e1 = ref.crossp(e0).normalized(); |
909 |
|
ZVec e2 = e0.crossp(e1); |
910 |
|
|
911 |
for (i = 0; i <= ndice; i++) { |
for (i = 0; i <= ndice; i++) { |
912 |
float f = (float)i / ndice; |
float f = (float)i / ndice; |
913 |
|
|
914 |
Vec v = conns[k]->f.point(f); |
Vec v = conns[k]->f.point(f); |
|
|
|
|
ZVec e0 = conns[k]->dir; |
|
|
ZVec e1 = e0.crossp(ref).normalized(); |
|
|
ZVec e2 = e0.crossp(e1); |
|
915 |
|
|
916 |
for (j = 0; j < ndice; j++) { |
for (j = 0; j < ndice; j++) { |
917 |
float a = j * 2 * M_PI / ndice; |
float a = j * 2 * M_PI / ndice; |
923 |
} |
} |
924 |
} |
} |
925 |
|
|
926 |
for (i = 0; i < (ndice + 1) * ndice; i++) |
std::vector<bool> clip(pt.size()); |
927 |
pt[i] = blend(conns, N, r, pt[i]) + p0; |
for (i = 0; i <= ndice; i++) { |
928 |
|
for (j = 0; j < ndice; j++) { |
929 |
|
int ind = i * ndice + j; |
930 |
|
int maxi; |
931 |
|
pt[ind] = blend(conns, N, r, pt[ind], &maxi) + p0; |
932 |
|
clip[ind] = (maxi != k); |
933 |
|
} |
934 |
|
} |
935 |
|
|
936 |
renderGrid(pt, ndice + 1, ndice); |
renderCylinder2(pt, clip, ndice + 1, ndice); |
937 |
|
|
938 |
|
if (k == 0) { |
939 |
|
for (i = 0; i <= ndice; i++) { |
940 |
|
float f = (float)i / ndice; |
941 |
|
|
942 |
|
float a = lerp(conns[k]->f.tangentAngle, M_PI, f); |
943 |
|
Vec v(r * cos(a), r * sin(a)); |
944 |
|
|
945 |
|
for (j = 0; j < ndice; j++) { |
946 |
|
float a = j * 2 * M_PI / ndice; |
947 |
|
|
948 |
|
pt[i * ndice + j] = p0 + |
949 |
|
v.x * e0 |
950 |
|
+ v.y * cos(a) * e1 |
951 |
|
+ v.y * sin(a) * e2; |
952 |
|
} |
953 |
|
} |
954 |
|
|
955 |
|
renderCylinder(pt, ndice + 1, ndice); |
956 |
|
} |
957 |
} |
} |
958 |
|
|
959 |
#elif 1 // Old version without Dicer |
#elif 1 // Old version without Dicer |
978 |
for (i = 0; i < (ndice + 1) * (ndice * 2); i++) |
for (i = 0; i < (ndice + 1) * (ndice * 2); i++) |
979 |
pt[i] = blend(conns, N, r, pt[i]) + p0; |
pt[i] = blend(conns, N, r, pt[i]) + p0; |
980 |
|
|
981 |
renderGrid(pt, ndice + 1, ndice * 2); |
renderCylinder(pt, ndice + 1, ndice * 2); |
982 |
|
|
983 |
|
|
984 |
#else // use Dicer |
#else // use Dicer |
1038 |
|
|
1039 |
ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)); |
ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)); |
1040 |
ZVec e0 = conns[i]->dir; |
ZVec e0 = conns[i]->dir; |
1041 |
ZVec e1 = e0.crossp(ref).normalized(); |
ZVec e1 = ref.crossp(e0).normalized(); |
1042 |
ZVec e2 = e0.crossp(e1); |
ZVec e2 = e0.crossp(e1); |
1043 |
|
|
1044 |
ZVec p0 = d * e0; |
ZVec p0 = d * e0; |