nmg.h

Go to the documentation of this file.
00001 /*                           N M G . H
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2004-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.1 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 /** @addtogroup nmg */
00022 /*@{*/
00023 /** @file nmg.h
00024  *
00025  *
00026  *  @author     Lee A. Butler
00027  *  @author     Michael John Muuss
00028  *
00029  *  @par Source
00030  *      The U. S. Army Research Laboratory
00031  *@n    Aberdeen Proving Ground, Maryland  21005-5066
00032  *
00033  *@brief
00034  *  Definition of data structures for "Non-Manifold Geometry Modelling."
00035  *  Developed from "Non-Manifold Geometric Boundary Modeling" by
00036  *  Kevin Weiler, 5/7/87 (SIGGraph 1989 Course #20 Notes)
00037  *
00038  *  Include Sequencing -
00039  *      #  include <stdio.h>
00040  *      # include <math.h>
00041  *      # include "machine.h"   /_* For fastf_t definition on this machine *_/
00042  *      # include "vmath.h"     /_* For vect_t definition *_/
00043  *      # include "rtlist.h"    /_* OPTIONAL, auto-included by raytrace.h *_/
00044  *      # include "rtstring.h"  /_* OPTIONAL, auto-included by raytrace.h *_/
00045  *      # include "nmg.h"
00046  *      # include "raytrace.h"
00047  *      # include "nurb.h"      /_* OPTIONAL, follows raytrace.h when used *_/
00048  *
00049  *  @par Libraries Used -
00050  *      LIBRT LIBRT_LIBES -lm -lc
00051  *
00052  *  $Header: /cvsroot/brlcad/brlcad/include/nmg.h,v 14.10 2006/09/18 05:24:07 lbutler Exp $
00053  */
00054 #ifndef NMG_H
00055 #define NMG_H seen
00056 
00057 #include "common.h"
00058 
00059 /* make sure all the prerequisite include files have been included
00060  */
00061 #ifndef MACHINE_H
00062 #include "machine.h"
00063 #endif
00064 
00065 #ifndef VMATH_H
00066 #include "vmath.h"
00067 #endif
00068 
00069 #ifndef SEEN_RTLIST_H
00070 #include "rtlist.h"
00071 #endif
00072 
00073 #ifndef SEEN_COMPAT4_H
00074 #include "compat4.h"
00075 #endif
00076 
00077 #ifndef SEEN_BU_H
00078 #include "bu.h"
00079 #endif
00080 
00081 #ifndef NULL
00082 #define NULL 0
00083 #endif
00084 
00085 #define NMG_EXTERN(type_and_name,args)  RT_EXTERN(type_and_name,args)
00086 
00087 
00088 #define DEBUG_PL_ANIM   0x00000001      /**< @brief 1 mged: animated evaluation */
00089 #define DEBUG_PL_SLOW   0x00000002      /**< @brief 2 mged: add delays to animation */
00090 #define DEBUG_GRAPHCL   0x00000004      /**< @brief 3 mged: graphic classification */
00091 #define DEBUG_PL_LOOP   0x00000008      /**< @brief 4 loop class (needs GRAPHCL) */
00092 #define DEBUG_PLOTEM    0x00000010      /**< @brief 5 make plots in debugged routines (needs other flags set too) */
00093 #define DEBUG_POLYSECT  0x00000020      /**< @brief 6 nmg_inter: face intersection */
00094 #define DEBUG_VERIFY    0x00000040      /**< @brief 7 nmg_vshell() frequently, verify health */
00095 #define DEBUG_BOOL      0x00000080      /**< @brief 8 nmg_bool:  */
00096 #define DEBUG_CLASSIFY  0x00000100      /**< @brief 9 nmg_class: */
00097 #define DEBUG_BOOLEVAL  0x00000200      /**< @brief 10 nmg_eval: what to retain */
00098 #define DEBUG_BASIC     0x00000400      /**< @brief 013 nmg_mk.c and nmg_mod.c routines */
00099 #define DEBUG_MESH      0x00000800      /**< @brief 12 nmg_mesh: describe edge search */
00100 #define DEBUG_MESH_EU   0x00001000      /**< @brief 13 nmg_mesh: list edges meshed */
00101 #define DEBUG_POLYTO    0x00002000      /**< @brief 14 nmg_misc: polytonmg */
00102 #define DEBUG_LABEL_PTS 0x00004000      /**< @brief 15 label points in plot files */
00103 /***#define DEBUG_INS   0x00008000      /_* 16 bu_ptbl table insert */
00104 #define DEBUG_NMGRT     0x00010000      /**< @brief 17 ray tracing */
00105 #define DEBUG_FINDEU    0x00020000      /**< @brief 18 nmg_mod: nmg_findeu() */
00106 #define DEBUG_CMFACE    0x00040000      /**< @brief 19 nmg_mod: nmg_cmface() */
00107 #define DEBUG_CUTLOOP   0x00080000      /**< @brief 024 nmg_mod: nmg_cut_loop */
00108 #define DEBUG_VU_SORT   0x00100000      /**< @brief 025 nmg_fcut: coincident vu sort */
00109 #define DEBUG_FCUT      0x00200000      /**< @brief 026 nmg_fcut: face cutter */
00110 #define DEBUG_RT_SEGS   0x00400000      /**< @brief 027 nmg_rt_segs: */
00111 #define DEBUG_RT_ISECT  0x00800000      /**< @brief 028 nmg_rt_isect: */
00112 #define DEBUG_TRI       0x01000000      /**< @brief 029 nmg_tri */
00113 #define DEBUG_PT_FU     0x02000000      /**< @brief 029 nmg_pt_fu */
00114 #define DEBUG_MANIF     0x04000000      /**< @brief 029 nmg_manif */
00115 #define NMG_DEBUG_FORMAT \
00116 "\020\033MANIF\032PTFU\031TRIANG\030RT_ISECT\
00117 \027RT_SEGS\026FCUT\025VU_SORT\024CUTLOOP\023CMFACE\022FINDEU\021RT_ISECT\020(FREE)\
00118 \017LABEL_PTS\016POLYTO\015MESH_EU\014MESH\013BASIC\012BOOLEVAL\011CLASSIFY\
00119 \010BOOL\7VERIFY\6POLYSECT\5PLOTEM\4PL_LOOP\3GRAPHCL\2PL_SLOW\1PL_ANIM"
00120 
00121 /*
00122  *  Macros for providing function prototypes, regardless of whether
00123  *  the compiler understands them or not.
00124  *  It is vital that the argument list given for "args" be enclosed
00125  *  in parens.
00126  *  The setting of USE_PROTOTYPES is done in machine.h
00127  */
00128 #if USE_PROTOTYPES
00129 #       define  NMG_ARGS(args)                  args
00130 #else
00131 #       define  NMG_ARGS(args)                  ()
00132 #endif
00133 
00134 /* Boolean operations */
00135 #define NMG_BOOL_SUB 1          /**< @brief subtraction */
00136 #define NMG_BOOL_ADD 2          /**< @brief addition/union */
00137 #define NMG_BOOL_ISECT 4        /**< @brief intsersection */
00138 
00139 /* Boolean classifications */
00140 #define NMG_CLASS_Unknown       -1
00141 #define NMG_CLASS_AinB          0
00142 #define NMG_CLASS_AonBshared    1
00143 #define NMG_CLASS_AonBanti      2
00144 #define NMG_CLASS_AoutB         3
00145 #define NMG_CLASS_BinA          4
00146 #define NMG_CLASS_BonAshared    5
00147 #define NMG_CLASS_BonAanti      6
00148 #define NMG_CLASS_BoutA         7
00149 
00150 /* orientations available.  All topological elements are orientable. */
00151 #define OT_NONE     0    /**< @brief no orientation (error) */
00152 #define OT_SAME     1    /**< @brief orientation same */
00153 #define OT_OPPOSITE 2    /**< @brief orientation opposite */
00154 #define OT_UNSPEC   3    /**< @brief orientation unspecified */
00155 #define OT_BOOLPLACE 4   /**< @brief object is intermediate data for boolean ops */
00156 
00157 /*
00158  *  Magic Numbers.
00159  */
00160 #define NMG_MODEL_MAGIC         0x12121212
00161 #define NMG_REGION_MAGIC        0x23232323
00162 #define NMG_REGION_A_MAGIC      0x696e6720
00163 #define NMG_SHELL_MAGIC         0x71077345      /**< @brief shell oil */
00164 #define NMG_SHELL_A_MAGIC       0x65207761
00165 #define NMG_FACE_MAGIC          0x45454545
00166 #define NMG_FACE_G_PLANE_MAGIC  0x726b6e65
00167 #define NMG_FACE_G_SNURB_MAGIC  0x736e7262      /**< @brief was RT_SNURB_MAGIC */
00168 #define NMG_FACEUSE_MAGIC       0x56565656
00169 #define NMG_LOOP_MAGIC          0x67676767
00170 #define NMG_LOOP_G_MAGIC        0x6420224c
00171 #define NMG_LOOPUSE_MAGIC       0x78787878
00172 #define NMG_EDGE_MAGIC          0x33333333
00173 #define NMG_EDGE_G_LSEG_MAGIC   0x6c696768
00174 #define NMG_EDGE_G_CNURB_MAGIC  0x636e7262      /**< @brief was RT_CNURB_MAGIC */
00175 #define NMG_EDGEUSE_MAGIC       0x90909090
00176 #define NMG_EDGEUSE2_MAGIC      0x91919191      /**< @brief used in eu->l2.magic */
00177 #define NMG_VERTEX_MAGIC        0x00123123
00178 #define NMG_VERTEX_G_MAGIC      0x72737707
00179 #define NMG_VERTEXUSE_MAGIC     0x12341234
00180 #define NMG_VERTEXUSE_A_PLANE_MAGIC     0x69676874
00181 #define NMG_VERTEXUSE_A_CNURB_MAGIC     0x20416e64
00182 #define NMG_KNOT_VECTOR_MAGIC   0x6b6e6f74      /**< @brief aka RT_KNOT_VECTOR_MAGIC */
00183 
00184 /** 
00185  * macros to check/validate a structure pointer
00186  */
00187 #define NMG_CKMAG(_ptr, _magic, _str)   BU_CKMAG(_ptr,_magic,_str)
00188 #define NMG_CK2MAG(_ptr, _magic1, _magic2, _str)        \
00189         if( !(_ptr) || (*((long *)(_ptr)) != (_magic1) && *((long *)(_ptr)) != (_magic2) ) )  { \
00190                 bu_badmagic( (long *)(_ptr), _magic1, _str, __FILE__, __LINE__ ); \
00191         }
00192 
00193 #define NMG_CK_MODEL(_p)        NMG_CKMAG(_p, NMG_MODEL_MAGIC, "model")
00194 #define NMG_CK_REGION(_p)       NMG_CKMAG(_p, NMG_REGION_MAGIC, "region")
00195 #define NMG_CK_REGION_A(_p)     NMG_CKMAG(_p, NMG_REGION_A_MAGIC, "region_a")
00196 #define NMG_CK_SHELL(_p)        NMG_CKMAG(_p, NMG_SHELL_MAGIC, "shell")
00197 #define NMG_CK_SHELL_A(_p)      NMG_CKMAG(_p, NMG_SHELL_A_MAGIC, "shell_a")
00198 #define NMG_CK_FACE(_p)         NMG_CKMAG(_p, NMG_FACE_MAGIC, "face")
00199 #define NMG_CK_FACE_G_PLANE(_p) NMG_CKMAG(_p, NMG_FACE_G_PLANE_MAGIC, "face_g_plane")
00200 #define NMG_CK_FACE_G_SNURB(_p) NMG_CKMAG(_p, NMG_FACE_G_SNURB_MAGIC, "face_g_snurb")
00201 #define NMG_CK_FACE_G_EITHER(_p)        NMG_CK2MAG(_p, NMG_FACE_G_PLANE_MAGIC, NMG_FACE_G_SNURB_MAGIC, "face_g_plane|face_g_snurb")
00202 #define NMG_CK_FACEUSE(_p)      NMG_CKMAG(_p, NMG_FACEUSE_MAGIC, "faceuse")
00203 #define NMG_CK_LOOP(_p)         NMG_CKMAG(_p, NMG_LOOP_MAGIC, "loop")
00204 #define NMG_CK_LOOP_G(_p)       NMG_CKMAG(_p, NMG_LOOP_G_MAGIC, "loop_g")
00205 #define NMG_CK_LOOPUSE(_p)      NMG_CKMAG(_p, NMG_LOOPUSE_MAGIC, "loopuse")
00206 #define NMG_CK_EDGE(_p)         NMG_CKMAG(_p, NMG_EDGE_MAGIC, "edge")
00207 #define NMG_CK_EDGE_G_LSEG(_p)  NMG_CKMAG(_p, NMG_EDGE_G_LSEG_MAGIC, "edge_g_lseg")
00208 #define NMG_CK_EDGE_G_CNURB(_p) NMG_CKMAG(_p, NMG_EDGE_G_CNURB_MAGIC, "edge_g_cnurb")
00209 #define NMG_CK_EDGE_G_EITHER(_p)        NMG_CK2MAG(_p, NMG_EDGE_G_LSEG_MAGIC, NMG_EDGE_G_CNURB_MAGIC, "edge_g_lseg|edge_g_cnurb")
00210 #define NMG_CK_EDGEUSE(_p)      NMG_CKMAG(_p, NMG_EDGEUSE_MAGIC, "edgeuse")
00211 #define NMG_CK_VERTEX(_p)       NMG_CKMAG(_p, NMG_VERTEX_MAGIC, "vertex")
00212 #define NMG_CK_VERTEX_G(_p)     NMG_CKMAG(_p, NMG_VERTEX_G_MAGIC, "vertex_g")
00213 #define NMG_CK_VERTEXUSE(_p)    NMG_CKMAG(_p, NMG_VERTEXUSE_MAGIC, "vertexuse")
00214 #define NMG_CK_VERTEXUSE_A_PLANE(_p)    NMG_CKMAG(_p, NMG_VERTEXUSE_A_PLANE_MAGIC, "vertexuse_a_plane")
00215 #define NMG_CK_VERTEXUSE_A_CNURB(_p)    NMG_CKMAG(_p, NMG_VERTEXUSE_A_CNURB_MAGIC, "vertexuse_a_cnurb")
00216 #define NMG_CK_VERTEXUSE_A_EITHER(_p)   NMG_CK2MAG(_p, NMG_VERTEXUSE_A_PLANE_MAGIC, NMG_VERTEXUSE_A_CNURB_MAGIC, "vertexuse_a_plane|vertexuse_a_cnurb")
00217 #define NMG_CK_LIST(_p)         BU_CKMAG(_p, BU_LIST_HEAD_MAGIC, "bu_list")
00218 
00219 /* Used only in nmg_mod.c */
00220 #define NMG_TEST_EDGEUSE(_p) \
00221         if (!(_p)->l.forw || !(_p)->l.back || !(_p)->eumate_p || \
00222             !(_p)->radial_p || !(_p)->e_p || !(_p)->vu_p || \
00223             !(_p)->up.magic_p ) { \
00224                 bu_log("in %s at %d Bad edgeuse member pointer\n",\
00225                          __FILE__, __LINE__);  nmg_pr_eu(_p, (char *)NULL); \
00226                         rt_bomb("Null pointer\n"); \
00227         } else if ((_p)->vu_p->up.eu_p != (_p) || \
00228         (_p)->eumate_p->vu_p->up.eu_p != (_p)->eumate_p) {\
00229                 bu_log("in %s at %d edgeuse lost vertexuse\n",\
00230                          __FILE__, __LINE__); rt_bomb("bye");}
00231 
00232 /**
00233  *                      K N O T _ V E C T O R
00234  * @brief
00235  *  Definition of a knot vector.
00236  *
00237  *  Not found independently, but used in the cnurb and snurb structures.
00238  *  (Exactly the same as the definition in nurb.h)
00239  */
00240 struct knot_vector {
00241         int             magic;
00242         int             k_size;         /**< @brief knot vector size */
00243         fastf_t         * knots;        /**< @brief pointer to knot vector  */
00244 };
00245 #define RT_KNOT_VECTOR_MAGIC    NMG_KNOT_VECTOR_MAGIC   /**< @brief nurb.h compat */
00246 
00247 /*
00248  *      N O T I C E !
00249  *
00250  *      We rely on the fact that the first long in a struct is the magic
00251  *      number (which is used to identify the struct type).
00252  *      This may be either a long, or an rt_list structure, which
00253  *      starts with a magic number.
00254  *
00255  *      To these ends, there is a standard ordering for fields in "object-use"
00256  *      structures.  That ordering is:
00257  *              1) magic number, or rt_list structure
00258  *              2) pointer to parent
00259  *              5) pointer to mate
00260  *              6) pointer to geometry
00261  *              7) pointer to attributes
00262  *              8) pointer to child(ren)
00263  */
00264 
00265 
00266 /**
00267  *                      M O D E L
00268  */
00269 struct model {
00270         long                    magic;
00271         struct bu_list          r_hd;   /**< @brief list of regions */
00272         long                    index;  /**< @brief struct # in this model */
00273         long                    maxindex; /**< @brief # of structs so far */
00274 };
00275 
00276 /**
00277  *                      R E G I O N
00278  */
00279 struct nmgregion {
00280         struct bu_list          l;      /**< @brief regions, in model's r_hd list */
00281         struct model            *m_p;   /**< @brief owning model */
00282         struct nmgregion_a      *ra_p;  /**< @brief attributes */
00283         struct bu_list          s_hd;   /**< @brief list of shells in region */
00284         long                    index;  /**< @brief struct # in this model */
00285 };
00286 
00287 struct nmgregion_a {
00288         long                    magic;
00289         point_t                 min_pt; /**< @brief minimums of bounding box */
00290         point_t                 max_pt; /**< @brief maximums of bounding box */
00291         long                    index;  /**< @brief struct # in this model */
00292 };
00293 
00294 /**
00295  *                      S H E L L
00296  *
00297  *  When a shell encloses volume, it's done entirely by the list of faceuses.
00298  *
00299  *  The wire loopuses (each of which heads a list of edges) define a
00300  *  set of connected line segments which form a closed path, but do not
00301  *  enclose either volume or surface area.
00302  *
00303  *  The wire edgeuses are disconnected line segments.
00304  *  There is a special interpetation to the eu_hd list of wire edgeuses.
00305  *  Unlike edgeuses seen in loops, the eu_hd list contains eu1, eu1mate,
00306  *  eu2, eu2mate, ..., where each edgeuse and it's mate comprise a
00307  *  *non-connected* "wire" edge which starts at eu1->vu_p->v_p and ends
00308  *  at eu1mate->vu_p->v_p.  There is no relationship between the pairs
00309  *  of edgeuses at all, other than that they all live on the same linked
00310  *  list.
00311  */
00312 struct shell {
00313         struct bu_list          l;      /**< @brief shells, in region's s_hd list */
00314         struct nmgregion        *r_p;   /**< @brief owning region */
00315         struct shell_a          *sa_p;  /**< @brief attribs */
00316 
00317         struct bu_list          fu_hd;  /**< @brief list of face uses in shell */
00318         struct bu_list          lu_hd;  /**< @brief wire loopuses (edge groups) */
00319         struct bu_list          eu_hd;  /**< @brief wire list (shell has wires) */
00320         struct vertexuse        *vu_p;  /**< @brief internal ptr to single vertexuse */
00321         long                    index;  /**< @brief struct # in this model */
00322 };
00323 
00324 struct shell_a {
00325         long                    magic;
00326         point_t                 min_pt; /**< @brief minimums of bounding box */
00327         point_t                 max_pt; /**< @brief maximums of bounding box */
00328         long                    index;  /**< @brief struct # in this model */
00329 };
00330 
00331 /**
00332  *                      F A C E
00333  *
00334  *  Note: there will always be exactly two faceuse's using a face.
00335  *  To find them, go up fu_p for one, then across fumate_p to other.
00336  */
00337 struct face {
00338         struct bu_list          l;      /**< @brief faces in face_g's f_hd list */
00339         struct faceuse          *fu_p;  /**< @brief Ptr up to one use of this face */
00340         union {
00341                 long                *magic_p;
00342                 struct face_g_plane *plane_p;
00343                 struct face_g_snurb *snurb_p;
00344         } g;                            /**< @brief geometry */
00345         int                     flip;   /**< @brief !0 ==> flip normal of fg */
00346         /* These might be better stored in a face_a (not faceuse_a!) */
00347         /* These are not stored on disk */
00348         point_t                 min_pt; /**< @brief minimums of bounding box */
00349         point_t                 max_pt; /**< @brief maximums of bounding box */
00350         long                    index;  /**< @brief struct # in this model */
00351 };
00352 
00353 struct face_g_plane {
00354         long                    magic;
00355         struct bu_list          f_hd;   /**< @brief list of faces sharing this surface */
00356         plane_t                 N;      /**< @brief Plane equation (incl normal) */
00357         long                    index;  /**< @brief struct # in this model */
00358 };
00359 
00360 struct face_g_snurb {
00361         /* NOTICE:  l.forw & l.back *not* stored in database.  For LIBNURB internal use only. */
00362         struct bu_list          l;
00363         struct bu_list          f_hd;   /**< @brief list of faces sharing this surface */
00364         int                     order[2]; /**< @brief surface order [0] = u, [1] = v */
00365         struct knot_vector      u;      /**< @brief surface knot vectors */
00366         struct knot_vector      v;      /**< @brief surface knot vectors */
00367         /* surface control points */
00368         int                     s_size[2]; /**< @brief mesh size, u,v */
00369         int                     pt_type; /**< @brief surface point type */
00370         fastf_t                 *ctl_points; /**< @brief array [size[0]*size[1]] */
00371         /* START OF ITEMS VALID IN-MEMORY ONLY -- NOT STORED ON DISK */
00372         int                     dir;    /**< @brief direction of last refinement */
00373         point_t                 min_pt; /**< @brief min corner of bounding box */
00374         point_t                 max_pt; /**< @brief max corner of bounding box */
00375         /*   END OF ITEMS VALID IN-MEMORY ONLY -- NOT STORED ON DISK */
00376         long                    index;  /**< @brief struct # in this model */
00377 };
00378 
00379 struct faceuse {
00380         struct bu_list          l;      /**< @brief fu's, in shell's fu_hd list */
00381         struct shell            *s_p;   /**< @brief owning shell */
00382         struct faceuse          *fumate_p;    /**< @brief opposite side of face */
00383         int                     orientation;  /**< @brief rel to face geom defn */
00384         int                     outside; /**< @brief RESERVED for future:  See Lee Butler */
00385         struct face             *f_p;   /**< @brief face definition and attributes */
00386         struct bu_list          lu_hd;  /**< @brief list of loops in face-use */
00387         long                    index;  /**< @brief struct # in this model */
00388 };
00389 
00390 /** Returns a 3-tuple (vect_t), given faceuse and state of flip flags */
00391 #define NMG_GET_FU_NORMAL(_N, _fu)      { \
00392         register const struct faceuse   *_fu1 = (_fu); \
00393         register const struct face_g_plane      *_fg; \
00394         NMG_CK_FACEUSE(_fu1); \
00395         NMG_CK_FACE(_fu1->f_p); \
00396         _fg = _fu1->f_p->g.plane_p; \
00397         NMG_CK_FACE_G_PLANE(_fg); \
00398         if( (_fu1->orientation != OT_SAME) != (_fu1->f_p->flip != 0) )  { \
00399                 VREVERSE( _N, _fg->N); \
00400         } else { \
00401                 VMOVE( _N, _fg->N ); \
00402         } }
00403 
00404 /** Returns a 4-tuple (plane_t), given faceuse and state of flip flags */
00405 #define NMG_GET_FU_PLANE(_N, _fu)       { \
00406         register const struct faceuse   *_fu1 = (_fu); \
00407         register const struct face_g_plane      *_fg; \
00408         NMG_CK_FACEUSE(_fu1); \
00409         NMG_CK_FACE(_fu1->f_p); \
00410         _fg = _fu1->f_p->g.plane_p; \
00411         NMG_CK_FACE_G_PLANE(_fg); \
00412         if( (_fu1->orientation != OT_SAME) != (_fu1->f_p->flip != 0) )  { \
00413                 HREVERSE( _N, _fg->N); \
00414         } else { \
00415                 HMOVE( _N, _fg->N ); \
00416         } }
00417 
00418 /**
00419  *                      L O O P
00420  *
00421  *  To find all the uses of this loop, use lu_p for one loopuse,
00422  *  then go down and find an edge,
00423  *  then wander around either eumate_p or radial_p from there.
00424  *
00425  *  Normally, down_hd heads a doubly linked list of edgeuses.
00426  *  But, before using it, check BU_LIST_FIRST_MAGIC(&lu->down_hd)
00427  *  for the magic number type.
00428  *  If this is a self-loop on a single vertexuse, then get the vertex pointer
00429  *  with vu = BU_LIST_FIRST(vertexuse, &lu->down_hd)
00430  *
00431  *  This is an especially dangerous storage efficiency measure ("hack"),
00432  *  because the list that the vertexuse structure belongs to is headed,
00433  *  not by a superior element type, but by the vertex structure.
00434  *  When a loopuse needs to point down to a vertexuse, rip off the
00435  *  forw pointer.  Take careful note that this is just a pointer,
00436  *  **not** the head of a linked list (single, double, or otherwise)!
00437  *  Exercise great care!
00438  *
00439  *  The edges of an exterior (OT_SAME) loop occur in counter-clockwise
00440  *  order, as viewed from the normalward side (outside).
00441  */
00442 #define RT_LIST_SET_DOWN_TO_VERT(_hp,_vu)       { \
00443         (_hp)->forw = &((_vu)->l); (_hp)->back = (struct bu_list *)NULL; }
00444 
00445 struct loop {
00446         long                    magic;
00447         struct loopuse          *lu_p;  /**< @brief Ptr to one use of this loop */
00448         struct loop_g           *lg_p;  /**< @brief Geometry */
00449         long                    index;  /**< @brief struct # in this model */
00450 };
00451 
00452 struct loop_g {
00453         long                    magic;
00454         point_t                 min_pt; /**< @brief minimums of bounding box */
00455         point_t                 max_pt; /**< @brief maximums of bounding box */
00456         long                    index;  /**< @brief struct # in this model */
00457 };
00458 
00459 struct loopuse {
00460         struct bu_list          l;      /**< @brief lu's, in fu's lu_hd, or shell's lu_hd */
00461         union {
00462                 struct faceuse  *fu_p;  /**< @brief owning face-use */
00463                 struct shell    *s_p;
00464                 long            *magic_p;
00465         } up;
00466         struct loopuse          *lumate_p; /**< @brief loopuse on other side of face */
00467         int                     orientation;  /**< @brief OT_SAME=outside loop */
00468         struct loop             *l_p;   /**< @brief loop definition and attributes */
00469         struct bu_list          down_hd; /**< @brief eu list or vu pointer */
00470         long                    index;  /**< @brief struct # in this model */
00471 };
00472 
00473 /**
00474  *                      E D G E
00475  *
00476  *  To find all edgeuses of an edge, use eu_p to get an arbitrary edgeuse,
00477  *  then wander around either eumate_p or radial_p from there.
00478  *
00479  *  Only the first vertex of an edge is kept in an edgeuse (eu->vu_p).
00480  *  The other vertex can be found by either eu->eumate_p->vu_p or
00481  *  by BU_LIST_PNEXT_CIRC(edgeuse,eu)->vu_p.  Note that the first
00482  *  form gives a vertexuse in the faceuse of *opposite* orientation,
00483  *  while the second form gives a vertexuse in the faceuse of the correct
00484  *  orientation.  If going on to the vertex (vu_p->v_p), both forms
00485  *  are identical.
00486  *
00487  *  An edge_g_lseg structure represents a line in 3-space.  All edges on that
00488  *  line should share the same edge_g.
00489  *
00490  *  An edge occupies the range eu->param to eu->eumate_p->param in it's
00491  *  geometry's parameter space.  (cnurbs only)
00492  */
00493 struct edge {
00494         long                    magic;
00495         struct edgeuse          *eu_p;  /**< @brief Ptr to one use of this edge */
00496         long                    is_real;/**< @brief artifact or modeled edge (from tessellator) */
00497         long                    index;  /**< @brief struct # in this model */
00498 };
00499 
00500 /**
00501  *  IMPORTANT:  First two items in edge_g_lseg and edge_g_cnurb must be
00502  *  identical structure, so pointers are puns for both.
00503  *  eu_hd2 list must be in same place for both.
00504  */
00505 struct edge_g_lseg {
00506         struct bu_list          l;      /**< @brief NOTICE:  l.forw & l.back *not* stored in database.  For alignment only. */
00507         struct bu_list          eu_hd2; /**< @brief heads l2 list of edgeuses on this line */
00508         point_t                 e_pt;   /**< @brief parametric equation of the line */
00509         vect_t                  e_dir;
00510         long                    index;  /**< @brief struct # in this model */
00511 };
00512 
00513 /*
00514  *  The ctl_points on this curve are (u,v) values on the face's surface.
00515  *  As a storage and performance efficiency measure, if order <= 0,
00516  *  then the cnurb is a straight line segment in parameter space,
00517  *  and the k.knots and ctl_points pointers will be NULL.
00518  *  In this case, the vertexuse_a_cnurb's at both ends of the edgeuse define
00519  *  the path through parameter space.
00520  */
00521 struct edge_g_cnurb {
00522         struct bu_list          l;      /**< @brief NOTICE:  l.forw & l.back *not* stored in database.  For LIBNURB internal use only. */
00523         struct bu_list          eu_hd2; /**< @brief heads l2 list of edgeuses on this curve */
00524         int                     order;  /**< @brief Curve Order */
00525         struct knot_vector      k;      /**< @brief curve knot vector */
00526         /* curve control polygon */
00527         int                     c_size; /**< @brief number of ctl points */
00528         int                     pt_type;/**< @brief curve point type */
00529         fastf_t                 *ctl_points; /**< @brief array [c_size] */
00530         long                    index;  /**< @brief struct # in this model */
00531 };
00532 
00533 struct edgeuse {
00534         struct bu_list          l;      /**< @brief cw/ccw edges in loop or wire edges in shell */
00535         struct bu_list          l2;     /**< @brief member of edge_g's eu_hd2 list */
00536         union {
00537                 struct loopuse  *lu_p;
00538                 struct shell    *s_p;
00539                 long            *magic_p; /**< @brief for those times when we're not sure */
00540         } up;
00541         struct edgeuse          *eumate_p;  /**< @brief eu on other face or other end of wire*/
00542         struct edgeuse          *radial_p;  /**< @brief eu on radially adj. fu (null if wire)*/
00543         struct edge             *e_p;       /**< @brief edge definition and attributes */
00544         int                     orientation;/**< @brief compared to geom (null if wire) */
00545         struct vertexuse        *vu_p;      /**< @brief first vu of eu in this orient */
00546         union {
00547                 long                *magic_p;
00548                 struct edge_g_lseg  *lseg_p;
00549                 struct edge_g_cnurb *cnurb_p;
00550         } g;                            /**< @brief geometry */
00551         /* (u,v,w) param[] of vu is found in vu_p->vua_p->param */
00552         long                    index;  /**< @brief struct # in this model */
00553 };
00554 
00555 /**
00556  *                      V E R T E X
00557  *
00558  *  The vertex and vertexuse structures are connected in a way different
00559  *  from the superior kinds of topology elements.
00560  *  The vertex structure heads a linked list that all vertexuse's
00561  *  that use the vertex are linked onto.
00562  */
00563 struct vertex {
00564         long                    magic;
00565         struct bu_list          vu_hd;  /**< @brief heads list of vu's of this vertex */
00566         struct vertex_g         *vg_p;  /**< @brief geometry */
00567         long                    index;  /**< @brief struct # in this model */
00568 };
00569 
00570 struct vertex_g {
00571         long                    magic;
00572         point_t                 coord;  /**< @brief coordinates of vertex in space */
00573         long                    index;  /**< @brief struct # in this model */
00574 };
00575 
00576 struct vertexuse {
00577         struct bu_list          l;      /**< @brief list of all vu's on a vertex */
00578         union {
00579                 struct shell    *s_p;   /**< @brief no fu's or eu's on shell */
00580                 struct loopuse  *lu_p;  /**< @brief loopuse contains single vertex */
00581                 struct edgeuse  *eu_p;  /**< @brief eu causing this vu */
00582                 long            *magic_p; /**< @brief for those times when we're not sure */
00583         } up;
00584         struct vertex           *v_p;   /**< @brief vertex definition and attributes */
00585         union {
00586                 long                            *magic_p;
00587                 struct vertexuse_a_plane        *plane_p;
00588                 struct vertexuse_a_cnurb        *cnurb_p;
00589         } a;                            /**< @brief Attributes */
00590         long                    index;  /**< @brief struct # in this model */
00591 };
00592 
00593 struct vertexuse_a_plane {
00594         long                    magic;
00595         vect_t                  N;      /**< @brief (opt) surface Normal at vertexuse */
00596         long                    index;  /**< @brief struct # in this model */
00597 };
00598 
00599 struct vertexuse_a_cnurb {
00600         long                    magic;
00601         fastf_t                 param[3]; /**< @brief (u,v,w) of vu on eu's cnurb */
00602         long                    index;  /**< @brief struct # in this model */
00603 };
00604 
00605 /**
00606  * storage allocation and de-allocation support
00607  *  Primarily used by nmg_mk.c
00608  */
00609 
00610 #define NMG_GETSTRUCT(p,str)    BU_GETSTRUCT(p,str)
00611 
00612 
00613 #if __STDC__ && !defined(alliant) && !defined(apollo)
00614 # define NMG_FREESTRUCT(ptr, str) \
00615         { bzero((char *)(ptr), sizeof(struct str)); \
00616           bu_free((char *)(ptr), "freestruct " #str); }
00617 #else
00618 # define NMG_FREESTRUCT(ptr, str) \
00619         { bzero((char *)(ptr), sizeof(struct str)); \
00620           bu_free((char *)(ptr), "freestruct str"); }
00621 #endif
00622 
00623 
00624 /*
00625  *  Macros to create and destroy storage for the NMG data structures.
00626  *  Since nmg_mk.c and g_nmg.c are the only source file which should perform
00627  *  these most fundamental operations, the macros do not belong in nmg.h
00628  *  In particular, application code should NEVER do these things.
00629  *  Any need to do so should be handled by extending nmg_mk.c
00630  */
00631 #define NMG_INCR_INDEX(_p,_m)   \
00632         NMG_CK_MODEL(_m); (_p)->index = ((_m)->maxindex)++
00633 
00634 #define GET_REGION(p,m)     {NMG_GETSTRUCT(p, nmgregion); NMG_INCR_INDEX(p,m);}
00635 #define GET_REGION_A(p,m)   {NMG_GETSTRUCT(p, nmgregion_a); NMG_INCR_INDEX(p,m);}
00636 #define GET_SHELL(p,m)      {NMG_GETSTRUCT(p, shell); NMG_INCR_INDEX(p,m);}
00637 #define GET_SHELL_A(p,m)    {NMG_GETSTRUCT(p, shell_a); NMG_INCR_INDEX(p,m);}
00638 #define GET_FACE(p,m)       {NMG_GETSTRUCT(p, face); NMG_INCR_INDEX(p,m);}
00639 #define GET_FACE_G_PLANE(p,m) {NMG_GETSTRUCT(p, face_g_plane); NMG_INCR_INDEX(p,m);}
00640 #define GET_FACE_G_SNURB(p,m) {NMG_GETSTRUCT(p, face_g_snurb); NMG_INCR_INDEX(p,m);}
00641 #define GET_FACEUSE(p,m)    {NMG_GETSTRUCT(p, faceuse); NMG_INCR_INDEX(p,m);}
00642 #define GET_LOOP(p,m)       {NMG_GETSTRUCT(p, loop); NMG_INCR_INDEX(p,m);}
00643 #define GET_LOOP_G(p,m)     {NMG_GETSTRUCT(p, loop_g); NMG_INCR_INDEX(p,m);}
00644 #define GET_LOOPUSE(p,m)    {NMG_GETSTRUCT(p, loopuse); NMG_INCR_INDEX(p,m);}
00645 #define GET_EDGE(p,m)       {NMG_GETSTRUCT(p, edge); NMG_INCR_INDEX(p,m);}
00646 #define GET_EDGE_G_LSEG(p,m)  {NMG_GETSTRUCT(p, edge_g_lseg); NMG_INCR_INDEX(p,m);}
00647 #define GET_EDGE_G_CNURB(p,m) {NMG_GETSTRUCT(p, edge_g_cnurb); NMG_INCR_INDEX(p,m);}
00648 #define GET_EDGEUSE(p,m)    {NMG_GETSTRUCT(p, edgeuse); NMG_INCR_INDEX(p,m);}
00649 #define GET_VERTEX(p,m)     {NMG_GETSTRUCT(p, vertex); NMG_INCR_INDEX(p,m);}
00650 #define GET_VERTEX_G(p,m)   {NMG_GETSTRUCT(p, vertex_g); NMG_INCR_INDEX(p,m);}
00651 #define GET_VERTEXUSE(p,m)  {NMG_GETSTRUCT(p, vertexuse); NMG_INCR_INDEX(p,m);}
00652 #define GET_VERTEXUSE_A_PLANE(p,m) {NMG_GETSTRUCT(p, vertexuse_a_plane); NMG_INCR_INDEX(p,m);}
00653 #define GET_VERTEXUSE_A_CNURB(p,m) {NMG_GETSTRUCT(p, vertexuse_a_cnurb); NMG_INCR_INDEX(p,m);}
00654 
00655 #define FREE_MODEL(p)       NMG_FREESTRUCT(p, model)
00656 #define FREE_REGION(p)      NMG_FREESTRUCT(p, nmgregion)
00657 #define FREE_REGION_A(p)    NMG_FREESTRUCT(p, nmgregion_a)
00658 #define FREE_SHELL(p)       NMG_FREESTRUCT(p, shell)
00659 #define FREE_SHELL_A(p)     NMG_FREESTRUCT(p, shell_a)
00660 #define FREE_FACE(p)        NMG_FREESTRUCT(p, face)
00661 #define FREE_FACE_G_PLANE(p) NMG_FREESTRUCT(p, face_g_plane)
00662 #define FREE_FACE_G_SNURB(p) NMG_FREESTRUCT(p, face_g_snurb)
00663 #define FREE_FACEUSE(p)     NMG_FREESTRUCT(p, faceuse)
00664 #define FREE_LOOP(p)        NMG_FREESTRUCT(p, loop)
00665 #define FREE_LOOP_G(p)      NMG_FREESTRUCT(p, loop_g)
00666 #define FREE_LOOPUSE(p)     NMG_FREESTRUCT(p, loopuse)
00667 #define FREE_LOOPUSE_A(p)   NMG_FREESTRUCT(p, loopuse_a)
00668 #define FREE_EDGE(p)        NMG_FREESTRUCT(p, edge)
00669 #define FREE_EDGE_G_LSEG(p)  NMG_FREESTRUCT(p, edge_g_lseg)
00670 #define FREE_EDGE_G_CNURB(p) NMG_FREESTRUCT(p, edge_g_cnurb)
00671 #define FREE_EDGEUSE(p)     NMG_FREESTRUCT(p, edgeuse)
00672 #define FREE_VERTEX(p)      NMG_FREESTRUCT(p, vertex)
00673 #define FREE_VERTEX_G(p)    NMG_FREESTRUCT(p, vertex_g)
00674 #define FREE_VERTEXUSE(p)   NMG_FREESTRUCT(p, vertexuse)
00675 #define FREE_VERTEXUSE_A_PLANE(p) NMG_FREESTRUCT(p, vertexuse_a_plane)
00676 #define FREE_VERTEXUSE_A_CNURB(p) NMG_FREESTRUCT(p, vertexuse_a_cnurb)
00677 
00678 /** Do two edgeuses share the same two vertices? If yes, eu's should be joined. */
00679 #define NMG_ARE_EUS_ADJACENT(_eu1,_eu2) (  \
00680         ( (_eu1)->vu_p->v_p == (_eu2)->vu_p->v_p &&   \
00681           (_eu1)->eumate_p->vu_p->v_p == (_eu2)->eumate_p->vu_p->v_p )  ||  \
00682         ( (_eu1)->vu_p->v_p == (_eu2)->eumate_p->vu_p->v_p &&  \
00683           (_eu1)->eumate_p->vu_p->v_p == (_eu2)->vu_p->v_p ) )
00684 
00685 /** Compat: Used in nmg_misc.c and nmg_mod.c */
00686 #define EDGESADJ(_e1, _e2) NMG_ARE_EUS_ADJACENT(_e1,_e2)
00687 
00688 /** Print a plane equation. */
00689 #define PLPRINT(_s, _pl) bu_log("%s %gx + %gy + %gz = %g\n", (_s), \
00690         (_pl)[0], (_pl)[1], (_pl)[2], (_pl)[3])
00691 
00692 
00693 /** values for the "allhits" argument to mg_class_pt_fu_except() */
00694 #define NMG_FPI_FIRST   0       /**< @brief return after finding first touch */
00695 #define NMG_FPI_PERGEOM 1       /**< @brief find all touches,
00696                                  *  call user funcs once for each
00697                                  * geometry element touched
00698                                  */
00699 #define NMG_FPI_PERUSE  2       /**< @brief find all touches,
00700                                  *  call user funcs once for each
00701                                  * use of geom elements touched
00702                                  */
00703 
00704 
00705 struct nmg_boolstruct {
00706         struct bu_ptbl  ilist;          /**< @brief vertexuses on intersection line */
00707         fastf_t         tol;
00708         point_t         pt;             /**< @brief line of intersection */
00709         vect_t          dir;
00710         int             coplanar;
00711         char            *vertlist;
00712         int             vlsize;
00713         struct model    *model;
00714 };
00715 
00716 #define PREEXIST 1
00717 #define NEWEXIST 2
00718 
00719 
00720 #define VU_PREEXISTS(_bs, _vu) { chkidxlist((_bs), (_vu)); \
00721         (_bs)->vertlist[(_vu)->index] = PREEXIST; }
00722 
00723 #define VU_NEW(_bs, _vu) { chkidxlist((_bs), (_vu)); \
00724         (_bs)->vertlist[(_vu)->index] = NEWEXIST; }
00725 
00726 
00727 struct nmg_struct_counts {
00728         /* Actual structure counts (Xuse, then X) */
00729         long    model;
00730         long    region;
00731         long    region_a;
00732         long    shell;
00733         long    shell_a;
00734         long    faceuse;
00735         long    face;
00736         long    face_g_plane;
00737         long    face_g_snurb;
00738         long    loopuse;
00739         long    loop;
00740         long    loop_g;
00741         long    edgeuse;
00742         long    edge;
00743         long    edge_g_lseg;
00744         long    edge_g_cnurb;
00745         long    vertexuse;
00746         long    vertexuse_a_plane;
00747         long    vertexuse_a_cnurb;
00748         long    vertex;
00749         long    vertex_g;
00750         /* Abstractions */
00751         long    max_structs;
00752         long    face_loops;
00753         long    face_edges;
00754         long    face_lone_verts;
00755         long    wire_loops;
00756         long    wire_loop_edges;
00757         long    wire_edges;
00758         long    wire_lone_verts;
00759         long    shells_of_lone_vert;
00760 };
00761 
00762 /*
00763  *  For use with tables subscripted by NMG structure "index" values,
00764  *  traditional test and set macros.
00765  *  A value of zero indicates unset, a value of one indicates set.
00766  *  test-and-set returns TRUE if value was unset;  in the process,
00767  *  value has become set.  This is often used to detect the first
00768  *  time an item is used, so an alternative name is given, for clarity.
00769  *  Note that the somewhat simpler auto-increment form
00770  *      ( (tab)[(p)->index]++ == 0 )
00771  *  is not used, to avoid the possibility of integer overflow from
00772  *  repeated test-and-set operations on one item.
00773  */
00774 #define NMG_INDEX_VALUE(_tab,_index)    ((_tab)[_index])
00775 #define NMG_INDEX_TEST(_tab,_p)         ( (_tab)[(_p)->index] )
00776 #define NMG_INDEX_SET(_tab,_p)          {(_tab)[(_p)->index] = 1;}
00777 #define NMG_INDEX_CLEAR(_tab,_p)        {(_tab)[(_p)->index] = 0;}
00778 #define NMG_INDEX_TEST_AND_SET(_tab,_p) \
00779         ( (_tab)[(_p)->index] == 0 ? ((_tab)[(_p)->index] = 1) : 0 )
00780 #define NMG_INDEX_IS_SET(_tab,_p)       NMG_INDEX_TEST(_tab,_p)
00781 #define NMG_INDEX_FIRST_TIME(_tab,_p)   NMG_INDEX_TEST_AND_SET(_tab,_p)
00782 #define NMG_INDEX_ASSIGN(_tab,_p,_val)  {(_tab)[(_p)->index] = _val;}
00783 #define NMG_INDEX_GET(_tab,_p)          ((_tab)[(_p)->index])
00784 #define NMG_INDEX_GETP(_ty,_tab,_p)     ((struct _ty *)((_tab)[(_p)->index]))
00785 #define NMG_INDEX_OR(_tab,_p,_val)      {(_tab)[(_p)->index] |= _val;}
00786 #define NMG_INDEX_AND(_tab,_p,_val)     {(_tab)[(_p)->index] &= _val;}
00787 #define NMG_INDEX_RETURN_IF_SET_ELSE_SET(_tab,_index)   \
00788         { if( (_tab)[_index] )  return; \
00789           else (_tab)[_index] = 1; }
00790 
00791 /* flags for manifold-ness */
00792 #define NMG_3MANIFOLD   16
00793 #define NMG_2MANIFOLD   4
00794 #define NMG_1MANIFOLD   2
00795 #define NMG_0MANIFOLD   1
00796 #if 0
00797 # define NMG_DANGLING   8 /* NMG_2MANIFOLD + 4th bit for special cond */
00798 #endif
00799 
00800 #define NMG_SET_MANIFOLD(_t,_p,_v) NMG_INDEX_OR(_t, _p, _v)
00801 #define NMG_MANIFOLDS(_t, _p)      NMG_INDEX_VALUE(_t, (_p)->index)
00802 #define NMG_CP_MANIFOLD(_t, _p, _q) (_t)[(_p)->index] = (_t)[(_q)->index]
00803 
00804 /*
00805  *  Bit-parameters for nmg_lu_to_vlist() poly_markers code.
00806  */
00807 #define NMG_VLIST_STYLE_VECTOR                  0
00808 #define NMG_VLIST_STYLE_POLYGON                 1
00809 #define NMG_VLIST_STYLE_VISUALIZE_NORMALS       2
00810 #define NMG_VLIST_STYLE_USE_VU_NORMALS          4
00811 #define NMG_VLIST_STYLE_NO_SURFACES             8
00812 
00813 /**
00814  *  Function table, for use with nmg_visit()
00815  *  Indended to have same generally the organization as nmg_struct_counts.
00816  *  The handler's args are long* to allow generic handlers to be written,
00817  *  in which case the magic number at long* specifies the object type.
00818  *
00819  *  The "vis_" prefix means the handler is visited only once.
00820  *  The "bef_" and "aft_" prefixes are called (respectively) before
00821  *  and after recursing into subsidiary structures.
00822  *  The 3rd arg is 0 for a "bef_" call, and 1 for an "aft_" call,
00823  *  to allow generic handlers to be written, if desired.
00824  */
00825 struct nmg_visit_handlers {
00826         void    (*bef_model) NMG_ARGS((long *, genptr_t, int));
00827         void    (*aft_model) NMG_ARGS((long *, genptr_t, int));
00828 
00829         void    (*bef_region) NMG_ARGS((long *, genptr_t, int));
00830         void    (*aft_region) NMG_ARGS((long *, genptr_t, int));
00831 
00832         void    (*vis_region_a) NMG_ARGS((long *, genptr_t, int));
00833 
00834         void    (*bef_shell) NMG_ARGS((long *, genptr_t, int));
00835         void    (*aft_shell) NMG_ARGS((long *, genptr_t, int));
00836 
00837         void    (*vis_shell_a) NMG_ARGS((long *, genptr_t, int));
00838 
00839         void    (*bef_faceuse) NMG_ARGS((long *, genptr_t, int));
00840         void    (*aft_faceuse) NMG_ARGS((long *, genptr_t, int));
00841 
00842         void    (*vis_face) NMG_ARGS((long *, genptr_t, int));
00843         void    (*vis_face_g) NMG_ARGS((long *, genptr_t, int));
00844 
00845         void    (*bef_loopuse) NMG_ARGS((long *, genptr_t, int));
00846         void    (*aft_loopuse) NMG_ARGS((long *, genptr_t, int));
00847 
00848         void    (*vis_loop) NMG_ARGS((long *, genptr_t, int));
00849         void    (*vis_loop_g) NMG_ARGS((long *, genptr_t, int));
00850 
00851         void    (*bef_edgeuse) NMG_ARGS((long *, genptr_t, int));
00852         void    (*aft_edgeuse) NMG_ARGS((long *, genptr_t, int));
00853 
00854         void    (*vis_edge) NMG_ARGS((long *, genptr_t, int));
00855         void    (*vis_edge_g) NMG_ARGS((long *, genptr_t, int));
00856 
00857         void    (*bef_vertexuse) NMG_ARGS((long *, genptr_t, int));
00858         void    (*aft_vertexuse) NMG_ARGS((long *, genptr_t, int));
00859 
00860         void    (*vis_vertexuse_a) NMG_ARGS((long *, genptr_t, int));
00861         void    (*vis_vertex) NMG_ARGS((long *, genptr_t, int));
00862         void    (*vis_vertex_g) NMG_ARGS((long *, genptr_t, int));
00863 };
00864 
00865 #endif
00866 /*@}*/
00867 /*
00868  * Local Variables:
00869  * mode: C
00870  * tab-width: 8
00871  * c-basic-offset: 4
00872  * indent-tabs-mode: t
00873  * End:
00874  * ex: shiftwidth=4 tabstop=8
00875  */
00876 

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