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 #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
00066 std::set<Ref<Vertex> > _vertices;
00067 std::set<Ref<Edge> > _edges;
00068 std::set<Ref<Triangle> > _triangles;
00069
00070
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
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
00081 int** _triangle_vertex;
00082 int** _triangle_edge;
00083 int** _edge_vertex;
00084
00085
00086 int _have_values;
00087 std::vector<double> _values;
00088
00089
00090 Ref<TriangleIntegrator> _integrator;
00091
00092
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
00108
00109
00110
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
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
00125 int verbose() const { return _verbose; }
00126 void verbose(int v) { _verbose = v; }
00127
00128
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
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
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
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
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
00182
00183 void compute_values(Ref<Volume>&);
00184
00185
00186 virtual double flat_area();
00187 virtual double flat_volume();
00188 virtual double area();
00189 virtual double volume();
00190
00191
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
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
00219 TriangulatedSurfaceIntegrator(const Ref<TriangulatedSurface>&);
00220 ~TriangulatedSurfaceIntegrator();
00221
00222
00223
00224 void operator = (const TriangulatedSurfaceIntegrator&);
00225 TriangulatedSurfaceIntegrator(const TriangulatedSurfaceIntegrator&i) {
00226 operator = (i);
00227 }
00228
00229 int n();
00230
00231 void set_surface(const Ref<TriangulatedSurface>&);
00232
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
00242
00243 int update();
00244
00245
00246
00247 int operator < (TriangulatedSurfaceIntegrator&i) {
00248 update();
00249 return _itri<i._itri?1:(_itri>i._itri?0:(_irs<i._irs?1:0));
00250 }
00251
00252 void operator++();
00253 inline void operator++(int) { operator++(); }
00254
00255 int operator = (int);
00256 int itri() const { return _itri; }
00257 int irs() const { return _irs; }
00258
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
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
00300
00301
00302