g_grip.c

Go to the documentation of this file.
00001 /** @addtogroup g_  */
00002 /*@{*/
00003 /** @file g_grip.c
00004  *  Intersect a ray with a "grip" and return nothing.
00005  *
00006  *
00007  *  A GRIP is defiend by a direction normal, a center and a
00008  *  height/magnitued vector.  The center is the control point used
00009  *  for all grip movements.
00010  *
00011  *  All Ray intersections return "missed"
00012  *
00013  *  The bounding box for a grip is emtpy.
00014  *
00015  *  Authors -
00016  *      Christopher T. Johnson
00017  *
00018  *
00019  *  Copyright Notice -
00020  *      This software is Copyright (C) 1993 by Geometric Solutions, Inc.
00021  *      All rights reserved.
00022  */
00023 
00024 #ifndef lint
00025 static const char RCSgrip[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_grip.c,v 14.6 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00026 #endif
00027 
00028 #include "common.h"
00029 
00030 #include <stddef.h>
00031 #include <stdio.h>
00032 #include <math.h>
00033 
00034 #include "machine.h"
00035 #include "vmath.h"
00036 #include "raytrace.h"
00037 #include "nmg.h"
00038 #include "db.h"
00039 #include "rtgeom.h"
00040 #include "./debug.h"
00041 
00042 struct grip_specific {
00043         long    grip_magic;
00044         vect_t  grip_center;
00045         vect_t  grip_normal;
00046         fastf_t grip_mag;
00047 };
00048 #define GRIP_NULL       ((struct grip_specific *)0)
00049 
00050 const struct bu_structparse rt_grp_parse[] = {
00051         { "%f", 3, "V", bu_offsetof(struct rt_grip_internal, center[X]), BU_STRUCTPARSE_FUNC_NULL },
00052         { "%f", 3, "N", bu_offsetof(struct rt_grip_internal, normal[X]), BU_STRUCTPARSE_FUNC_NULL },
00053         { "%f", 1, "L", bu_offsetof(struct rt_grip_internal, mag), BU_STRUCTPARSE_FUNC_NULL },
00054         { {'\0','\0','\0','\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL }
00055 };
00056 
00057 /**
00058  *                      R T _ G R P _ P R E P
00059  */
00060 int
00061 rt_grp_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00062 {
00063         struct rt_grip_internal *gip;
00064         register struct grip_specific *gripp;
00065 
00066         gip = (struct rt_grip_internal *)ip->idb_ptr;
00067         RT_GRIP_CK_MAGIC(gip);
00068 
00069         BU_GETSTRUCT( gripp, grip_specific);
00070         stp->st_specific = (genptr_t)gripp;
00071 
00072         VMOVE(gripp->grip_normal, gip->normal);
00073         VMOVE(gripp->grip_center, gip->center);
00074         gripp->grip_mag = gip->mag;
00075 
00076         /* No bounding sphere or bounding RPP is possible */
00077         VSETALL( stp->st_min, 0.0);
00078         VSETALL( stp->st_max, 0.0);
00079 
00080         stp->st_aradius = 0.0;
00081         stp->st_bradius = 0.0;
00082         return 0;               /* OK */
00083 }
00084 
00085 /**
00086  *                      R T _ G R P _ P R I N T
00087  */
00088 void
00089 rt_grp_print(register const struct soltab *stp)
00090 {
00091         register const struct grip_specific *gripp =
00092                 (struct grip_specific *)stp->st_specific;
00093 
00094         if( gripp == GRIP_NULL )  {
00095                 bu_log("grip(%s):  no data?\n", stp->st_name);
00096                 return;
00097         }
00098         VPRINT( "Center", gripp->grip_center);
00099         VPRINT( "Normal", gripp->grip_normal);
00100         bu_log( "mag = %f\n", gripp->grip_mag);
00101 }
00102 
00103 /**
00104  *                      R T _ G R P _ S H O T
00105  *
00106  * Function -
00107  *      Shoot a ray at a GRIP
00108  *
00109  * Algorithm -
00110  *      The intersection distance is computed.
00111  *
00112  * Returns -
00113  *      0       MISS
00114  *      >0      HIT
00115  */
00116 int
00117 rt_grp_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00118 {
00119         return 0;       /* this has got to be the easiest */
00120                         /* RT routine I've written */
00121 }
00122 
00123 #define RT_HALF_SEG_MISS(SEG)   (SEG).seg_stp=RT_SOLTAB_NULL
00124 
00125 /**
00126  *                      R T _ G R P _ V S H O T
00127  *
00128  *  Vectorizing version.
00129  */
00130 void
00131 rt_grp_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
00132                                /* An array of solid pointers */
00133                                /* An array of ray pointers */
00134                                /* array of segs (results returned) */
00135                                /* Number of ray/object pairs */
00136 
00137 {
00138         return;
00139 }
00140 
00141 /**
00142  *                      R T _ G R P _ N O R M
00143  *
00144  *  Given ONE ray distance, return the normal and entry/exit point.
00145  *  The normal is already filled in.
00146  */
00147 void
00148 rt_grp_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
00149 {
00150         rt_bomb("rt_grp_norm: grips should never be hit.\n");
00151 }
00152 /**
00153  *                      R T _ G R P _ C U R V E
00154  *
00155  *  Return the "curvature" of the grip.
00156  */
00157 void
00158 rt_grp_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
00159 {
00160         rt_bomb("rt_grp_curve: nobody should be asking for curve of a grip.\n");
00161 }
00162 
00163 /**
00164  *                      R T _ G R P _ U V
00165  *
00166  *  For a hit on a face of an HALF, return the (u,v) coordinates
00167  *  of the hit point.  0 <= u,v <= 1.
00168  *  u extends along the Xbase direction
00169  *  v extends along the "Ybase" direction
00170  *  Note that a "toroidal" map is established, varying each from
00171  *  0 up to 1 and then back down to 0 again.
00172  */
00173 void
00174 rt_grp_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
00175 {
00176         rt_bomb("rt_grp_uv: nobody should be asking for UV of a grip.\n");
00177 }
00178 
00179 /**
00180  *                      R T _ G R P _ F R E E
00181  */
00182 void
00183 rt_grp_free(struct soltab *stp)
00184 {
00185         register struct grip_specific *gripp =
00186                 (struct grip_specific *)stp->st_specific;
00187 
00188         bu_free( (char *)gripp, "grip_specific");
00189 }
00190 
00191 int
00192 rt_grp_class(void)
00193 {
00194         return(0);
00195 }
00196 
00197 /**
00198  *                      R T _ G R P _ P L O T
00199  *
00200  * We represent a GRIP as a pyramid.  The center describes where
00201  * the center of the base is.  The normal describes which direction
00202  * the tip of the pyramid is.  Mag describes the distence from the
00203  * center to the tip. 1/4 of the width is the length of a base side.
00204  *
00205  */
00206 int
00207 rt_grp_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00208 {
00209         struct rt_grip_internal *gip;
00210         vect_t xbase, ybase;    /* perpendiculars to normal */
00211         vect_t x1, x2;
00212         vect_t y1, y2;
00213         vect_t tip;
00214 
00215         RT_CK_DB_INTERNAL(ip);
00216         gip = (struct rt_grip_internal *)ip->idb_ptr;
00217         RT_GRIP_CK_MAGIC(gip);
00218 
00219         /* The use of "x" and "y" here is not related to the axis */
00220         bn_vec_perp( xbase, gip->normal );
00221         VCROSS( ybase, xbase, gip->normal );
00222 
00223         /* Arrange for the cross to be 2 meters across */
00224         VUNITIZE( xbase );
00225         VUNITIZE( ybase);
00226         VSCALE( xbase, xbase, gip->mag/4.0 );
00227         VSCALE( ybase, ybase, gip->mag/4.0 );
00228 
00229         VADD2( x1, gip->center, xbase );
00230         VSUB2( x2, gip->center, xbase );
00231         VADD2( y1, gip->center, ybase );
00232         VSUB2( y2, gip->center, ybase );
00233 
00234         RT_ADD_VLIST( vhead, x1, BN_VLIST_LINE_MOVE );  /* the base */
00235         RT_ADD_VLIST( vhead, y1, BN_VLIST_LINE_DRAW );
00236         RT_ADD_VLIST( vhead, x2, BN_VLIST_LINE_DRAW );
00237         RT_ADD_VLIST( vhead, y2, BN_VLIST_LINE_DRAW );
00238         RT_ADD_VLIST( vhead, x1, BN_VLIST_LINE_DRAW );
00239 
00240         VSCALE( tip, gip->normal, gip->mag );
00241         VADD2( tip, gip->center, tip );
00242 
00243         RT_ADD_VLIST( vhead, x1,  BN_VLIST_LINE_MOVE ); /* the sides */
00244         RT_ADD_VLIST( vhead, tip, BN_VLIST_LINE_DRAW );
00245         RT_ADD_VLIST( vhead, x2,  BN_VLIST_LINE_DRAW );
00246         RT_ADD_VLIST( vhead, y1,  BN_VLIST_LINE_MOVE );
00247         RT_ADD_VLIST( vhead, tip, BN_VLIST_LINE_DRAW );
00248         RT_ADD_VLIST( vhead, y2,  BN_VLIST_LINE_DRAW );
00249         return(0);
00250 }
00251 
00252 /**
00253  *                      R T _ G R P _ I M P O R T
00254  *
00255  *  Returns -
00256  *      -1      failure
00257  *       0      success
00258  */
00259 int
00260 rt_grp_import(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
00261 {
00262         struct rt_grip_internal *gip;
00263         union record    *rp;
00264 
00265         fastf_t         orig_eqn[3*3];
00266         register double f,t;
00267 
00268         BU_CK_EXTERNAL( ep );
00269         rp = (union record *)ep->ext_buf;
00270         if( rp->u_id != ID_SOLID )  {
00271                 bu_log("rt_grp_import: defective record, id=x%x\n", rp->u_id);
00272                 return(-1);
00273         }
00274 
00275         RT_CK_DB_INTERNAL( ip );
00276         ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00277         ip->idb_type = ID_GRIP;
00278         ip->idb_meth = &rt_functab[ID_GRIP];
00279         ip->idb_ptr = bu_malloc( sizeof(struct rt_grip_internal), "rt_grip_internal");
00280         gip = (struct rt_grip_internal *)ip->idb_ptr;
00281         gip->magic = RT_GRIP_INTERNAL_MAGIC;
00282 
00283         rt_fastf_float( orig_eqn, rp->s.s_values, 3 );  /* 2 floats to many */
00284 
00285         /* Transform the point, and the normal */
00286         MAT4X3PNT( gip->center, mat, &orig_eqn[0] );
00287         MAT4X3VEC( gip->normal, mat, &orig_eqn[3] );
00288         if ( NEAR_ZERO(mat[15], 0.001) ) {
00289                 rt_bomb("rt_grip_import, scale factor near zero.");
00290         }
00291         gip->mag = orig_eqn[6]/mat[15];
00292 
00293         /* Verify that normal has unit length */
00294         f = MAGNITUDE( gip->normal );
00295         if( f < SMALL )  {
00296                 bu_log("rt_grp_import:  bad normal, len=%g\n", f );
00297                 return(-1);             /* BAD */
00298         }
00299         t = f - 1.0;
00300         if( !NEAR_ZERO( t, 0.001 ) )  {
00301                 /* Restore normal to unit length */
00302                 f = 1/f;
00303                 VSCALE( gip->normal, gip->normal, f );
00304         }
00305         return 0;                       /* OK */
00306 }
00307 
00308 /**
00309  *                      R T _ G R P _ E X P O R T
00310  */
00311 int
00312 rt_grp_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
00313 {
00314         struct rt_grip_internal *gip;
00315         union record            *rec;
00316 
00317         RT_CK_DB_INTERNAL(ip);
00318         if( ip->idb_type != ID_GRIP )  return(-1);
00319         gip = (struct rt_grip_internal *)ip->idb_ptr;
00320         RT_GRIP_CK_MAGIC(gip);
00321 
00322         BU_CK_EXTERNAL(ep);
00323         ep->ext_nbytes = sizeof(union record);
00324         ep->ext_buf = (genptr_t)bu_calloc( 1, ep->ext_nbytes, "grip external");
00325         rec = (union record *)ep->ext_buf;
00326 
00327         rec->s.s_id = ID_SOLID;
00328         rec->s.s_type = GRP;
00329         VMOVE(&rec->s.s_grip_N, gip->normal);
00330         VMOVE(&rec->s.s_grip_C, gip->center);
00331         rec->s.s_grip_m = gip->mag;
00332 
00333         return(0);
00334 }
00335 
00336 int
00337 rt_grp_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
00338 {
00339         struct rt_grip_internal *gip;
00340         fastf_t                 vec[7];
00341         register double         f,t;
00342 
00343         RT_CK_DB_INTERNAL( ip );
00344         BU_CK_EXTERNAL( ep );
00345 
00346         BU_ASSERT_LONG( ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * 7 );
00347 
00348         ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00349         ip->idb_type = ID_GRIP;
00350         ip->idb_meth = &rt_functab[ID_GRIP];
00351         ip->idb_ptr = bu_malloc( sizeof(struct rt_grip_internal), "rt_grip_internal");
00352 
00353         gip = (struct rt_grip_internal *)ip->idb_ptr;
00354         gip->magic = RT_GRIP_INTERNAL_MAGIC;
00355 
00356         /* Convert from database (network) to internal (host) format */
00357         ntohd( (unsigned char *)vec, ep->ext_buf, 7 );
00358 
00359         /* Transform the point, and the normal */
00360         MAT4X3PNT( gip->center, mat, &vec[0] );
00361         MAT4X3VEC( gip->normal, mat, &vec[3] );
00362         if ( NEAR_ZERO(mat[15], 0.001) ) {
00363                 rt_bomb("rt_grip_import5, scale factor near zero.");
00364         }
00365         gip->mag = vec[6]/mat[15];
00366 
00367         /* Verify that normal has unit length */
00368         f = MAGNITUDE( gip->normal );
00369         if( f < SMALL )  {
00370                 bu_log("rt_grp_import:  bad normal, len=%g\n", f );
00371                 return(-1);             /* BAD */
00372         }
00373         t = f - 1.0;
00374         if( !NEAR_ZERO( t, 0.001 ) )  {
00375                 /* Restore normal to unit length */
00376                 f = 1/f;
00377                 VSCALE( gip->normal, gip->normal, f );
00378         }
00379         return 0;               /* OK */
00380 }
00381 
00382 /**
00383  *                      R T _ G R I P _ E X P O R T 5
00384  *
00385  */
00386 int
00387 rt_grp_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
00388 {
00389         struct rt_grip_internal *gip;
00390         fastf_t                 vec[7];
00391 
00392         RT_CK_DB_INTERNAL(ip);
00393         if( ip->idb_type != ID_GRIP )  return(-1);
00394         gip = (struct rt_grip_internal *)ip->idb_ptr;
00395         RT_GRIP_CK_MAGIC(gip);
00396 
00397         BU_CK_EXTERNAL(ep);
00398         ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * 7;
00399         ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes, "grip external");
00400 
00401         VSCALE( &vec[0], gip->center, local2mm );
00402         VMOVE( &vec[3], gip->normal );
00403         vec[6] = gip->mag * local2mm;
00404 
00405         /* Convert from internal (host) to database (network) format */
00406         htond( ep->ext_buf, (unsigned char *)vec, 7 );
00407 
00408         return 0;
00409 }
00410 
00411 /**
00412  *                      R T _ G R P _ D E S C R I B E
00413  *
00414  *  Make human-readable formatted presentation of this solid.
00415  *  First line describes type of solid.
00416  *  Additional lines are indented one tab, and give parameter values.
00417  */
00418 int
00419 rt_grp_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
00420 {
00421         register struct rt_grip_internal        *gip =
00422                 (struct rt_grip_internal *)ip->idb_ptr;
00423         char    buf[256];
00424 
00425         RT_GRIP_CK_MAGIC(gip);
00426         bu_vls_strcat( str, "grip\n");
00427 
00428         sprintf(buf, "\tN (%g, %g, %g)\n",
00429                 V3INTCLAMPARGS(gip->normal));           /* should have unit length */
00430 
00431         bu_vls_strcat( str, buf );
00432 
00433         sprintf(buf, "\tC (%g %g %g) mag=%g\n",
00434                 INTCLAMP(gip->center[0]*mm2local), 
00435                 INTCLAMP(gip->center[1]*mm2local),
00436                 INTCLAMP(gip->center[2]*mm2local),
00437                 INTCLAMP(gip->mag*mm2local) );
00438 
00439         bu_vls_strcat( str, buf);
00440         return(0);
00441 }
00442 
00443 /**
00444  *                      R T _ G R P _ I F R E E
00445  *
00446  *  Free the storage associated with the rt_db_internal version of this solid.
00447  */
00448 void
00449 rt_grp_ifree(struct rt_db_internal *ip)
00450 {
00451         RT_CK_DB_INTERNAL(ip);
00452         bu_free( ip->idb_ptr, "grip ifree" );
00453         ip->idb_ptr = GENPTR_NULL;
00454 }
00455 
00456 /**
00457  *                      R T _ G R P _ T E S S
00458  */
00459 int
00460 rt_grp_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00461 {
00462         struct rt_grip_internal *gip;
00463 
00464         RT_CK_DB_INTERNAL(ip);
00465         gip = (struct rt_grip_internal *)ip->idb_ptr;
00466         RT_GRIP_CK_MAGIC(gip);
00467 
00468         /* XXX tess routine needed */
00469         return(-1);
00470 }
00471 
00472 /*@}*/
00473 /*
00474  * Local Variables:
00475  * mode: C
00476  * tab-width: 8
00477  * c-basic-offset: 4
00478  * indent-tabs-mode: t
00479  * End:
00480  * ex: shiftwidth=4 tabstop=8
00481  */

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