nurb_eval.c

Go to the documentation of this file.
00001 /*                     N U R B _ E V A L . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1990-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 nurb */
00023 /*@{*/
00024 /** @file nurb_eval.c
00025  *      Evaluate a Non Uniform Rational B-spline curve or at the
00026  *      given (u,v) values.
00027  *  Author -
00028  *      Paul Randal 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 /*@}*/
00037 
00038 #include "common.h"
00039 
00040 
00041 
00042 #include <stdio.h>
00043 #include <math.h>
00044 #include "machine.h"
00045 #include "vmath.h"
00046 #include "nmg.h"
00047 #include "raytrace.h"
00048 #include "nurb.h"
00049 
00050 /* Algorithm -
00051  *
00052  * The algorithm uses the traditional COX-deBoor approach
00053  * found in the book "Pratical Guide to Splines" Carl de Boor, pg 147
00054  * to evaluate a parametric value on a curve. This is expanded to the surface.
00055  */
00056 
00057 void
00058 rt_nurb_s_eval(const struct face_g_snurb *srf, fastf_t u, fastf_t v, fastf_t *final_value)
00059 {
00060         fastf_t * mesh_ptr = srf->ctl_points;
00061         fastf_t * curves;
00062         int     i, j, k;
00063         int     row_size = srf->s_size[RT_NURB_SPLIT_ROW];
00064         int     col_size = srf->s_size[RT_NURB_SPLIT_COL];
00065         fastf_t * c_ptr;
00066         fastf_t * diff_curve, *ev_pt;
00067         int     k_index;
00068         int     coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
00069 
00070         NMG_CK_SNURB(srf);
00071 
00072         /* Because the algorithm is destructive in nature, the
00073          * rows of the control mesh are copied. The evaluation
00074          * is then done on each row curve and then evaluation
00075          * is then performed on the resulting curve.
00076          */
00077 
00078         diff_curve = (fastf_t * )
00079         bu_malloc(row_size * sizeof(fastf_t) * coords,
00080             "rt_nurb_s__eval: diff_curve");
00081 
00082         c_ptr = diff_curve;
00083 
00084         k_index = rt_nurb_knot_index( &srf->u, u, srf->order[RT_NURB_SPLIT_ROW] );
00085         if( k_index < 0 )
00086         {
00087                 bu_log( "rt_nurb_s_eval: u value outside parameter range\n");
00088                 bu_log( "\tUV = (%g %g )\n", u,v );
00089                 rt_nurb_s_print( "", srf );
00090                 rt_bomb( "rt_nurb_s_eval: u value outside parameter range\n");
00091         }
00092 
00093         curves = (fastf_t * ) bu_malloc( col_size * sizeof(fastf_t) * coords,
00094             "rt_nurb_s_eval:crv_ptr");
00095 
00096         for ( i = 0; i < row_size; i++) {
00097                 fastf_t * rtr_pt;
00098                 fastf_t * crv_ptr;
00099 
00100                 crv_ptr = curves;
00101 
00102                 for ( j = 0; j < (col_size * coords ); j++) {
00103                         *crv_ptr++ = *mesh_ptr++;
00104                 }
00105 
00106                 rtr_pt =  (fastf_t * ) rt_nurb_eval_crv( curves, srf->order[RT_NURB_SPLIT_ROW], u,
00107                     &srf->u, k_index, coords );
00108 
00109                 for (k = 0; k < coords; k++)
00110                         c_ptr[k] = rtr_pt[k];
00111                 c_ptr += coords;
00112         }
00113 
00114         bu_free( (char *)curves, "rt_nurb_s_eval: curves" );
00115 
00116         k_index = rt_nurb_knot_index( &srf->v, v, srf->order[RT_NURB_SPLIT_COL] );
00117 
00118         ev_pt = (fastf_t * ) rt_nurb_eval_crv( diff_curve, srf->order[RT_NURB_SPLIT_COL],
00119                 v, &srf->v, k_index, coords);
00120 
00121         for ( k = 0; k < coords; k++)
00122                 final_value[k] = ev_pt[k];
00123 
00124         bu_free ( (char *)diff_curve, "rt_nurb_s_eval: diff curve" );
00125 }
00126 
00127 
00128 void
00129 rt_nurb_c_eval(const struct edge_g_cnurb *crv, fastf_t param, fastf_t *final_value)
00130 {
00131         fastf_t * pnts;
00132         fastf_t * ev_pt;
00133         int     coords;
00134         int     i, k_index;
00135 
00136         NMG_CK_CNURB(crv);
00137 
00138         coords = RT_NURB_EXTRACT_COORDS( crv->pt_type);
00139 
00140         k_index = rt_nurb_knot_index( &crv->k, param, crv->order);
00141 
00142         pnts = (fastf_t * ) bu_malloc( coords * sizeof( fastf_t) *
00143             crv->c_size, "diff: rt_nurb_c_eval");
00144 
00145         for ( i = 0; i < coords * crv->c_size; i++)
00146                 pnts[i] = crv->ctl_points[i];
00147 
00148         ev_pt = (fastf_t * ) rt_nurb_eval_crv(
00149             pnts, crv->order, param, &crv->k, k_index, coords);
00150 
00151         for ( i = 0; i < coords; i++)
00152                 final_value[i] = ev_pt[i];
00153 
00154         bu_free( (char *) pnts, "rt_nurb_c_eval");
00155 }
00156 
00157 
00158 fastf_t *
00159 rt_nurb_eval_crv(register fastf_t *crv, int order, fastf_t param, const struct knot_vector *k_vec, int k_index, int coords)
00160 {
00161         int     i, j;
00162 
00163         if ( order <= 1 )
00164                 return
00165                     (crv + ((k_index) * coords));
00166 
00167         j = k_index;
00168 
00169         while ( j > (k_index - order + 1)) {
00170                 register fastf_t  k1, k2;
00171 
00172                 k1 =  k_vec->knots[ (j + order - 1)];
00173 
00174                 k2 =  k_vec->knots[ ( j ) ];
00175 
00176                 if ((k1 - k2) != 0.0 ) {
00177                         for ( i= 0; i < coords; i++)
00178                         {
00179                                 *((crv + ((j) * coords)) + i) =
00180                                         ((k1 - param) *
00181                                         *((crv + ((j - 1) * coords)) + i)
00182                                         + (param - k2 ) * *((crv + ((j) *
00183                                         coords)) + i)) / (k1 - k2);
00184                         }
00185                 }
00186                 j--;
00187         }
00188         return rt_nurb_eval_crv( crv, order - 1, param, k_vec,
00189                 k_index, coords );
00190 }
00191 
00192 
00193 void
00194 rt_nurb_pr_crv(fastf_t *crv, int c_size, int coords)
00195 {
00196         int     i;
00197 
00198         fprintf(stderr, "\n");
00199         if (coords == 3)
00200                 for (i = 0; i < c_size; i++)
00201                         fprintf(stderr, "p%d   %f   %f   %f\n", i, *((crv + ((i) * coords))),
00202                             *((crv + ((i) * coords)) + 1),
00203                             *((crv + ((i) * coords)) + 2));
00204 
00205         else if (coords == 4)
00206                 for (i = 0; i < c_size; i++)
00207                         fprintf(stderr, "p%d   %f   %f   %f   %f\n", i,
00208                             *((crv + ((i) * coords))),
00209                             *((crv + ((i) * coords)) + 1),
00210                             *((crv + ((i) * coords)) + 2),
00211                             *((crv + ((i) * coords)) + 3));
00212 }
00213 
00214 /*
00215  * Local Variables:
00216  * mode: C
00217  * tab-width: 8
00218  * c-basic-offset: 4
00219  * indent-tabs-mode: t
00220  * End:
00221  * ex: shiftwidth=4 tabstop=8
00222  */

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