00001 #ifndef MXSTDMODEL_INCLUDED 00002 #define MXSTDMODEL_INCLUDED 00003 00004 /************************************************************************ 00005 00006 MxModel 00007 00008 Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. 00009 00010 $Id: lod__model_8h-source.html,v 1.4 2008-02-21 21:41:00 stage Exp $ 00011 00012 ************************************************************************/ 00013 00014 #include "mxtype.h" 00015 00016 00017 /* 00018 * some useful definitions for the model type 00019 */ 00020 #define MX_UNBOUND 0x0 00021 #define MX_PERFACE 0x1 00022 #define MX_PERVERTEX 0x2 00023 #define MX_MAX_BINDING 0x2 00024 00025 #define MX_NORMAL_MASK 0x3 00026 #define MX_COLOR_MASK (0x3<<2) 00027 #define MX_TEXTURE_MASK (0x3<<4) 00028 #define MX_ALL_MASK (MX_NORMAL_MASK|MX_COLOR_MASK|MX_TEXTURE_MASK) 00029 00030 00031 00032 00033 typedef struct vertex_data_TAG 00034 { 00035 unsigned char mark, tag; /* Internal tag bits*/ 00036 unsigned char user_mark, user_tag; /* External tag bits*/ 00037 00038 } vertex_data; 00039 00040 00041 typedef struct face_data_TAG 00042 { 00043 unsigned char mark, tag; /* Internal tag bits*/ 00044 unsigned char user_mark, user_tag; /* External tag bits*/ 00045 00046 } face_data; 00047 00048 00049 typedef struct MxPairContraction_TAG 00050 { 00051 MxVertexID v1, v2; 00052 double dv1[3], dv2[3]; /* dv2 is not really necessary*/ 00053 00054 Block delta_faces; /* holds type int */ 00055 Block dead_faces; /* holds type int */ 00056 00057 } MxPairContraction; 00058 00059 extern void mxpaircontraction_init( MxPairContraction *mpc ); 00060 extern void mxpaircontraction_cleanup( MxPairContraction *mpc ); 00061 00062 /* inline int get_delta_faces( MxPairContraction *mpc, int i ) { return *((int *) getb (&(mpc->delta_faces), i ) ); } */ 00063 /* inline int get_dead_faces( MxPairContraction *mpc, int i ) { return *((int *) getb (&(mpc->dead_faces), i ) ); } */ 00064 #define get_delta_faces(mpc,i) ( *((int *) getb (&((mpc)->delta_faces), (i) ) ) ) 00065 #define get_dead_faces(mpc,i) ( *((int *) getb (&((mpc)->dead_faces), (i) ) ) ) 00066 00067 00068 typedef MxPairContraction MxPairExpansion; 00069 00070 /* Masks for internal tag bits*/ 00071 #define MX_VALID_FLAG 0x01 00072 #define MX_PROXY_FLAG 0x02 00073 #define MX_TOUCHED_FLAG 0x04 00074 00075 typedef struct MxModel_TAG 00076 { 00077 unsigned char cbinding, nbinding, tbinding; 00078 unsigned int flags; 00079 00080 /* all mapping lists hold type int */ 00081 Block face_map1; /* maps original polygons to this model's original triangles */ 00082 Block face_map2; /* maps this model's original triangles to output triangles */ 00083 Block vertex_map; /* maps original vertices to output vertices */ 00084 00085 /* Required blocks*/ 00086 Block vertices; /* stores type MxVertex */ 00087 Block faces; /* stores type MxFace */ 00088 /* Optional blocks*/ 00089 Block *normals; /* stores type MxNormal */ 00090 Block *colors; /* stores type MxColor */ 00091 Block *tcoords; /* stores type MxTexCoord */ 00092 00093 int binding_mask; 00094 Block v_data; /* holds type vertex_data */ 00095 Block f_data; /* holds type face_data */ 00096 Block face_links; 00097 00098 } MxModel; 00099 00100 extern void mxmodel_init( MxModel *m, int nvert, int nface); 00101 extern void mxmodel_cleanup( MxModel *m ); 00102 00103 00104 /* 00105 * Simple access routines 00106 */ 00107 /* inline MxVertex *model_vertex( MxModel *m, int i ) { return (MxVertex *) getb ( &(m->vertices), i ); } */ 00108 /* inline MxFace *model_face( MxModel *m, int i ) { return (MxFace *) getb ( &(m->faces), i ); } */ 00109 /* inline MxVertex *model_corner( MxModel *m, MxFaceID f, short i) { return model_vertex( m, model_face(m, f)->v[i]); } */ 00110 /* inline MxNormal *model_normal( MxModel *m, int i ) { return (MxNormal *) getb ( m->normals, i ); } */ 00111 /* inline MxColor *model_color( MxModel *m, int i ) { return (MxColor *) getb ( m->colors, i ); } */ 00112 /* inline MxTexCoord *model_texcoord( MxModel *m, int i ) { return (MxTexCoord *) getb ( m->tcoords, i ); } */ 00113 /* inline int model_vertex_count(MxModel *m) { return lengthb( &(m->vertices) ); } */ 00114 /* inline int model_face_count(MxModel *m) { return lengthb( &(m->faces) ); } */ 00115 #define model_vertex(m,i) ( (MxVertex *) getb ( &((m)->vertices), (i) ) ) 00116 #define model_face(m,i) ( (MxFace *) getb ( &((m)->faces), (i) ) ) 00117 #define model_corner(m,f,i) ( model_vertex( (m), model_face((m), (f))->v[(i)]) ) 00118 #define model_normal(m,i) ( (MxNormal *) getb ( (m)->normals, (i) ) ) 00119 #define model_color(m,i) ( (MxColor *) getb ( m->colors, i ) ) 00120 #define model_texcoord(m,i) ( (MxTexCoord *) getb ( m->tcoords, i ) ) 00121 #define model_vertex_count(m) ( lengthb( &((m)->vertices) ) ) 00122 #define model_face_count(m) ( lengthb( &((m)->faces) ) ) 00123 #define model_vertex_map_entry(m,i) ( (int) getb ( &((m)->vertex_map), (i) ) ) 00124 extern int model_valid_face_count( MxModel *m ); 00125 extern int model_valid_vertex_count( MxModel *m ); 00126 00127 00128 /* 00129 * Accessors for internal tag and mark bits 00130 */ 00131 /* inline vertex_data *get_v_data( MxModel *m, int i ) { return (vertex_data *) getb ( &(m->v_data), i ); }; */ 00132 /* inline int v_check_tag( MxModel *m, MxVertexID i, int tag ) { return get_v_data( m,i )->tag & tag; } */ 00133 /* inline void v_set_tag( MxModel *m, MxVertexID i, int tag ) { get_v_data( m, i )->tag |= tag; } */ 00134 /* inline void v_unset_tag( MxModel *m, MxVertexID i, int tag ) { get_v_data( m, i )->tag &= ~tag; } */ 00135 /* inline unsigned char get_vmark( MxModel *m, MxVertexID i ) { return get_v_data( m, i )->mark; } */ 00136 /* inline void vmarkc( MxModel *m, MxVertexID i, unsigned char c ) { get_v_data( m, i )->mark = c; } */ 00137 #define get_v_data(m,i) ( (vertex_data *) getb ( &((m)->v_data), (i) ) ) 00138 #define v_check_tag(m,i,t) ( get_v_data( (m), (i) )->tag & (t) ) 00139 #define v_set_tag(m,i,t) ( get_v_data( (m), (i) )->tag |= (t) ) 00140 #define v_unset_tag(m,i,t) ( get_v_data( (m), (i) )->tag &= ~(t) ) 00141 #define get_vmark(m,i) ( get_v_data( (m), (i) )->mark ) 00142 #define vmarkc(m,i,c) ( get_v_data( (m), (i) )->mark = (c) ) 00143 00144 /* inline face_data *get_f_data( MxModel *m, int i ) { return (face_data *) getb ( &(m->f_data), i ); }; */ 00145 /* inline int f_check_tag( MxModel *m, MxFaceID i, int tag ) { return get_f_data( m, i )->tag & tag; } */ 00146 /* inline void f_set_tag( MxModel *m, MxFaceID i, int tag ) { get_f_data( m, i )->tag |= tag; } */ 00147 /* inline void f_unset_tag( MxModel *m, MxFaceID i, int tag ) { get_f_data( m, i )->tag &= ~tag; } */ 00148 /* inline unsigned char get_fmark( MxModel *m, MxFaceID i ) { return get_f_data( m, i )->mark; } */ 00149 /* inline void fmark( MxModel *m, MxFaceID i, unsigned char c ) { get_f_data( m, i )->mark = c; } */ 00150 #define get_f_data(m,i) ( (face_data *) getb ( &((m)->f_data), (i) ) ) 00151 #define f_check_tag(m,i,t) ( get_f_data( (m), (i) )->tag & (t) ) 00152 #define f_set_tag(m,i,t) ( get_f_data( (m), (i) )->tag |= (t) ) 00153 #define f_unset_tag(m,i,t) ( get_f_data( (m), (i) )->tag &= ~(t) ) 00154 #define get_fmark(m,i) ( get_f_data( (m), (i) )->mark ) 00155 #define fmark(m,i,c) ( get_f_data( (m), (i) )->mark = (c) ) 00156 00157 00158 /* 00159 * exported access for tagging and marking 00160 */ 00161 /* inline int vertex_is_valid( MxModel *m, MxVertexID i ) { return v_check_tag(m,i,MX_VALID_FLAG); } */ 00162 /* inline void vertex_mark_valid( MxModel *m, MxVertexID i ) { v_set_tag(m,i,MX_VALID_FLAG); } */ 00163 /* inline void vertex_mark_invalid( MxModel *m, MxVertexID i ) { v_unset_tag(m,i,MX_VALID_FLAG); } */ 00164 /* inline int face_is_valid( MxModel *m, MxFaceID i ) { return f_check_tag(m,i,MX_VALID_FLAG);} */ 00165 /* inline void face_mark_valid( MxModel *m, MxFaceID i ) { f_set_tag(m,i,MX_VALID_FLAG); } */ 00166 /* inline void face_mark_invalid( MxModel *m, MxFaceID i ) { f_unset_tag(m,i,MX_VALID_FLAG); } */ 00167 #define vertex_is_valid(m,i) ( v_check_tag((m),(i),MX_VALID_FLAG) ) 00168 #define vertex_mark_valid(m,i) ( v_set_tag((m),(i),MX_VALID_FLAG) ) 00169 #define vertex_mark_invalid(m,i) ( v_unset_tag((m),(i),MX_VALID_FLAG) ) 00170 #define face_is_valid(m,i) ( f_check_tag((m),(i),MX_VALID_FLAG) ) 00171 #define face_mark_valid(m,i) ( f_set_tag((m),(i),MX_VALID_FLAG) ) 00172 #define face_mark_invalid(m,i) ( f_unset_tag((m),(i),MX_VALID_FLAG) ) 00173 00174 /* 00175 * Accessors for external tag and mark bits 00176 */ 00177 /* inline int vertex_check_tag( MxModel *m, MxVertexID i, int tag ) { return get_v_data( m, i )->user_tag & tag; } */ 00178 /* inline void vertex_set_tag( MxModel *m, MxVertexID i, int tag ) { get_v_data( m, i )->user_tag |= tag; } */ 00179 /* inline void vertex_unset_tag( MxModel *m, MxVertexID i, int tag ) { get_v_data( m, i )->user_tag &= ~tag;} */ 00180 /* inline unsigned char get_vertex_mark( MxModel *m, MxVertexID i ) { return get_v_data( m, i )->user_mark; } */ 00181 /* inline void vertex_mark( MxModel *m, MxVertexID i, unsigned char c ) { get_v_data( m, i )->user_mark=c; } */ 00182 #define vertex_check_tag(m,i,t) ( get_v_data( (m), (i) )->user_tag & (t) ) 00183 #define vertex_set_tag(m,i,t) ( get_v_data( (m), (i) )->user_tag |= (t) ) 00184 #define vertex_unset_tag(m,i,t) ( get_v_data( (m), (i) )->user_tag &= ~(t) ) 00185 #define get_vertex_mark(m,i) ( get_v_data( (m), (i) )->user_mark ) 00186 #define vertex_mark(m,i,c ) ( get_v_data( (m), (i) )->user_mark=(c) ) 00187 00188 /* inline int face_check_tag( MxModel *m, MxFaceID i, int tag ) { return get_f_data( m, i )->user_tag & tag; } */ 00189 /* inline void face_set_tag( MxModel *m, MxFaceID i, int tag ) { get_f_data( m, i )->user_tag |= tag; } */ 00190 /* inline void face_unset_tag( MxModel *m, MxFaceID i, int tag ) { get_f_data( m, i )->user_tag &= ~tag;} */ 00191 /* inline unsigned char face_mark( MxModel *m, MxFaceID i ) { return get_f_data( m, i )->user_mark; } */ 00192 /* inline void face_mark( MxModel *m, MxFaceID i, unsigned char c ) { get_f_data( m, i )->user_mark = c; } */ 00193 #define face_check_tag(m,i,t) ( get_f_data( (m), (i) )->user_tag & (t) ) 00194 #define face_set_tag(m,i,t) ( get_f_data( (m), (i) )->user_tag |= (t) ) 00195 #define face_unset_tag(m,i,t) ( get_f_data( (m), i )->user_tag &= ~(t) ) 00196 #define get_face_mark(m,i) ( get_f_data( (m), (i) )->user_mark ) 00197 #define face_mark(m,i,c) ( get_f_data( (m), (i) )->user_mark = (c) ) 00198 00199 00200 /* 00201 * Vertex management 00202 */ 00203 00204 extern MxVertexID add_vertex ( MxModel *m, double, double, double); 00205 extern MxFaceID add_face ( MxModel *m, int, int, int); 00206 extern int add_color ( MxModel *m, double, double, double); 00207 extern int add_normal ( MxModel *m, double, double, double); 00208 extern int add_texcoord ( MxModel *m, double, double); 00209 extern void remove_vertex( MxModel *m, MxVertexID v); 00210 extern void free_vertex ( MxModel *m, MxVertexID ); 00211 extern MxFaceID alloc_face ( MxModel *m, MxVertexID, MxVertexID, MxVertexID ); 00212 extern void init_face ( MxModel *m, MxFaceID ); 00213 00214 00215 00216 /* inline int normal_binding(MxModel *m) { return ( m->nbinding & m->binding_mask ); } */ 00217 /* inline int color_binding(MxModel *m) { return ( m->cbinding & (m->binding_mask >> 2) ); } */ 00218 /* inline int texcoord_binding(MxModel *m) { return ( m->tbinding & (m->binding_mask >> 4) ); } */ 00219 #define normal_binding(m) ( ( (m)->nbinding & (m)->binding_mask ) ) 00220 #define color_binding(m) ( ( (m)->cbinding & ((m)->binding_mask >> 2) ) ) 00221 #define texcoord_binding(m) ( ( (m)->tbinding & ((m)->binding_mask >> 4) ) ) 00222 00223 extern const char *binding_name( MxModel *m, int ); 00224 extern int parse_binding( MxModel *m, const char * ); 00225 00226 extern int compute_face_normal ( MxModel *m, MxFaceID, double *, MxBool will_unitize ); 00227 extern double compute_face_area ( MxModel *m, MxFaceID ); 00228 extern double compute_face_perimeter( MxModel *m, MxFaceID, MxBool *edge_flags ); 00229 00230 extern double compute_corner_angle( MxModel *m, MxFaceID, int ); 00231 00232 00233 /* 00234 * Neighborhood collection and management, vertex normal calculations 00235 */ 00236 extern void mark_neighborhood( MxModel *m, MxVertexID, unsigned short ); 00237 extern void collect_unmarked_neighbors( MxModel *m, MxVertexID, MxFaceList * ); 00238 extern void partition_marked_neighbors( MxModel *m, MxVertexID, unsigned short pivot, 00239 MxFaceList *below, MxFaceList *above ); 00240 00241 extern void mark_corners( MxModel *m, MxFaceList *faces, unsigned short mark ); 00242 extern void collect_unmarked_corners(MxModel *m, MxFaceList *faces,MxVertexList *verts ); 00243 00244 extern void collect_edge_neighbors( MxModel *m, MxVertexID, MxVertexID, MxFaceList * ); 00245 extern void collect_vertex_star( MxModel *m, MxVertexID v, MxVertexList *verts ); 00246 00247 /* extern MxFaceList *neighbors( MxModel *m, MxVertexID v ); */ 00248 #define neighbors(m,v) ((MxFaceList *) getpb( &((m)->face_links), (v) )) 00249 00250 extern void compute_vertex_normal( MxModel *m, MxVertexID v, double * ); 00251 00252 /* 00253 * Primitive transformation operations 00254 */ 00255 extern void model_remap_vertex( MxModel *m, MxVertexID from, MxVertexID to ); 00256 extern MxVertexID split_edge( MxModel *m, MxVertexID v1, MxVertexID v2, double x, double y, double z ); 00257 extern MxVertexID split_edge_simple( MxModel *m, MxVertexID v1, MxVertexID v2 ); 00258 00259 extern void flip_edge( MxModel *m, MxVertexID v1, MxVertexID v2 ); 00260 extern void split_face4( MxModel *m, MxFaceID f, MxVertexID *newverts ); 00261 extern void unlink_face( MxModel *m, MxFaceID f); 00262 00263 00264 00265 /* 00266 * Contraction and related operations 00267 */ 00268 extern void compact_vertices( MxModel * ); 00269 extern void remove_degeneracy( MxModel *, MxFaceList * ); 00270 00271 /* Pair contraction interface*/ 00272 extern void compute_pair_contraction( MxModel *, MxVertexID, MxVertexID, MxPairContraction *); 00273 extern void apply_pair_contraction( MxModel *, MxPairContraction *); 00274 extern void apply_pair_expansion( MxModel *, MxPairExpansion *); 00275 extern void pair_contract( MxModel *, MxVertexID v1, MxVertexID v2, 00276 const double *, MxPairContraction *); 00277 00278 00279 /* MXSTDMODEL_INCLUDED*/ 00280 #endif