|
surf.h00001 // 00002 // surf.h 00003 // 00004 // Copyright (C) 1996 Limit Point Systems, Inc. 00005 // 00006 // Author: Curtis Janssen <cljanss@limitpt.com> 00007 // Maintainer: LPS 00008 // 00009 // This file is part of the SC Toolkit. 00010 // 00011 // The SC Toolkit is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Library General Public License as published by 00013 // the Free Software Foundation; either version 2, or (at your option) 00014 // any later version. 00015 // 00016 // The SC Toolkit is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU Library General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Library General Public License 00022 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to 00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 00024 // 00025 // The U.S. Government is granted a limited license as per AL 91-7. 00026 // 00027 00028 #ifndef _math_isosurf_surf_h 00029 #define _math_isosurf_surf_h 00030 00031 #ifdef __GNUC__ 00032 #pragma interface 00033 #endif 00034 00035 #ifdef HAVE_CONFIG_H 00036 #include <scconfig.h> 00037 #endif 00038 00039 #ifdef HAVE_STL 00040 #include <vector> 00041 #endif 00042 00043 #include <util/container/array.h> 00044 #include <math/isosurf/triangle.h> 00045 #include <math/isosurf/volume.h> 00046 #include <util/render/render.h> 00047 00048 namespace sc { 00049 00050 class TriangulatedSurface: public DescribedClass { 00051 protected: 00052 int _verbose; 00053 int _debug; 00054 00055 int _completed_surface; 00056 00057 // sets of objects that make up the surface 00058 AVLSet<Ref<Vertex> > _vertices; 00059 AVLSet<Ref<Edge> > _edges; 00060 AVLSet<Ref<Triangle> > _triangles; 00061 00062 // map objects to an integer index 00063 AVLMap<Ref<Vertex>,int> _vertex_to_index; 00064 AVLMap<Ref<Edge>,int> _edge_to_index; 00065 AVLMap<Ref<Triangle>,int> _triangle_to_index; 00066 00067 // map integer indices to an object 00068 #ifdef HAVE_STL 00069 std::vector<Ref<Vertex> > _index_to_vertex; 00070 std::vector<Ref<Edge> > _index_to_edge; 00071 std::vector<Ref<Triangle> > _index_to_triangle; 00072 #else 00073 Array<Ref<Vertex> > _index_to_vertex; 00074 Array<Ref<Edge> > _index_to_edge; 00075 Array<Ref<Triangle> > _index_to_triangle; 00076 #endif 00077 00078 // mappings between array element numbers 00079 int** _triangle_vertex; 00080 int** _triangle_edge; 00081 int** _edge_vertex; 00082 00083 // values for each of the vertices 00084 int _have_values; 00085 Arraydouble _values; 00086 00087 // what to use to integrate over the surface, by default 00088 Ref<TriangleIntegrator> _integrator; 00089 // other integrators, in terms of time & accuracy: 00090 // _fast_integrator <= _integrator <= _accurate_interator 00091 Ref<TriangleIntegrator> _fast_integrator; 00092 Ref<TriangleIntegrator> _accurate_integrator; 00093 00094 void clear_int_arrays(); 00095 00096 void complete_ref_arrays(); 00097 void complete_int_arrays(); 00098 00099 void recompute_index_maps(); 00100 00101 void add_triangle(const Ref<Triangle>&); 00102 void add_vertex(const Ref<Vertex>&); 00103 void add_edge(const Ref<Edge>&); 00104 00105 // these members must be used to allocate new triangles and edges 00106 // since specializations of TriangulatedSurface might need to 00107 // override these to produce triangles and edges with interpolation 00108 // data. 00109 virtual Triangle* newTriangle(const Ref<Edge>&, 00110 const Ref<Edge>&, 00111 const Ref<Edge>&, 00112 int orientation) const; 00113 virtual Edge* newEdge(const Ref<Vertex>&,const Ref<Vertex>&) const; 00114 00115 // this map of edges to vertices is used to construct the surface 00116 AVLMap<Ref<Vertex>,AVLSet<Ref<Edge> > > _tmp_edges; 00117 public: 00118 TriangulatedSurface(); 00119 TriangulatedSurface(const Ref<KeyVal>&); 00120 virtual ~TriangulatedSurface(); 00121 00122 // control printing 00123 int verbose() const { return _verbose; } 00124 void verbose(int v) { _verbose = v; } 00125 00126 // set up an integrator 00127 void set_integrator(const Ref<TriangleIntegrator>&); 00128 void set_fast_integrator(const Ref<TriangleIntegrator>&); 00129 void set_accurate_integrator(const Ref<TriangleIntegrator>&); 00130 virtual Ref<TriangleIntegrator> integrator(int itri); 00131 virtual Ref<TriangleIntegrator> fast_integrator(int itri); 00132 virtual Ref<TriangleIntegrator> accurate_integrator(int itri); 00133 00134 // construct the surface 00135 void add_triangle(const Ref<Vertex>&, 00136 const Ref<Vertex>&, 00137 const Ref<Vertex>&); 00138 Ref<Edge> find_edge(const Ref<Vertex>&, const Ref<Vertex>&); 00139 virtual void complete_surface(); 00140 00141 // clean up the surface 00142 virtual void remove_short_edges(double cutoff_length = 1.0e-6, 00143 const Ref<Volume> &vol=0, double isoval=0.0); 00144 virtual void remove_slender_triangles( 00145 int remove_slender, double height_cutoff, 00146 int remove_small, double area_cutoff, 00147 const Ref<Volume> &vol=0, double isoval=0.0); 00148 virtual void fix_orientation(); 00149 virtual void clear(); 00150 00151 // get information from the object sets 00152 int nvertex() const { return _vertices.length(); }; 00153 Ref<Vertex> vertex(int i) const { return _index_to_vertex[i]; }; 00154 int vertex_index(const Ref<Vertex> &o) { 00155 AVLMap<Ref<Vertex>,int>::iterator i = _vertex_to_index.find(o); 00156 if (i != _vertex_to_index.end()) return i.data(); 00157 return -1; 00158 } 00159 int nedge() const { return _edges.length(); }; 00160 Ref<Edge> edge(int i) const { return _index_to_edge[i]; }; 00161 int edge_index(const Ref<Edge> &o) { 00162 AVLMap<Ref<Edge>,int>::iterator i = _edge_to_index.find(o); 00163 if (i != _edge_to_index.end()) return i.data(); 00164 return -1; 00165 } 00166 int ntriangle() const { return _triangles.length(); }; 00167 Ref<Triangle> triangle(int i) const { return _index_to_triangle[i]; } 00168 int triangle_index(const Ref<Triangle> &o) { 00169 AVLMap<Ref<Triangle>,int>::iterator i = _triangle_to_index.find(o); 00170 if (i != _triangle_to_index.end()) return i.data(); 00171 return -1; 00172 } 00173 00174 // information from the index mappings 00175 int triangle_vertex(int i,int j) const { return _triangle_vertex[i][j]; }; 00176 int triangle_edge(int i,int j) const { return _triangle_edge[i][j]; }; 00177 int edge_vertex(int i,int j) const { return _edge_vertex[i][j]; }; 00178 00179 // associate values with vertices 00180 //void compute_colors(Volume&); 00181 void compute_values(Ref<Volume>&); 00182 00183 // properties of the surface 00184 virtual double flat_area(); // use flat triangles 00185 virtual double flat_volume(); // use flat triangles 00186 virtual double area(); 00187 virtual double volume(); 00188 00189 // output of the surface 00190 virtual void print(std::ostream&o=ExEnv::out0()) const; 00191 virtual void print_vertices_and_triangles(std::ostream&o=ExEnv::out0()) const; 00192 virtual void print_geomview_format(std::ostream&o=ExEnv::out0()) const; 00193 virtual void render(const Ref<Render> &render); 00194 00195 // print information about the topology 00196 void topology_info(std::ostream&o=ExEnv::out0()); 00197 void topology_info(int nvertex, int nedge, int ntri, std::ostream&o=ExEnv::out0()); 00198 }; 00199 00200 00201 class TriangulatedSurfaceIntegrator { 00202 private: 00203 Ref<TriangulatedSurface> _ts; 00204 int _itri; 00205 int _irs; 00206 double _r; 00207 double _s; 00208 double _weight; 00209 double _surface_element; 00210 Ref<Vertex> _current; 00211 SCVector3 _dA; 00212 Ref<TriangleIntegrator> (TriangulatedSurface::*_integrator)(int itri); 00213 Ref<MessageGrp> _grp; 00214 public: 00215 TriangulatedSurfaceIntegrator(); 00216 // the surface cannot be changed until this is destroyed 00217 TriangulatedSurfaceIntegrator(const Ref<TriangulatedSurface>&); 00218 ~TriangulatedSurfaceIntegrator(); 00219 // Objects initialized by these operators are not automatically 00220 // updated. This must be done with the update member. 00221 // The _grp is not copied. 00222 void operator = (const TriangulatedSurfaceIntegrator&); 00223 TriangulatedSurfaceIntegrator(const TriangulatedSurfaceIntegrator&i) { 00224 operator = (i); 00225 } 00226 // Return the number of integration points. 00227 int n(); 00228 // Assign the surface. Don't do this while iterating. 00229 void set_surface(const Ref<TriangulatedSurface>&); 00230 // returns the number of the vertex in the current triangle 00231 int vertex_number(int i); 00232 inline double r() const { return _r; } 00233 inline double s() const { return _s; } 00234 inline double w() const { return _weight*_surface_element; } 00235 double surface_element() const { return _surface_element; } 00236 double weight() const { return _weight; } 00237 const SCVector3& dA() const { return _dA; } 00238 Ref<Vertex> current(); 00239 // Tests to see if this point is valid, if it is then 00240 // _r, _s, etc are computed and 1 is returned. 00241 int update(); 00242 // This can be used to loop through unique pairs of points. 00243 // The argument should be a TriangulatedSurfaceIntegrator for 00244 // the same surface as this. 00245 int operator < (TriangulatedSurfaceIntegrator&i) { 00246 update(); 00247 return _itri<i._itri?1:(_itri>i._itri?0:(_irs<i._irs?1:0)); 00248 } 00249 // Goes to the next point. Does not update. 00250 void operator++(); 00251 inline void operator++(int) { operator++(); } 00252 // setting TSI = i sets TSI to begin at the triangle i 00253 int operator = (int); 00254 int itri() const { return _itri; } 00255 int irs() const { return _irs; } 00256 // the number of points in the current triangle 00257 int n_in_tri() const { return (_ts.pointer()->*_integrator)(_itri)->n(); } 00258 void distribute(const Ref<MessageGrp> &); 00259 void use_fast_integrator(); 00260 void use_accurate_integrator(); 00261 void use_default_integrator(); 00262 }; 00263 00264 class TriangulatedImplicitSurface: public TriangulatedSurface { 00265 private: 00266 // The surface is defined as an isosurface of the volume vol_. 00267 Ref<Volume> vol_; 00268 double isovalue_; 00269 00270 int fix_orientation_; 00271 int remove_short_edges_; 00272 double short_edge_factor_; 00273 int remove_slender_triangles_; 00274 double slender_triangle_factor_; 00275 int remove_small_triangles_; 00276 double small_triangle_factor_; 00277 double resolution_; 00278 00279 int order_; 00280 00281 int inited_; 00282 public: 00283 TriangulatedImplicitSurface(const Ref<KeyVal>&); 00284 ~TriangulatedImplicitSurface(); 00285 00286 Ref<Volume> volume_object() const { return vol_; } 00287 double isovalue() const { return isovalue_; } 00288 00289 void init(); 00290 int inited() const { return inited_; } 00291 }; 00292 00293 } 00294 00295 #endif 00296 00297 // Local Variables: 00298 // mode: c++ 00299 // c-file-style: "CLJ" 00300 // End: Generated at Fri Jan 10 08:14:10 2003 for MPQC 2.1.3 using the documentation package Doxygen 1.2.14. |