nurb_bound.c

Go to the documentation of this file.
00001 /*                    N U R B _ B O U N D . 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 /*@{*/
00025 /** @file nurb_bound.c
00026  *     Find the bounding box for the a NURB surface.
00027  *
00028  * Author -
00029  *     Paul R. Stay
00030  *
00031  * Source -
00032  *     SECAD/VLD Computing Consortium, Bldg 394
00033  *     The U.S. Army Ballistic Research Laboratory
00034  *     Aberdeen Proving Ground, Maryland 21005
00035  *
00036  */
00037 /*@}*/
00038 
00039 /* Since a B-Spline surface follows the convex hull property
00040  * the bounding box can be found by taking the min and max of
00041  * all points in the control  If the surface mesh contains
00042  * homogeneous points (i.e. [XYZW]) then divide out the W first.
00043  */
00044 
00045 #include "common.h"
00046 
00047 
00048 
00049 #include <stdio.h>
00050 
00051 #include "machine.h"
00052 #include "vmath.h"
00053 #include "raytrace.h"
00054 #include "nurb.h"
00055 
00056 #define NEAR_ZERO(val,epsilon)  ( ((val) > -epsilon) && ((val) < epsilon) )
00057 
00058 #ifndef INFINITY                /* if INFINITY is not defined define it */
00059 #define INFINITY        (1.0e20)
00060 #endif
00061 
00062 /* rt_nurb_sbound()
00063  *      Calculates the bounding Right Parallel Piped (RPP) of the
00064  *      NURB surface, and returns the minimum and maximum points
00065  *      of the surface.
00066  */
00067 
00068 int
00069 rt_nurb_s_bound(struct face_g_snurb *srf, fastf_t *bmin, fastf_t *bmax)
00070 {
00071         register fastf_t *p_ptr;        /* Mesh pointr */
00072         register int    coords;         /* Elements per vector */
00073         int     i;
00074         int     rat;
00075 
00076 
00077         bmin[0] = bmin[1] = bmin[2] = INFINITY;
00078         bmax[0] = bmax[1] = bmax[2] = -INFINITY;
00079 
00080         if ( srf == (struct face_g_snurb *)0 )  {
00081                 bu_log("nurb_s_bound:  NULL surface\n");
00082                 return(-1);             /* BAD */
00083         }
00084 
00085         p_ptr = srf->ctl_points;
00086         coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
00087         rat =    RT_NURB_IS_PT_RATIONAL(srf->pt_type);
00088 
00089         for ( i = ( srf->s_size[RT_NURB_SPLIT_ROW] *
00090             srf->s_size[RT_NURB_SPLIT_COL] ); i > 0; i--) {
00091                 if ( !rat ) {
00092                         VMINMAX( bmin, bmax, p_ptr );
00093                 } else if ( rat  ) {
00094                         point_t tmp_pt;
00095                         if ( NEAR_ZERO( p_ptr[H], SMALL ) )  {
00096                                 HPRINT( "mesh point", p_ptr );
00097                                 bu_log("nurb_s_bound:  H too small\n");
00098                         } else {
00099                                 HDIVIDE( tmp_pt, p_ptr );
00100                                 VMINMAX( bmin, bmax, tmp_pt );
00101                         }
00102                 }
00103                 p_ptr += coords;
00104         }
00105         return(0);      /* OK */
00106 }
00107 
00108 
00109 int
00110 rt_nurb_c_bound(struct edge_g_cnurb *crv, fastf_t *bmin, fastf_t *bmax)
00111 {
00112         register fastf_t *p_ptr;        /* Mesh pointr */
00113         register int    coords;         /* Elements per vector */
00114         int     i;
00115         int     rat;
00116 
00117 
00118         bmin[0] = bmin[1] = bmin[2] = INFINITY;
00119         bmax[0] = bmax[1] = bmax[2] = -INFINITY;
00120 
00121         if ( crv == (struct edge_g_cnurb *)0 )  {
00122                 bu_log("nurb_c_bound:  NULL surface\n");
00123                 return(-1);             /* BAD */
00124         }
00125 
00126         p_ptr = crv->ctl_points;
00127         coords = RT_NURB_EXTRACT_COORDS(crv->pt_type);
00128         rat =    RT_NURB_IS_PT_RATIONAL(crv->pt_type);
00129 
00130         for ( i = crv->c_size; i > 0; i--) {
00131                 if ( !rat ) {
00132                         VMINMAX( bmin, bmax, p_ptr );
00133                 } else if ( rat  ) {
00134                         point_t tmp_pt;
00135                         if ( NEAR_ZERO( p_ptr[H], SMALL ) )  {
00136                                 HPRINT( "mesh point", p_ptr );
00137                                 bu_log("nurb_c_bound:  H too small\n");
00138                         } else {
00139                                 HDIVIDE( tmp_pt, p_ptr );
00140                                 VMINMAX( bmin, bmax, tmp_pt );
00141                         }
00142                 }
00143                 p_ptr += coords;
00144         }
00145         return(0);      /* OK */
00146 }
00147 
00148 
00149 /* rt_nurb_s_check( srf )
00150  *      Checks the NURB surface control points to make
00151  *      sure no one point is near INIFITY, which probably means
00152  *      that the surface mesh is bad.
00153  */
00154 
00155 int
00156 rt_nurb_s_check(register struct face_g_snurb *srf)
00157 {
00158         register fastf_t *mp;   /* Mesh pointr */
00159         register int    i;
00160 
00161         mp = srf->ctl_points;
00162         i = srf->s_size[RT_NURB_SPLIT_ROW] *
00163             srf->s_size[RT_NURB_SPLIT_COL] *
00164             srf->pt_type;
00165         for ( ; i > 0; i--, mp++)  {
00166                 /* Sanity checking */
00167                 if ( !NEAR_ZERO( *mp, INFINITY ) )  {
00168                         bu_log("nurb_s_check:  bad mesh found\n");
00169                         return(-1);     /* BAD */
00170                 }
00171         }
00172         return(0);                      /* OK */
00173 }
00174 
00175 
00176 
00177 /* rt_nurb_c_check( srf )
00178  *      Checks the NURB curve control points to make
00179  *      sure no one point is near INIFITY, which probably means
00180  *      that the surface mesh is bad.
00181  */
00182 
00183 int
00184 rt_nurb_c_check(register struct edge_g_cnurb *crv)
00185 {
00186         register fastf_t *mp;   /* Mesh pointr */
00187         register int    i;
00188 
00189         mp = crv->ctl_points;
00190         i = crv->c_size *
00191             crv->pt_type;
00192         for ( ; i > 0; i--, mp++)  {
00193                 /* Sanity checking */
00194                 if ( !NEAR_ZERO( *mp, INFINITY ) )  {
00195                         bu_log("nurb_c_check:  bad mesh found\n");
00196                         return(-1);     /* BAD */
00197                 }
00198         }
00199         return(0);                      /* OK */
00200 }
00201 
00202 
00203 
00204 /*
00205  * Local Variables:
00206  * mode: C
00207  * tab-width: 8
00208  * c-basic-offset: 4
00209  * indent-tabs-mode: t
00210  * End:
00211  * ex: shiftwidth=4 tabstop=8
00212  */

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