oslo_calc.c

Go to the documentation of this file.
00001 /*                     O S L O _ C A L C . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1986-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup librt
00023 /*@{*/
00024 /** @file oslo_calc.c
00025  * Calculate the Oslo refinement matrix.
00026  *
00027  * Author -
00028  *     Paul R. Stay
00029  *
00030  * Source -
00031  *     SECAD/VLD Computing Consortium, Bldg 394
00032  *     The U.S. Army Ballistic Research Laboratory
00033  *     Aberdeen Proving Ground, Maryland 21005
00034  *
00035  *
00036  * This algorithm was taken from the paper
00037  * "Making the Oslo Algorithm More Efficient" by T. Lyche and K. Morken
00038  * The algorithm referenced in the paper is algorithm 1 since we will be
00039  * dealing mostly with surfaces. This routine computes the refinement
00040  * matrix and returns a oslo structure which will allow a new curve or
00041  * surface to be built.
00042  *
00043  * Since we only want the last row of the alpha's as outlined in the
00044  * paper we can use a one dimensional array for the ah.
00045  */
00046 
00047 #include "common.h"
00048 
00049 
00050 
00051 #include <stdio.h>
00052 #include "machine.h"
00053 #include "vmath.h"
00054 #include "raytrace.h"
00055 #include "nurb.h"
00056 
00057 #define AMAX(i,j)    ( (i) > (j) ? (i) : (j) )
00058 #define AMIN(i,j)    ( (i) < (j) ? (i) : (j) )
00059 
00060 struct oslo_mat *
00061 rt_nurb_calc_oslo(register int order, register const struct knot_vector *tau_kv, register struct knot_vector *t_kv, struct resource *res)
00062 
00063                                                 /* old knot vector */
00064                                                 /* new knot vector */
00065 
00066 {
00067         register fastf_t        *t_p;
00068         register const fastf_t  *tau_p;
00069         fastf_t ah[20];
00070         fastf_t newknots[20];                   /* new knots */
00071         register int  j;                        /* d(j), j = 0 : # of new ctl points */
00072         int     mu,                             /* mu:  tau[mu] <= t[j] < tau[mu+1]*/
00073                 muprim,
00074                 v,                              /* Nu value (order of matrix) */
00075                 p,
00076                 iu,                             /* upper bound loop counter */
00077                 il,                             /* lower bound loop counter */
00078                 ih,
00079                 n1;                             /* upper bound of t knot vector - order*/
00080 
00081         fastf_t tj;
00082 
00083         struct oslo_mat * head, * o_ptr, *new_o;
00084 
00085         n1 = t_kv->k_size - order;
00086 
00087         t_p = t_kv->knots;
00088         tau_p = tau_kv->knots;
00089 
00090         mu = 0;                         /* initialize mu */
00091 
00092         head = (struct oslo_mat *) bu_malloc (
00093                     sizeof( struct oslo_mat),
00094                     "rt_nurb_calc_oslo: oslo mat head" );
00095 
00096         o_ptr = head;
00097 
00098         for (j = 0; j < n1; j++) {
00099                 register int  i;
00100 
00101                 if ( j != 0 )
00102                 {
00103                         new_o = (struct oslo_mat *) bu_malloc (
00104                                     sizeof( struct oslo_mat),
00105                                     "rt_nurb_calc_oslo: oslo mat struct" );
00106 
00107                         o_ptr->next = new_o;
00108                         o_ptr = new_o;
00109                 }
00110 
00111                 /* find the bounding mu */
00112                 while (tau_p[mu + 1] <= t_p[j]) mu++;
00113 
00114                 muprim = mu;
00115 
00116                 i = j + 1;
00117 
00118                 while ((t_p[i] == tau_p[muprim]) && i < (j + order)) {
00119                         i++;
00120                         muprim--;
00121                 }
00122 
00123                 ih = muprim + 1;
00124 
00125                 for (v = 0, p = 1; p < order; p++) {
00126                         if (t_p[j + p] == tau_p[ih])
00127                                 ih++;
00128                         else
00129                                 newknots[++v - 1] = t_p[j + p];
00130                 }
00131 
00132                 ah[order-1] = 1.0;
00133 
00134                 for (p = 1; p <= v; p++) {
00135 
00136                         fastf_t beta1;
00137                         int o_m;
00138 
00139                         beta1 = 0.0;
00140                         o_m = order - muprim;
00141 
00142                         tj = newknots[p-1];
00143 
00144                         if (p > muprim) {
00145                                 beta1 = ah[o_m];
00146                                 beta1 = ((tj - tau_p[0]) * beta1) /
00147                                     (tau_p[p + order - v] - tau_p[0]);
00148                         }
00149                         i = muprim - p + 1;
00150                         il = AMAX (1, i);
00151                         i = n1 - 1 + v - p;
00152                         iu = AMIN (muprim, i);
00153 
00154                         for (i = il; i <= iu; i++) {
00155                                 fastf_t d1, d2;
00156                                 fastf_t beta;
00157 
00158                                 d1 = tj - tau_p[i];
00159                                 d2 = tau_p[i + p + order - v - 1] - tj;
00160 
00161                                 beta = ah[i + o_m - 1] / (d1 + d2);
00162 
00163                                 ah[i + o_m - 2] = d2 * beta + beta1;
00164                                 beta1 = d1 * beta;
00165                         }
00166 
00167                         ah[iu + o_m - 1] = beta1;
00168 
00169                         if (iu < muprim) {
00170                                 register fastf_t kkk;
00171                                 register fastf_t ahv;
00172 
00173                                 kkk = tau_p[n1 - 1 + order];
00174                                 ahv = ah[iu + o_m];
00175                                 ah[iu + o_m - 1] =
00176                                     beta1 + (kkk - tj) *
00177                                     ahv / (kkk - tau_p[iu + 1]);
00178                         }
00179                 }
00180 
00181                 o_ptr->o_vec = (fastf_t *) bu_malloc ( sizeof( fastf_t) * (v+1),
00182                             "rt_nurb_calc_oslo: oslo vector");
00183 
00184                 o_ptr->offset = AMAX(muprim -v,0);
00185                 o_ptr->osize = v;
00186 
00187                 for ( i = v, p = 0; i >= 0; i--)
00188                         o_ptr->o_vec[p++] =  ah[(order-1) - i];
00189         }
00190 
00191         o_ptr->next = (struct oslo_mat*) 0;
00192         return head;
00193 }
00194 
00195 
00196 /*
00197  *  rt_pr_oslo() - FOR DEBUGGING PURPOSES
00198  */
00199 void
00200 rt_nurb_pr_oslo(struct oslo_mat *om)
00201 {
00202         struct oslo_mat * omp;
00203         int j;
00204 
00205         for( omp = om; omp!= ( struct oslo_mat *) 0; omp = omp->next)
00206         {
00207                 fprintf(stderr, "%lx offset %d osize %d next %lx\n",
00208                         (unsigned long)omp,  omp->offset,  omp->osize,
00209                         (unsigned long)omp->next);
00210 
00211                 fprintf(stderr,"\t%f",  omp->o_vec[0]);
00212 
00213                 for ( j = 1; j <= omp->osize; j++)
00214                         fprintf(stderr,"\t%f",  omp->o_vec[j]);
00215                 fprintf(  stderr, "\n");
00216         }
00217 }
00218 
00219 /* rt_nurb_free_oslo()
00220  * Free up the structures and links for the oslo matrix.
00221  */
00222 
00223 void
00224 rt_nurb_free_oslo(struct oslo_mat *om, struct resource *res)
00225 {
00226         register struct oslo_mat * omp;
00227 
00228         while( om != (struct oslo_mat *) 0 )
00229         {
00230                 omp = om;
00231                 om = om->next;
00232                 bu_free( (char *)omp->o_vec, "rt_nurb_free_oslo: ovec");
00233                 bu_free( (char *)omp, "rt_nurb_free_oslo: struct oslo");
00234         }
00235 }
00236 
00237 /*@}*/
00238 /*
00239  * Local Variables:
00240  * mode: C
00241  * tab-width: 8
00242  * c-basic-offset: 4
00243  * indent-tabs-mode: t
00244  * End:
00245  * ex: shiftwidth=4 tabstop=8
00246  */

Generated on Mon Sep 18 01:24:56 2006 for BRL-CAD by  doxygen 1.4.6