Subversion Repositories gelsvn

Rev

Rev 595 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 595 Rev 601
1
/* ----------------------------------------------------------------------- *
1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
5
 * ----------------------------------------------------------------------- */
6
 
6
 
7
/**
7
/**
8
 * @file mesh_optimization.h
8
 * @file mesh_optimization.h
9
 * @brief Functions for energy minimization based mesh optimization.
9
 * @brief Functions for energy minimization based mesh optimization.
10
 */
10
 */
11
 
11
 
12
#ifndef __HMESH_MESH_OPTIMIZATION_H
12
#ifndef __HMESH_MESH_OPTIMIZATION_H
13
#define __HMESH_MESH_OPTIMIZATION_H
13
#define __HMESH_MESH_OPTIMIZATION_H
14
 
14
 
15
#include "Manifold.h"
15
#include "Manifold.h"
16
#include <CGLA/Vec3d.h>
16
#include "../CGLA/Vec3d.h"
17
namespace HMesh
17
namespace HMesh
18
{
18
{
19
    // forward declarations
19
    // forward declarations
20
    //class Manifold;
20
    //class Manifold;
21
    //class HalfEdgeID;
21
    //class HalfEdgeID;
22
 
22
 
23
    /// This class represents the energy of an edge. It is used in optimization schemes where edges are swapped (aka flipped). */
23
    /// This class represents the energy of an edge. It is used in optimization schemes where edges are swapped (aka flipped). */
24
    class EnergyFun
24
    class EnergyFun
25
    {
25
    {
26
    public:
26
    public:
27
        virtual double delta_energy(const Manifold& m, HalfEdgeID h) const = 0;
27
        virtual double delta_energy(const Manifold& m, HalfEdgeID h) const = 0;
28
        virtual double energy(const Manifold& m, HalfEdgeID h) const {return 0;}
28
        virtual double energy(const Manifold& m, HalfEdgeID h) const {return 0;}
29
    };
29
    };
30
	
30
	
31
	class MinAngleEnergy: public EnergyFun
31
	class MinAngleEnergy: public EnergyFun
32
	{
32
	{
33
		double min_angle(const CGLA::Vec3d& v0, const CGLA::Vec3d& v1, const CGLA::Vec3d& v2) const;
33
		double min_angle(const CGLA::Vec3d& v0, const CGLA::Vec3d& v1, const CGLA::Vec3d& v2) const;
34
		double thresh;
34
		double thresh;
35
		
35
		
36
	public:
36
	public:
37
		
37
		
38
		MinAngleEnergy(double _thresh): thresh(_thresh) {}
38
		MinAngleEnergy(double _thresh): thresh(_thresh) {}
39
		
39
		
40
		double delta_energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
40
		double delta_energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
41
	};
41
	};
42
	
42
	
43
	class DihedralEnergy: public EnergyFun
43
	class DihedralEnergy: public EnergyFun
44
	{
44
	{
45
		const double gamma;
45
		const double gamma;
46
		const bool use_alpha;
46
		const bool use_alpha;
47
		
47
		
48
		double cos_ang(const CGLA::Vec3d& n1, const CGLA::Vec3d& n2) const
48
		double cos_ang(const CGLA::Vec3d& n1, const CGLA::Vec3d& n2) const
49
		{
49
		{
50
			return CGLA::s_max(-1.0, CGLA::s_min(1.0, CGLA::dot(n1, n2)));
50
			return CGLA::s_max(-1.0, CGLA::s_min(1.0, CGLA::dot(n1, n2)));
51
		}
51
		}
52
		
52
		
53
		double edge_alpha_energy(CGLA::Vec3d v1, CGLA::Vec3d v2, double ca) const
53
		double edge_alpha_energy(CGLA::Vec3d v1, CGLA::Vec3d v2, double ca) const
54
		{
54
		{
55
			return pow(CGLA::length(v1-v2)*(acos(ca)), 1.0f/gamma); 
55
			return pow(CGLA::length(v1-v2)*(acos(ca)), 1.0f/gamma); 
56
		}
56
		}
57
		
57
		
58
		double edge_c_energy(CGLA::Vec3d v1, CGLA::Vec3d v2, double ca) const
58
		double edge_c_energy(CGLA::Vec3d v1, CGLA::Vec3d v2, double ca) const
59
		{
59
		{
60
			return pow(length(v1-v2)*(1-ca), 1.0f/gamma); 
60
			return pow(length(v1-v2)*(1-ca), 1.0f/gamma); 
61
		}
61
		}
62
 
62
 
63
		void compute_angles(const HMesh::Manifold & m, HMesh::HalfEdgeID h) const;
63
		void compute_angles(const HMesh::Manifold & m, HMesh::HalfEdgeID h) const;
64
		
64
		
65
 
65
 
66
 
66
 
67
		mutable double ab_12;
67
		mutable double ab_12;
68
		mutable double ab_a1;
68
		mutable double ab_a1;
69
		mutable double ab_b1;
69
		mutable double ab_b1;
70
		mutable double ab_2c;
70
		mutable double ab_2c;
71
		mutable double ab_2d;
71
		mutable double ab_2d;
72
		
72
		
73
		mutable double aa_12;
73
		mutable double aa_12;
74
		mutable double aa_b1;
74
		mutable double aa_b1;
75
		mutable double aa_c1;
75
		mutable double aa_c1;
76
		mutable double aa_2a;
76
		mutable double aa_2a;
77
		mutable double aa_2d;
77
		mutable double aa_2d;
78
		
78
		
79
	public:
79
	public:
80
		
80
		
81
		DihedralEnergy(double _gamma = 4.0, bool _use_alpha=false): 
81
		DihedralEnergy(double _gamma = 4.0, bool _use_alpha=false): 
82
		gamma(_gamma), use_alpha(_use_alpha) {}
82
		gamma(_gamma), use_alpha(_use_alpha) {}
83
		
83
		
84
		double energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
84
		double energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
85
		
85
		
86
		double delta_energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
86
		double delta_energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
87
	
87
	
88
		double min_angle(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const
88
		double min_angle(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const
89
		{
89
		{
90
			compute_angles(m, h);
90
			compute_angles(m, h);
91
			return CGLA::s_min(CGLA::s_min(CGLA::s_min(CGLA::s_min(aa_12, aa_b1), aa_c1), aa_2a), aa_2d);
91
			return CGLA::s_min(CGLA::s_min(CGLA::s_min(CGLA::s_min(aa_12, aa_b1), aa_c1), aa_2a), aa_2d);
92
		}		
92
		}		
93
	};
93
	};
94
	
94
	
95
	class CurvatureEnergy: public EnergyFun
95
	class CurvatureEnergy: public EnergyFun
96
	{
96
	{
97
		double abs_mean_curv(const CGLA::Vec3d& v, const std::vector<CGLA::Vec3d>& ring) const;
97
		double abs_mean_curv(const CGLA::Vec3d& v, const std::vector<CGLA::Vec3d>& ring) const;
98
	public:
98
	public:
99
		double delta_energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
99
		double delta_energy(const HMesh::Manifold& m, HMesh::HalfEdgeID h) const;
100
	};		
100
	};		
101
    
101
    
102
    class ValencyEnergy: public EnergyFun
102
    class ValencyEnergy: public EnergyFun
103
	{
103
	{
104
	public:
104
	public:
105
		double delta_energy(const Manifold& m, HalfEdgeID h) const;
105
		double delta_energy(const Manifold& m, HalfEdgeID h) const;
106
	};
106
	};
107
 
107
 
108
 
108
 
109
    /// Optimize in a greedy fashion.
109
    /// Optimize in a greedy fashion.
110
    void priority_queue_optimization(Manifold& m, const EnergyFun& efun);
110
    void priority_queue_optimization(Manifold& m, const EnergyFun& efun);
111
 
111
 
112
    /// Optimize with simulated annealing. Avoids getting trapped in local minima
112
    /// Optimize with simulated annealing. Avoids getting trapped in local minima
113
    void simulated_annealing_optimization(Manifold& m, const EnergyFun& efun, int max_iter=10000);
113
    void simulated_annealing_optimization(Manifold& m, const EnergyFun& efun, int max_iter=10000);
114
 
114
 
115
    /// Minimize the angle between adjacent triangles. Almost the same as mean curvature minimization 
115
    /// Minimize the angle between adjacent triangles. Almost the same as mean curvature minimization 
116
    void minimize_dihedral_angle(Manifold& m, int max_iter=10000, bool anneal=false, bool alpha=false, double gamma=4.0);
116
    void minimize_dihedral_angle(Manifold& m, int max_iter=10000, bool anneal=false, bool alpha=false, double gamma=4.0);
117
 
117
 
118
    /// Minimizes mean curvature. This is really the same as dihedral angle optimization except that we weight by edge length 
118
    /// Minimizes mean curvature. This is really the same as dihedral angle optimization except that we weight by edge length 
119
    void minimize_curvature(Manifold& m, bool anneal=false);
119
    void minimize_curvature(Manifold& m, bool anneal=false);
120
 
120
 
121
    /// Minimizes gaussian curvature. Probably less useful than mean curvature.
121
    /// Minimizes gaussian curvature. Probably less useful than mean curvature.
122
    void minimize_gauss_curvature(Manifold& m, bool anneal=false);
122
    void minimize_gauss_curvature(Manifold& m, bool anneal=false);
123
 
123
 
124
    /// Maximizes the minimum angle of triangles. Makes the mesh more Delaunay.
124
    /// Maximizes the minimum angle of triangles. Makes the mesh more Delaunay.
125
    void maximize_min_angle(Manifold& m, float thresh, bool anneal=false);
125
    void maximize_min_angle(Manifold& m, float thresh, bool anneal=false);
126
 
126
 
127
    /// Tries to achieve valence 6 internally and 4 along edges.
127
    /// Tries to achieve valence 6 internally and 4 along edges.
128
    void optimize_valency(Manifold& m, bool anneal=false);
128
    void optimize_valency(Manifold& m, bool anneal=false);
129
 
129
 
130
    /// Make radom flips. Useful for generating synthetic test cases.
130
    /// Make radom flips. Useful for generating synthetic test cases.
131
    void randomize_mesh(Manifold& m, int max_iter);
131
    void randomize_mesh(Manifold& m, int max_iter);
132
 
132
 
133
}
133
}
134
 
134
 
135
 
135
 
136
#endif
136
#endif
137
 
137