Subversion Repositories gelsvn

Rev

Rev 636 | Details | Compare with Previous | Last modification | View Log | RSS feed

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