![]()
|
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. |