mater.c

Go to the documentation of this file.
00001 /*                         M A T E R . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1985-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 /*@{*/
00025 /** @file mater.c
00026  *  Code to deal with establishing and maintaining the tables which
00027  *  map region ID codes into worthwhile material information
00028  *  (colors and outboard database "handles").
00029  *
00030  *  These really are "db_" routines, more fundamental than "rt_".
00031  *
00032  *  Functions -
00033  *      color_addrec    Called by rt_dirbuild on startup
00034  *      color_map       Map one region reference to a material
00035  *
00036  *  Author -
00037  *      Michael John Muuss
00038  *
00039  *  Source -
00040  *      SECAD/VLD Computing Consortium, Bldg 394
00041  *      The U. S. Army Ballistic Research Laboratory
00042  *      Aberdeen Proving Ground, Maryland  21005
00043  *
00044  */
00045 /*@}*/
00046 
00047 #ifndef lint
00048 static const char RCSmater[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/mater.c,v 14.10 2006/09/16 02:04:25 lbutler Exp $ (BRL)";
00049 #endif
00050 
00051 #include "common.h"
00052 
00053 
00054 
00055 #include <stdio.h>
00056 #include "machine.h"
00057 #include "vmath.h"
00058 #include "mater.h"
00059 #include "raytrace.h"
00060 #include "./debug.h"
00061 
00062 /*
00063  *  It is expected that entries on this mater list will be sorted
00064  *  in strictly ascending order, with no overlaps (ie, monotonicly
00065  * increasing).
00066  */
00067 struct mater *rt_material_head = MATER_NULL;
00068 
00069 void    rt_insert_color(struct mater *newp);
00070 
00071 /*
00072  *                      R T _ P R _ M A T E R
00073  */
00074 void
00075 rt_pr_mater(register struct mater *mp)
00076 {
00077         (void)bu_log( "%5d..%d\t", mp->mt_low, mp->mt_high );
00078         (void)bu_log( "%d,%d,%d\t", mp->mt_r, mp->mt_g, mp->mt_b);
00079 }
00080 
00081 /*
00082  *                      R T _ C O L O R _ A D D R E C
00083  *
00084  *  Called from db_scan() when initially scanning database.
00085  */
00086 void
00087 rt_color_addrec( int low, int hi, int r, int g, int b, long addr )
00088 {
00089         register struct mater *mp;
00090 
00091         BU_GETSTRUCT( mp, mater );
00092         mp->mt_low = low;
00093         mp->mt_high = hi;
00094         mp->mt_r = r;
00095         mp->mt_g = g;
00096         mp->mt_b = b;
00097 /*      mp->mt_handle = bu_strdup( recp->md.md_material ); */
00098         mp->mt_daddr = addr;
00099         rt_insert_color( mp );
00100 }
00101 
00102 /*
00103  *                      R T _ I N S E R T _ C O L O R
00104  *
00105  *  While any additional database records are created and written here,
00106  *  it is the responsibility of the caller to color_putrec(newp) if needed.
00107  */
00108 void
00109 rt_insert_color( struct mater *newp )
00110 {
00111         register struct mater *mp;
00112         register struct mater *zot;
00113 
00114         if( rt_material_head == MATER_NULL || newp->mt_high < rt_material_head->mt_low )  {
00115                 /* Insert at head of list */
00116                 newp->mt_forw = rt_material_head;
00117                 rt_material_head = newp;
00118                 return;
00119         }
00120         if( newp->mt_low < rt_material_head->mt_low )  {
00121                 /* Insert at head of list, check for redefinition */
00122                 newp->mt_forw = rt_material_head;
00123                 rt_material_head = newp;
00124                 goto check_overlap;
00125         }
00126         for( mp = rt_material_head; mp != MATER_NULL; mp = mp->mt_forw )  {
00127                 if( mp->mt_low == newp->mt_low  &&
00128                     mp->mt_high <= newp->mt_high )  {
00129                         bu_log("dropping overwritten region-id based material property entry:\n");
00130                         newp->mt_forw = mp->mt_forw;
00131                         rt_pr_mater( mp );
00132                         *mp = *newp;            /* struct copy */
00133                         bu_free( (char *)newp, "getstruct mater" );
00134                         newp = mp;
00135                         goto check_overlap;
00136                 }
00137                 if( mp->mt_low  < newp->mt_low  &&
00138                     mp->mt_high > newp->mt_high )  {
00139                         /* New range entirely contained in old range; split */
00140                         bu_log("Splitting region-id based material property entry into 3 ranges\n");
00141                         BU_GETSTRUCT( zot, mater );
00142                         *zot = *mp;             /* struct copy */
00143                         zot->mt_daddr = MATER_NO_ADDR;
00144                         /* zot->mt_high = mp->mt_high; */
00145                         zot->mt_low = newp->mt_high+1;
00146                         mp->mt_high = newp->mt_low-1;
00147                         /* mp, newp, zot */
00148                         /* zot->mt_forw = mp->mt_forw; */
00149                         newp->mt_forw = zot;
00150                         mp->mt_forw = newp;
00151                         rt_pr_mater( mp );
00152                         rt_pr_mater( newp );
00153                         rt_pr_mater( zot );
00154                         return;
00155                 }
00156                 if( mp->mt_high > newp->mt_low )  {
00157                         /* Overlap to the left: Shorten preceeding entry */
00158                         bu_log("Shortening region-id based material property entry lhs range, from:\n");
00159                         rt_pr_mater( mp );
00160                         bu_log("to:\n");
00161                         mp->mt_high = newp->mt_low-1;
00162                         rt_pr_mater( mp );
00163                         /* Now append */
00164                         newp->mt_forw = mp->mt_forw;
00165                         mp->mt_forw = newp;
00166                         goto check_overlap;
00167                 }
00168                 if( mp->mt_forw == MATER_NULL ||
00169                     newp->mt_low < mp->mt_forw->mt_low )  {
00170                         /* Append */
00171                         newp->mt_forw = mp->mt_forw;
00172                         mp->mt_forw = newp;
00173                         goto check_overlap;
00174                 }
00175         }
00176         bu_log("fell out of rt_insert_color loop, append region-id based material property entry to end of list\n");
00177         /* Append at end */
00178         newp->mt_forw = MATER_NULL;
00179         mp->mt_forw = newp;
00180         return;
00181 
00182         /* Check for overlap, ie, redefinition of following colors */
00183 check_overlap:
00184         while( newp->mt_forw != MATER_NULL &&
00185                newp->mt_high >= newp->mt_forw->mt_low )  {
00186                 if( newp->mt_high >= newp->mt_forw->mt_high )  {
00187                         /* Drop this mater struct */
00188                         zot = newp->mt_forw;
00189                         newp->mt_forw = zot->mt_forw;
00190                         bu_log("dropping overlaping region-id based material property entry:\n");
00191                         rt_pr_mater( zot );
00192                         bu_free( (char *)zot, "getstruct mater" );
00193                         continue;
00194                 }
00195                 if( newp->mt_high >= newp->mt_forw->mt_low )  {
00196                         /* Shorten this mater struct, then done */
00197                         bu_log("Shortening region-id based material property entry rhs range, from:\n");
00198                         rt_pr_mater( newp->mt_forw );
00199                         bu_log("to:\n");
00200                         newp->mt_forw->mt_low = newp->mt_high+1;
00201                         rt_pr_mater( newp->mt_forw );
00202                         continue;       /* more conservative than returning */
00203                 }
00204         }
00205 }
00206 
00207 /*
00208  *                      R T _ R E G I O N _ C O L O R _ M A P
00209  *
00210  *  If the GIFT regionid of this region falls into a mapped area
00211  *  of regionid-driven color override.
00212  */
00213 void
00214 rt_region_color_map(register struct region *regp)
00215 {
00216         register struct mater *mp;
00217 
00218         if( regp == REGION_NULL )  {
00219                 bu_log("color_map(NULL)\n");
00220                 return;
00221         }
00222         for( mp = rt_material_head; mp != MATER_NULL; mp = mp->mt_forw )  {
00223                 if( regp->reg_regionid <= mp->mt_high &&
00224                     regp->reg_regionid >= mp->mt_low ) {
00225                         regp->reg_mater.ma_color_valid = 1;
00226                         regp->reg_mater.ma_color[0] =
00227                                 (((double)mp->mt_r)+0.5)*bn_inv255;
00228                         regp->reg_mater.ma_color[1] =
00229                                 (((double)mp->mt_g)+0.5)*bn_inv255;
00230                         regp->reg_mater.ma_color[2] =
00231                                 (((double)mp->mt_b)+0.5)*bn_inv255;
00232                         return;
00233                 }
00234         }
00235 }
00236 
00237 /*
00238  *                      R T _ C O L O R _ F R E E
00239  *
00240  *  Really should be db_color_free().
00241  *  Called from db_close().
00242  */
00243 void
00244 rt_color_free(void)
00245 {
00246         register struct mater *mp;
00247 
00248         while( (mp = rt_material_head) != MATER_NULL )  {
00249                 rt_material_head = mp->mt_forw; /* Dequeue 'mp' */
00250                 /* mt_handle? */
00251                 bu_free( (char *)mp, "getstruct mater" );
00252         }
00253 }
00254 
00255 /*
00256  * Local Variables:
00257  * mode: C
00258  * tab-width: 8
00259  * c-basic-offset: 4
00260  * indent-tabs-mode: t
00261  * End:
00262  * ex: shiftwidth=4 tabstop=8
00263  */

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