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 namespace sc {
00049
00050 class TriangulatedSurface: public DescribedClass {
00051 protected:
00052 int _verbose;
00053 int _debug;
00054
00055 int _completed_surface;
00056
00057
00058 AVLSet<Ref<Vertex> > _vertices;
00059 AVLSet<Ref<Edge> > _edges;
00060 AVLSet<Ref<Triangle> > _triangles;
00061
00062
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
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
00079 int** _triangle_vertex;
00080 int** _triangle_edge;
00081 int** _edge_vertex;
00082
00083
00084 int _have_values;
00085 Arraydouble _values;
00086
00087
00088 Ref<TriangleIntegrator> _integrator;
00089
00090
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
00106
00107
00108
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
00116 AVLMap<Ref<Vertex>,AVLSet<Ref<Edge> > > _tmp_edges;
00117 public:
00118 TriangulatedSurface();
00119 TriangulatedSurface(const Ref<KeyVal>&);
00120 virtual ~TriangulatedSurface();
00121
00122
00123 int verbose() const { return _verbose; }
00124 void verbose(int v) { _verbose = v; }
00125
00126
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
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
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
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
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
00180
00181 void compute_values(Ref<Volume>&);
00182
00183
00184 virtual double flat_area();
00185 virtual double flat_volume();
00186 virtual double area();
00187 virtual double volume();
00188
00189
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
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
00217 TriangulatedSurfaceIntegrator(const Ref<TriangulatedSurface>&);
00218 ~TriangulatedSurfaceIntegrator();
00219
00220
00221
00222 void operator = (const TriangulatedSurfaceIntegrator&);
00223 TriangulatedSurfaceIntegrator(const TriangulatedSurfaceIntegrator&i) {
00224 operator = (i);
00225 }
00226
00227 int n();
00228
00229 void set_surface(const Ref<TriangulatedSurface>&);
00230
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
00240
00241 int update();
00242
00243
00244
00245 int operator < (TriangulatedSurfaceIntegrator&i) {
00246 update();
00247 return _itri<i._itri?1:(_itri>i._itri?0:(_irs<i._irs?1:0));
00248 }
00249
00250 void operator++();
00251 inline void operator++(int) { operator++(); }
00252
00253 int operator = (int);
00254 int itri() const { return _itri; }
00255 int irs() const { return _irs; }
00256
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
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
00298
00299
00300