Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

surf.h

00001 // 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 #include <map> 00040 #include <set> 00041 #include <vector> 00042 00043 #include <math/isosurf/triangle.h> 00044 #include <math/isosurf/volume.h> 00045 #include <util/render/render.h> 00046 00047 namespace sc { 00048 00049 template <class C, class I> 00050 inline void 00051 erase_elements_by_value(C &container, I begin, I end) 00052 { 00053 for (I i=begin; i!=end; i++) { 00054 container.erase(*i); 00055 } 00056 } 00057 00058 class TriangulatedSurface: public DescribedClass { 00059 protected: 00060 int _verbose; 00061 int _debug; 00062 00063 int _completed_surface; 00064 00065 // sets of objects that make up the surface 00066 std::set<Ref<Vertex> > _vertices; 00067 std::set<Ref<Edge> > _edges; 00068 std::set<Ref<Triangle> > _triangles; 00069 00070 // map objects to an integer index 00071 std::map<Ref<Vertex>,int> _vertex_to_index; 00072 std::map<Ref<Edge>,int> _edge_to_index; 00073 std::map<Ref<Triangle>,int> _triangle_to_index; 00074 00075 // map integer indices to an object 00076 std::vector<Ref<Vertex> > _index_to_vertex; 00077 std::vector<Ref<Edge> > _index_to_edge; 00078 std::vector<Ref<Triangle> > _index_to_triangle; 00079 00080 // mappings between array element numbers 00081 int** _triangle_vertex; 00082 int** _triangle_edge; 00083 int** _edge_vertex; 00084 00085 // values for each of the vertices 00086 int _have_values; 00087 std::vector<double> _values; 00088 00089 // what to use to integrate over the surface, by default 00090 Ref<TriangleIntegrator> _integrator; 00091 // other integrators, in terms of time & accuracy: 00092 // _fast_integrator <= _integrator <= _accurate_interator 00093 Ref<TriangleIntegrator> _fast_integrator; 00094 Ref<TriangleIntegrator> _accurate_integrator; 00095 00096 void clear_int_arrays(); 00097 00098 void complete_ref_arrays(); 00099 void complete_int_arrays(); 00100 00101 void recompute_index_maps(); 00102 00103 void add_triangle(const Ref<Triangle>&); 00104 void add_vertex(const Ref<Vertex>&); 00105 void add_edge(const Ref<Edge>&); 00106 00107 // these members must be used to allocate new triangles and edges 00108 // since specializations of TriangulatedSurface might need to 00109 // override these to produce triangles and edges with interpolation 00110 // data. 00111 virtual Triangle* newTriangle(const Ref<Edge>&, 00112 const Ref<Edge>&, 00113 const Ref<Edge>&, 00114 int orientation) const; 00115 virtual Edge* newEdge(const Ref<Vertex>&,const Ref<Vertex>&) const; 00116 00117 // this map of edges to vertices is used to construct the surface 00118 std::map<Ref<Vertex>,std::set<Ref<Edge> > > _tmp_edges; 00119 public: 00120 TriangulatedSurface(); 00121 TriangulatedSurface(const Ref<KeyVal>&); 00122 virtual ~TriangulatedSurface(); 00123 00124 // control printing 00125 int verbose() const { return _verbose; } 00126 void verbose(int v) { _verbose = v; } 00127 00128 // set up an integrator 00129 void set_integrator(const Ref<TriangleIntegrator>&); 00130 void set_fast_integrator(const Ref<TriangleIntegrator>&); 00131 void set_accurate_integrator(const Ref<TriangleIntegrator>&); 00132 virtual Ref<TriangleIntegrator> integrator(int itri); 00133 virtual Ref<TriangleIntegrator> fast_integrator(int itri); 00134 virtual Ref<TriangleIntegrator> accurate_integrator(int itri); 00135 00136 // construct the surface 00137 void add_triangle(const Ref<Vertex>&, 00138 const Ref<Vertex>&, 00139 const Ref<Vertex>&); 00140 Ref<Edge> find_edge(const Ref<Vertex>&, const Ref<Vertex>&); 00141 virtual void complete_surface(); 00142 00143 // clean up the surface 00144 virtual void remove_short_edges(double cutoff_length = 1.0e-6, 00145 const Ref<Volume> &vol=0, double isoval=0.0); 00146 virtual void remove_slender_triangles( 00147 int remove_slender, double height_cutoff, 00148 int remove_small, double area_cutoff, 00149 const Ref<Volume> &vol=0, double isoval=0.0); 00150 virtual void fix_orientation(); 00151 virtual void clear(); 00152 00153 // get information from the object sets 00154 int nvertex() const { return _vertices.size(); }; 00155 Ref<Vertex> vertex(int i) const { return _index_to_vertex[i]; }; 00156 int vertex_index(const Ref<Vertex> &o) { 00157 std::map<Ref<Vertex>,int>::iterator i = _vertex_to_index.find(o); 00158 if (i != _vertex_to_index.end()) return i->second; 00159 return -1; 00160 } 00161 int nedge() const { return _edges.size(); }; 00162 Ref<Edge> edge(int i) const { return _index_to_edge[i]; }; 00163 int edge_index(const Ref<Edge> &o) { 00164 std::map<Ref<Edge>,int>::iterator i = _edge_to_index.find(o); 00165 if (i != _edge_to_index.end()) return i->second; 00166 return -1; 00167 } 00168 int ntriangle() const { return _triangles.size(); }; 00169 Ref<Triangle> triangle(int i) const { return _index_to_triangle[i]; } 00170 int triangle_index(const Ref<Triangle> &o) { 00171 std::map<Ref<Triangle>,int>::iterator i = _triangle_to_index.find(o); 00172 if (i != _triangle_to_index.end()) return i->second; 00173 return -1; 00174 } 00175 00176 // information from the index mappings 00177 int triangle_vertex(int i,int j) const { return _triangle_vertex[i][j]; }; 00178 int triangle_edge(int i,int j) const { return _triangle_edge[i][j]; }; 00179 int edge_vertex(int i,int j) const { return _edge_vertex[i][j]; }; 00180 00181 // associate values with vertices 00182 //void compute_colors(Volume&); 00183 void compute_values(Ref<Volume>&); 00184 00185 // properties of the surface 00186 virtual double flat_area(); // use flat triangles 00187 virtual double flat_volume(); // use flat triangles 00188 virtual double area(); 00189 virtual double volume(); 00190 00191 // output of the surface 00192 virtual void print(std::ostream&o=ExEnv::out0()) const; 00193 virtual void print_vertices_and_triangles(std::ostream&o=ExEnv::out0()) const; 00194 virtual void print_geomview_format(std::ostream&o=ExEnv::out0()) const; 00195 virtual void render(const Ref<Render> &render); 00196 00197 // print information about the topology 00198 void topology_info(std::ostream&o=ExEnv::out0()); 00199 void topology_info(int nvertex, int nedge, int ntri, std::ostream&o=ExEnv::out0()); 00200 }; 00201 00202 00203 class TriangulatedSurfaceIntegrator { 00204 private: 00205 Ref<TriangulatedSurface> _ts; 00206 int _itri; 00207 int _irs; 00208 double _r; 00209 double _s; 00210 double _weight; 00211 double _surface_element; 00212 Ref<Vertex> _current; 00213 SCVector3 _dA; 00214 Ref<TriangleIntegrator> (TriangulatedSurface::*_integrator)(int itri); 00215 Ref<MessageGrp> _grp; 00216 public: 00217 TriangulatedSurfaceIntegrator(); 00218 // the surface cannot be changed until this is destroyed 00219 TriangulatedSurfaceIntegrator(const Ref<TriangulatedSurface>&); 00220 ~TriangulatedSurfaceIntegrator(); 00221 // Objects initialized by these operators are not automatically 00222 // updated. This must be done with the update member. 00223 // The _grp is not copied. 00224 void operator = (const TriangulatedSurfaceIntegrator&); 00225 TriangulatedSurfaceIntegrator(const TriangulatedSurfaceIntegrator&i) { 00226 operator = (i); 00227 } 00228 // Return the number of integration points. 00229 int n(); 00230 // Assign the surface. Don't do this while iterating. 00231 void set_surface(const Ref<TriangulatedSurface>&); 00232 // returns the number of the vertex in the current triangle 00233 int vertex_number(int i); 00234 inline double r() const { return _r; } 00235 inline double s() const { return _s; } 00236 inline double w() const { return _weight*_surface_element; } 00237 double surface_element() const { return _surface_element; } 00238 double weight() const { return _weight; } 00239 const SCVector3& dA() const { return _dA; } 00240 Ref<Vertex> current(); 00241 // Tests to see if this point is valid, if it is then 00242 // _r, _s, etc are computed and 1 is returned. 00243 int update(); 00244 // This can be used to loop through unique pairs of points. 00245 // The argument should be a TriangulatedSurfaceIntegrator for 00246 // the same surface as this. 00247 int operator < (TriangulatedSurfaceIntegrator&i) { 00248 update(); 00249 return _itri<i._itri?1:(_itri>i._itri?0:(_irs<i._irs?1:0)); 00250 } 00251 // Goes to the next point. Does not update. 00252 void operator++(); 00253 inline void operator++(int) { operator++(); } 00254 // setting TSI = i sets TSI to begin at the triangle i 00255 int operator = (int); 00256 int itri() const { return _itri; } 00257 int irs() const { return _irs; } 00258 // the number of points in the current triangle 00259 int n_in_tri() const { return (_ts.pointer()->*_integrator)(_itri)->n(); } 00260 void distribute(const Ref<MessageGrp> &); 00261 void use_fast_integrator(); 00262 void use_accurate_integrator(); 00263 void use_default_integrator(); 00264 }; 00265 00266 class TriangulatedImplicitSurface: public TriangulatedSurface { 00267 private: 00268 // The surface is defined as an isosurface of the volume vol_. 00269 Ref<Volume> vol_; 00270 double isovalue_; 00271 00272 int fix_orientation_; 00273 int remove_short_edges_; 00274 double short_edge_factor_; 00275 int remove_slender_triangles_; 00276 double slender_triangle_factor_; 00277 int remove_small_triangles_; 00278 double small_triangle_factor_; 00279 double resolution_; 00280 00281 int order_; 00282 00283 int inited_; 00284 public: 00285 TriangulatedImplicitSurface(const Ref<KeyVal>&); 00286 ~TriangulatedImplicitSurface(); 00287 00288 Ref<Volume> volume_object() const { return vol_; } 00289 double isovalue() const { return isovalue_; } 00290 00291 void init(); 00292 int inited() const { return inited_; } 00293 }; 00294 00295 } 00296 00297 #endif 00298 00299 // Local Variables: 00300 // mode: c++ 00301 // c-file-style: "CLJ" 00302 // End:

Generated at Thu Jul 29 19:53:51 2004 for MPQC 2.2.1 using the documentation package Doxygen 1.3.7.