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 #ifndef lint
00038 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/nurb_interp.c,v 14.12 2006/09/16 02:04:25 lbutler Exp $ (ARL)";
00039 #endif
00040
00041 #include "common.h"
00042
00043
00044
00045 #include <stdio.h>
00046 #include <string.h>
00047
00048 #include "machine.h"
00049 #include "vmath.h"
00050 #include "raytrace.h"
00051 #include "nurb.h"
00052
00053
00054 void
00055 rt_nurb_nodes(fastf_t *nodes, const struct knot_vector *knots, int order)
00056 {
00057 int i, j;
00058 fastf_t sum;
00059
00060 for( i = 0; i < knots->k_size -order; i++)
00061 {
00062
00063 sum = 0.0;
00064
00065 for( j = 1; j <= order -1; j++)
00066 {
00067 sum += knots->knots[i+j];
00068 }
00069 nodes[i] = sum/(order -1);
00070 }
00071 }
00072
00073 void
00074 rt_nurb_interp_mat(fastf_t *imat, struct knot_vector *knots, fastf_t *nodes, int order, int dim)
00075 {
00076 int i,j;
00077 int ptr;
00078
00079 ptr = 0;
00080
00081 for( i = 0; i < dim; i++)
00082 for( j = 0; j < dim; j++)
00083 {
00084 imat[ptr] = rt_nurb_basis_eval( knots, j, order, nodes[i]);
00085 ptr++;
00086 }
00087
00088 imat[ptr-1] = 1.0;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 void
00098 rt_nurb_cinterp(struct edge_g_cnurb *crv, int order, const fastf_t *data, int n)
00099 {
00100 fastf_t * interp_mat;
00101 fastf_t * nodes;
00102 fastf_t *local_data;
00103
00104
00105
00106 interp_mat = (fastf_t *) bu_malloc( n * n * sizeof(fastf_t),
00107 "rt_nurb_interp: interp_mat");
00108
00109 nodes = (fastf_t *) bu_malloc( n * sizeof(fastf_t),"rt_nurb_interp:nodes");
00110 local_data = (fastf_t *)bu_malloc( n * 3 * sizeof(fastf_t), "rt_nurb_interp() local_data[]");
00111
00112 crv->ctl_points = (fastf_t *) bu_malloc( n * 3 * sizeof(fastf_t),
00113 "solution");
00114
00115 crv->order = order;
00116 crv->c_size = n;
00117 crv->pt_type = RT_NURB_MAKE_PT_TYPE( 3, RT_NURB_PT_XYZ, 0);
00118
00119
00120
00121
00122 rt_nurb_kvknot( &crv->k, order, 0.0, 1.0, (n - order), (struct resource *)NULL);
00123
00124
00125
00126
00127
00128 rt_nurb_nodes( nodes, &crv->k, order);
00129
00130
00131
00132
00133
00134 rt_nurb_interp_mat( interp_mat, &crv->k, nodes, order, n);
00135
00136
00137
00138
00139
00140
00141
00142 bcopy( (char *)data, (char *)local_data, n * 3 * sizeof(fastf_t) );
00143 rt_nurb_solve( interp_mat, local_data, crv->ctl_points, n, 3);
00144
00145
00146
00147 bu_free( (char *) interp_mat, "rt_nurb_cinterp: interp_mat");
00148 bu_free( (char *) nodes, "rt_nurb_cinterp: nodes");
00149 bu_free( (char *) local_data, "rt_nurb_cinterp() local_data[]");
00150
00151
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 void
00168 rt_nurb_sinterp(struct face_g_snurb *srf, int order, const fastf_t *data, int ymax, int xmax)
00169
00170
00171
00172
00173
00174 {
00175 int x;
00176 int y;
00177 struct edge_g_cnurb *crv;
00178 fastf_t *tmp;
00179 fastf_t *cpt;
00180
00181
00182 srf->order[0] = srf->order[1] = order;
00183 srf->dir = 0;
00184 srf->s_size[0] = xmax;
00185 srf->s_size[1] = ymax;
00186 srf->l.magic = RT_SNURB_MAGIC;
00187 srf->pt_type = RT_NURB_MAKE_PT_TYPE(3,RT_NURB_PT_XYZ,RT_NURB_PT_NONRAT);
00188
00189
00190
00191
00192
00193
00194 rt_nurb_kvknot(&srf->u, order, 0.0, 1.0, ymax - order, (struct resource *)NULL);
00195 rt_nurb_kvknot(&srf->v, order, 0.0, 1.0, xmax - order, (struct resource *)NULL);
00196
00197 srf->ctl_points = (fastf_t *) bu_malloc(
00198 sizeof(fastf_t) * xmax * ymax * 3,
00199 "rt_nurb_sinterp() surface ctl_points[]");
00200 cpt = &srf->ctl_points[0];
00201
00202
00203 #define NVAL(_col,_row) data[((_row)*xmax+(_col))*3]
00204
00205 crv = (struct edge_g_cnurb *)bu_calloc( sizeof(struct edge_g_cnurb), ymax,
00206 "rt_nurb_sinterp() crv[]");
00207
00208
00209 for( y = 0; y < ymax; y++) {
00210 crv[y].l.magic = RT_CNURB_MAGIC;
00211
00212 rt_nurb_cinterp( &crv[y], order, &NVAL(0,y), xmax );
00213 }
00214 #undef NVAL
00215
00216 tmp = (fastf_t *)bu_malloc( sizeof(fastf_t)*3 * ymax,
00217 "rt_nurb_sinterp() tmp[]");
00218 for( x = 0; x < xmax; x++) {
00219 struct edge_g_cnurb ncrv;
00220
00221
00222 for( y = 0; y < ymax; y++) {
00223 VMOVE( &tmp[y*3], &crv[y].ctl_points[x*3] );
00224 }
00225
00226
00227 ncrv.l.magic = RT_CNURB_MAGIC;
00228 rt_nurb_cinterp( &ncrv, order, tmp, ymax);
00229
00230
00231 for( y = 0; y < ymax*3; y++) {
00232 *cpt++ = ncrv.ctl_points[y];
00233 }
00234 rt_nurb_clean_cnurb( &ncrv );
00235 }
00236 for( y = 0; y < ymax; y++) {
00237 rt_nurb_clean_cnurb( &crv[y] );
00238 }
00239 bu_free( (char *)crv, "crv[]");
00240 bu_free( (char *)tmp, "tmp[]");
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251