00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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 class TriangulatedSurface: public DescribedClass {
00049 protected:
00050 int _verbose;
00051 int _debug;
00052
00053 int _completed_surface;
00054
00055
00056 AVLSet<Ref<Vertex> > _vertices;
00057 AVLSet<Ref<Edge> > _edges;
00058 AVLSet<Ref<Triangle> > _triangles;
00059
00060
00061 AVLMap<Ref<Vertex>,int> _vertex_to_index;
00062 AVLMap<Ref<Edge>,int> _edge_to_index;
00063 AVLMap<Ref<Triangle>,int> _triangle_to_index;
00064
00065
00066 #ifdef HAVE_STL
00067 std::vector<Ref<Vertex> > _index_to_vertex;
00068 std::vector<Ref<Edge> > _index_to_edge;
00069 std::vector<Ref<Triangle> > _index_to_triangle;
00070 #else
00071 Array<Ref<Vertex> > _index_to_vertex;
00072 Array<Ref<Edge> > _index_to_edge;
00073 Array<Ref<Triangle> > _index_to_triangle;
00074 #endif
00075
00076
00077 int** _triangle_vertex;
00078 int** _triangle_edge;
00079 int** _edge_vertex;
00080
00081
00082 int _have_values;
00083 Arraydouble _values;
00084
00085
00086 Ref<TriangleIntegrator> _integrator;
00087
00088
00089 Ref<TriangleIntegrator> _fast_integrator;
00090 Ref<TriangleIntegrator> _accurate_integrator;
00091
00092 void clear_int_arrays();
00093
00094 void complete_ref_arrays();
00095 void complete_int_arrays();
00096
00097 void recompute_index_maps();
00098
00099 void add_triangle(const Ref<Triangle>&);
00100 void add_vertex(const Ref<Vertex>&);
00101 void add_edge(const Ref<Edge>&);
00102
00103
00104
00105
00106
00107 virtual Triangle* newTriangle(const Ref<Edge>&,
00108 const Ref<Edge>&,
00109 const Ref<Edge>&,
00110 int orientation) const;
00111 virtual Edge* newEdge(const Ref<Vertex>&,const Ref<Vertex>&) const;
00112
00113
00114 AVLMap<Ref<Vertex>,AVLSet<Ref<Edge> > > _tmp_edges;
00115 public:
00116 TriangulatedSurface();
00117 TriangulatedSurface(const Ref<KeyVal>&);
00118 virtual ~TriangulatedSurface();
00119
00120
00121 int verbose() const { return _verbose; }
00122 void verbose(int v) { _verbose = v; }
00123
00124
00125 void set_integrator(const Ref<TriangleIntegrator>&);
00126 void set_fast_integrator(const Ref<TriangleIntegrator>&);
00127 void set_accurate_integrator(const Ref<TriangleIntegrator>&);
00128 virtual Ref<TriangleIntegrator> integrator(int itri);
00129 virtual Ref<TriangleIntegrator> fast_integrator(int itri);
00130 virtual Ref<TriangleIntegrator> accurate_integrator(int itri);
00131
00132
00133 void add_triangle(const Ref<Vertex>&,
00134 const Ref<Vertex>&,
00135 const Ref<Vertex>&);
00136 Ref<Edge> find_edge(const Ref<Vertex>&, const Ref<Vertex>&);
00137 virtual void complete_surface();
00138
00139
00140 virtual void remove_short_edges(double cutoff_length = 1.0e-6,
00141 const Ref<Volume> &vol=0, double isoval=0.0);
00142 virtual void remove_slender_triangles(
00143 int remove_slender, double height_cutoff,
00144 int remove_small, double area_cutoff,
00145 const Ref<Volume> &vol=0, double isoval=0.0);
00146 virtual void fix_orientation();
00147 virtual void clear();
00148
00149
00150 int nvertex() const { return _vertices.length(); };
00151 Ref<Vertex> vertex(int i) const { return _index_to_vertex[i]; };
00152 int vertex_index(const Ref<Vertex> &o) {
00153 AVLMap<Ref<Vertex>,int>::iterator i = _vertex_to_index.find(o);
00154 if (i != _vertex_to_index.end()) return i.data();
00155 return -1;
00156 }
00157 int nedge() const { return _edges.length(); };
00158 Ref<Edge> edge(int i) const { return _index_to_edge[i]; };
00159 int edge_index(const Ref<Edge> &o) {
00160 AVLMap<Ref<Edge>,int>::iterator i = _edge_to_index.find(o);
00161 if (i != _edge_to_index.end()) return i.data();
00162 return -1;
00163 }
00164 int ntriangle() const { return _triangles.length(); };
00165 Ref<Triangle> triangle(int i) const { return _index_to_triangle[i]; }
00166 int triangle_index(const Ref<Triangle> &o) {
00167 AVLMap<Ref<Triangle>,int>::iterator i = _triangle_to_index.find(o);
00168 if (i != _triangle_to_index.end()) return i.data();
00169 return -1;
00170 }
00171
00172
00173 int triangle_vertex(int i,int j) const { return _triangle_vertex[i][j]; };
00174 int triangle_edge(int i,int j) const { return _triangle_edge[i][j]; };
00175 int edge_vertex(int i,int j) const { return _edge_vertex[i][j]; };
00176
00177
00178
00179 void compute_values(Ref<Volume>&);
00180
00181
00182 virtual double flat_area();
00183 virtual double flat_volume();
00184 virtual double area();
00185 virtual double volume();
00186
00187
00188 virtual void print(std::ostream&o=ExEnv::out()) const;
00189 virtual void print_vertices_and_triangles(std::ostream&o=ExEnv::out()) const;
00190 virtual void print_geomview_format(std::ostream&o=ExEnv::out()) const;
00191 virtual void render(const Ref<Render> &render);
00192
00193
00194 void topology_info(std::ostream&o=ExEnv::out());
00195 void topology_info(int nvertex, int nedge, int ntri, std::ostream&o=ExEnv::out());
00196 };
00197
00198
00199 class TriangulatedSurfaceIntegrator {
00200 private:
00201 Ref<TriangulatedSurface> _ts;
00202 int _itri;
00203 int _irs;
00204 double _r;
00205 double _s;
00206 double _weight;
00207 double _surface_element;
00208 Ref<Vertex> _current;
00209 SCVector3 _dA;
00210 Ref<TriangleIntegrator> (TriangulatedSurface::*_integrator)(int itri);
00211 Ref<MessageGrp> _grp;
00212 public:
00213 TriangulatedSurfaceIntegrator();
00214
00215 TriangulatedSurfaceIntegrator(const Ref<TriangulatedSurface>&);
00216 ~TriangulatedSurfaceIntegrator();
00217
00218
00219
00220 void operator = (const TriangulatedSurfaceIntegrator&);
00221 TriangulatedSurfaceIntegrator(const TriangulatedSurfaceIntegrator&i) {
00222 operator = (i);
00223 }
00224
00225 int n();
00226
00227 void set_surface(const Ref<TriangulatedSurface>&);
00228
00229 int vertex_number(int i);
00230 inline double r() const { return _r; }
00231 inline double s() const { return _s; }
00232 inline double w() const { return _weight*_surface_element; }
00233 double surface_element() const { return _surface_element; }
00234 double weight() const { return _weight; }
00235 const SCVector3& dA() const { return _dA; }
00236 Ref<Vertex> current();
00237
00238
00239 int update();
00240
00241
00242
00243 int operator < (TriangulatedSurfaceIntegrator&i) {
00244 update();
00245 return _itri<i._itri?1:(_itri>i._itri?0:(_irs<i._irs?1:0));
00246 }
00247
00248 void operator++();
00249 inline void operator++(int) { operator++(); }
00250
00251 int operator = (int);
00252 int itri() const { return _itri; }
00253 int irs() const { return _irs; }
00254
00255 int n_in_tri() const { return (_ts.pointer()->*_integrator)(_itri)->n(); }
00256 void distribute(const Ref<MessageGrp> &);
00257 void use_fast_integrator();
00258 void use_accurate_integrator();
00259 void use_default_integrator();
00260 };
00261
00262 class TriangulatedImplicitSurface: public TriangulatedSurface {
00263 private:
00264
00265 Ref<Volume> vol_;
00266 double isovalue_;
00267
00268 int fix_orientation_;
00269 int remove_short_edges_;
00270 double short_edge_factor_;
00271 int remove_slender_triangles_;
00272 double slender_triangle_factor_;
00273 int remove_small_triangles_;
00274 double small_triangle_factor_;
00275 double resolution_;
00276
00277 int order_;
00278
00279 int inited_;
00280 public:
00281 TriangulatedImplicitSurface(const Ref<KeyVal>&);
00282 ~TriangulatedImplicitSurface();
00283
00284 Ref<Volume> volume_object() const { return vol_; }
00285 double isovalue() const { return isovalue_; }
00286
00287 void init();
00288 int inited() const { return inited_; }
00289 };
00290
00291
00292 #endif
00293
00294
00295
00296
00297