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 #include "machine.h"
00046 #include "vmath.h"
00047 #include "raytrace.h"
00048 #include "nurb.h"
00049
00050 int
00051 rt_nurb_s_flat(struct face_g_snurb *srf, fastf_t epsilon)
00052
00053
00054 {
00055 register fastf_t max_row_dist;
00056 register fastf_t max_col_dist;
00057 register fastf_t max_dist;
00058 int dir;
00059 fastf_t * mesh_ptr = srf->ctl_points;
00060 int coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
00061 int j, i, k;
00062 int mesh_elt;
00063 vect_t p1, p2, p3, p4, v1, v2, v3;
00064 vect_t nrm;
00065 fastf_t nrmln;
00066 fastf_t dist;
00067 fastf_t * crv;
00068 fastf_t spl_crv_flat();
00069 int otherdir;
00070
00071 dir = srf->dir;
00072
00073 otherdir = (dir == RT_NURB_SPLIT_ROW) ? RT_NURB_SPLIT_COL : RT_NURB_SPLIT_ROW;
00074
00075 max_row_dist = max_col_dist = -INFINITY;
00076
00077 crv = (fastf_t * ) bu_malloc( sizeof(fastf_t) *
00078 RT_NURB_EXTRACT_COORDS(srf->pt_type) * srf->s_size[1],
00079 "rt_nurb_s_flat: crv");
00080
00081
00082
00083
00084
00085
00086 for (i = 0; i < (srf->s_size[0]); i++) {
00087 fastf_t rdist;
00088 for (j = 0;
00089 j < (srf->s_size[1] *
00090 RT_NURB_EXTRACT_COORDS(srf->pt_type));
00091 j++)
00092 crv[j] = *mesh_ptr++;
00093
00094 rdist = rt_nurb_crv_flat(crv, srf->s_size[1],
00095 srf->pt_type);
00096 max_row_dist = MAX(max_row_dist, rdist);
00097 }
00098
00099 bu_free( (char *)crv, "rt_nurb_s_flat: crv" );
00100
00101 crv = (fastf_t * ) bu_malloc(sizeof(fastf_t) *
00102 RT_NURB_EXTRACT_COORDS(srf->pt_type) *
00103 srf->s_size[0], "rt_nurb_s_flat: crv");
00104
00105 for (i = 0; i < (coords * srf->s_size[1]); i += coords) {
00106 fastf_t rdist;
00107
00108 for (j = 0; j < (srf->s_size[0]); j++) {
00109 mesh_elt =
00110 (j * (srf->s_size[1] * coords)) + i;
00111
00112 for (k = 0; k < coords; k++)
00113 crv[j * coords + k] =
00114 srf->ctl_points[mesh_elt + k];
00115 }
00116
00117 rdist = rt_nurb_crv_flat(crv,
00118 srf->s_size[0], srf->pt_type);
00119
00120 max_col_dist = MAX( max_col_dist, rdist);
00121 }
00122
00123 bu_free((char *)crv, "rt_nurb_s_flat: crv");
00124
00125 max_dist = MAX( max_row_dist, max_col_dist);
00126
00127 if ( max_dist > epsilon) {
00128 if ( max_row_dist > max_col_dist )
00129 return RT_NURB_SPLIT_ROW;
00130 else
00131 return RT_NURB_SPLIT_COL;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141 mesh_ptr = srf->ctl_points;
00142
00143 if ( !RT_NURB_IS_PT_RATIONAL(srf->pt_type) ) {
00144
00145 VMOVE(p1, mesh_ptr);
00146 VMOVE(p2,
00147 (mesh_ptr + (srf->s_size[1] - 1) * coords));
00148 VMOVE(p3,
00149 (mesh_ptr +
00150 ((srf->s_size[1] *
00151 (srf->s_size[0] - 1)) +
00152 (srf->s_size[1] - 1)) * coords));
00153
00154 VMOVE(p4,
00155 (mesh_ptr +
00156 (srf->s_size[1] *
00157 (srf->s_size[0] - 1)) * coords));
00158 } else
00159 {
00160 hvect_t h1, h2, h3, h4;
00161 int offset;
00162
00163 HMOVE(h1, mesh_ptr);
00164 HDIVIDE( p1, h1 );
00165
00166 offset = (srf->s_size[1] - 1) * coords;
00167 HMOVE(h2, mesh_ptr + offset);
00168 HDIVIDE( p2, h2 );
00169
00170 offset =
00171 ((srf->s_size[1] *
00172 (srf->s_size[0] - 1)) +
00173 (srf->s_size[1] - 1)) * coords;
00174 HMOVE(h3, mesh_ptr + offset);
00175 HDIVIDE( p3, h3 );
00176
00177 offset =
00178 (srf->s_size[1] *
00179 (srf->s_size[0] - 1)) * coords;
00180 HMOVE(h4, mesh_ptr + offset);
00181 HDIVIDE( p4, h4 );
00182 }
00183
00184 VSUB2(v1, p2, p1);
00185 VSUB2(v2, p3, p1);
00186
00187 VCROSS(nrm, v1, v2);
00188
00189 nrmln = MAGNITUDE(nrm);
00190 if( nrmln < 0.0001 )
00191 return RT_NURB_SPLIT_FLAT;
00192
00193 VSUB2(v3, p4, p1);
00194
00195 dist = fabs(VDOT( v3, nrm)) / nrmln;
00196
00197 if (dist > epsilon)
00198 return otherdir;
00199
00200 return RT_NURB_SPLIT_FLAT;
00201
00202 }
00203
00204
00205 fastf_t
00206 rt_nurb_crv_flat(fastf_t *crv, int size, int pt_type)
00207 {
00208 point_t p1, p2;
00209 vect_t ln;
00210 int i;
00211 fastf_t dist;
00212 fastf_t max_dist;
00213 fastf_t length;
00214 fastf_t * c_ptr;
00215 vect_t testv, xp;
00216 hvect_t h1, h2;
00217 int coords;
00218 int rational;
00219
00220 coords = RT_NURB_EXTRACT_COORDS( pt_type);
00221 rational = RT_NURB_IS_PT_RATIONAL( pt_type);
00222 max_dist = -INFINITY;
00223
00224 if ( !rational) {
00225 VMOVE(p1, crv);
00226 } else {
00227 HMOVE( h1, crv);
00228 HDIVIDE( p1, h1);
00229 }
00230
00231 length = 0.0;
00232
00233
00234
00235
00236
00237 for (i = size - 1; (i > 0) && length < SQRT_SMALL_FASTF; i--) {
00238 if ( !rational) {
00239 VMOVE(p2, (crv + (i * coords)));
00240 } else {
00241 HMOVE( h2, (crv + ( i * coords)));
00242 HDIVIDE( p2, h2 );
00243 }
00244
00245 VSUB2(ln, p1, p2);
00246 length = MAGNITUDE(ln);
00247 }
00248
00249
00250 if( length >= SQRT_SMALL_FASTF ) {
00251 VSCALE(ln, ln, 1.0 / length);
00252 c_ptr = crv + coords;
00253
00254 for (i = 1; i < size; i++) {
00255 if ( !rational ) {
00256 VSUB2(testv, p1, c_ptr);
00257 } else {
00258 HDIVIDE(h2, c_ptr);
00259 VSUB2( testv, p1, h2);
00260 }
00261
00262 VCROSS(xp, testv, ln);
00263 dist = MAGNITUDE(xp);
00264 max_dist = MAX( max_dist, dist);
00265 c_ptr += coords;
00266 }
00267 }
00268 return max_dist;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279