00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "common.h"
00040
00041
00042
00043 #include <stdio.h>
00044 #include <math.h>
00045
00046 #include "machine.h"
00047 #include "vmath.h"
00048 #include "raytrace.h"
00049 #include "nurb.h"
00050
00051 void
00052 rt_nurb_curvature(struct curvature *cvp, const struct face_g_snurb *srf, fastf_t u, fastf_t v)
00053 {
00054 struct face_g_snurb * us, *vs, * uus, * vvs, *uvs;
00055 fastf_t ue[4], ve[4], uue[4], vve[4], uve[4], se[4];
00056 fastf_t E, F, G;
00057 fastf_t L, M, N;
00058 fastf_t denom;
00059 fastf_t wein[4];
00060 fastf_t evec[3];
00061 fastf_t mean, gauss, discrim;
00062 vect_t norm;
00063 int i;
00064
00065 us = rt_nurb_s_diff(srf, RT_NURB_SPLIT_ROW);
00066 vs = rt_nurb_s_diff(srf, RT_NURB_SPLIT_COL);
00067 uus = rt_nurb_s_diff(us, RT_NURB_SPLIT_ROW);
00068 vvs = rt_nurb_s_diff(vs, RT_NURB_SPLIT_COL);
00069 uvs = rt_nurb_s_diff(vs, RT_NURB_SPLIT_ROW);
00070
00071 rt_nurb_s_eval(srf, u, v, se);
00072 rt_nurb_s_eval(us, u,v, ue);
00073 rt_nurb_s_eval(vs, u,v, ve);
00074 rt_nurb_s_eval(uus, u,v, uue);
00075 rt_nurb_s_eval(vvs, u,v, vve);
00076 rt_nurb_s_eval(uvs, u,v, uve);
00077
00078 rt_nurb_free_snurb( us, (struct resource *)NULL);
00079 rt_nurb_free_snurb( vs, (struct resource *)NULL);
00080 rt_nurb_free_snurb( uus, (struct resource *)NULL);
00081 rt_nurb_free_snurb( vvs, (struct resource *)NULL);
00082 rt_nurb_free_snurb( uvs, (struct resource *)NULL);
00083
00084 if( RT_NURB_IS_PT_RATIONAL( srf->pt_type ))
00085 {
00086 for( i = 0; i < 3; i++)
00087 {
00088 ue[i] = (1.0 / se[3] * ue[i]) -
00089 (ue[3]/se[3]) * se[0]/se[3];
00090 ve[i] = (1.0 / se[3] * ve[i]) -
00091 (ve[3]/se[3]) * se[0]/se[3];
00092 }
00093 VCROSS(norm, ue, ve);
00094 VUNITIZE(norm);
00095 E = VDOT( ue, ue);
00096 F = VDOT( ue, ve);
00097 G = VDOT( ve, ve);
00098
00099 for( i = 0; i < 3; i++)
00100 {
00101 uue[i] = (1.0 / se[3] * uue[i]) -
00102 2 * (uue[3]/se[3]) * uue[i] -
00103 uue[3]/se[3] * (se[i]/se[3]);
00104
00105 vve[i] = (1.0 / se[3] * vve[i]) -
00106 2 * (vve[3]/se[3]) * vve[i] -
00107 vve[3]/se[3] * (se[i]/se[3]);
00108
00109 uve[i] = 1.0 / se[3] * uve[i] +
00110 (-1.0 / (se[3] * se[3])) *
00111 (ve[3] * ue[i] + ue[3] * ve[i] +
00112 uve[3] * se[i]) +
00113 (-2.0 / (se[3] * se[3] * se[3])) *
00114 (ve[3] * ue[3] * se[i]);
00115 }
00116
00117 L = VDOT( norm, uue);
00118 M = VDOT( norm, uve);
00119 N = VDOT( norm, vve);
00120
00121 } else
00122 {
00123 VCROSS( norm, ue, ve);
00124 VUNITIZE( norm );
00125 E = VDOT( ue, ue);
00126 F = VDOT( ue, ve);
00127 G = VDOT( ve, ve);
00128
00129 L = VDOT( norm, uue);
00130 M = VDOT( norm, uve);
00131 N = VDOT( norm, vve);
00132 }
00133
00134 if( srf->order[0] <= 2 && srf->order[1] <= 2)
00135 {
00136 cvp->crv_c1 = cvp->crv_c2 = 0;
00137 bn_vec_ortho(cvp->crv_pdir, norm);
00138 return;
00139 }
00140
00141 denom = ( (E*G) - (F*F) );
00142 gauss = (L * N - M *M)/denom;
00143 mean = (G * L + E * N - 2 * F * M) / (2 * denom);
00144 discrim = sqrt( mean * mean - gauss);
00145
00146 cvp->crv_c1 = mean - discrim;
00147 cvp->crv_c2 = mean + discrim;
00148
00149 if( fabs( E*G - F*F) < 0.0001 )
00150 {
00151 bu_log("rt_nurb_curvature: first fundamental form is singular E = %g F= %g G = %g\n",
00152 E,F,G);
00153 bn_vec_ortho(cvp->crv_pdir, norm);
00154 return;
00155 }
00156
00157 wein[0] = ( (G * L) - (F * M))/ (denom);
00158 wein[1] = ( (G * M) - (F * N))/ (denom);
00159 wein[2] = ( (E * M) - (F * L))/ (denom);
00160 wein[3] = ( (E * N) - (F * M))/ (denom);
00161
00162 if( fabs(wein[1]) < 0.0001 && fabs( wein[3] - cvp->crv_c1 ) < 0.0001 )
00163 {
00164 evec[0] = 0.0; evec[1] = 1.0;
00165 } else
00166 {
00167 evec[0] = 1.0;
00168 if( fabs( wein[1] ) > fabs( wein[3] - cvp->crv_c1) )
00169 {
00170 evec[1] = (cvp->crv_c1 - wein[0]) / wein[1];
00171 } else
00172 {
00173 evec[1] = wein[2] / ( cvp->crv_c1 - wein[3] );
00174 }
00175 }
00176
00177 cvp->crv_pdir[0] = evec[0] * ue[0] + evec[1] * ve[0];
00178 cvp->crv_pdir[1] = evec[0] * ue[1] + evec[1] * ve[1];
00179 cvp->crv_pdir[2] = evec[0] * ue[2] + evec[1] * ve[2];
00180 VUNITIZE( cvp->crv_pdir);
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191