1 /*
2  *  OGF/Graphite: Geometry and Graphics Programming Library + Utilities
3  *  Copyright (C) 2000-2015 INRIA - Project ALICE
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  *  If you modify this software, you should include a notice giving the
20  *  name of the person performing the modification, the date of modification,
21  *  and the reason for such modification.
22  *
23  *  Contact for Graphite: Bruno Levy - Bruno.Levy@inria.fr
24  *  Contact for this Plugin: Nicolas Ray - nicolas.ray@inria.fr
25  *
26  *     Project ALICE
27  *     LORIA, INRIA Lorraine,
28  *     Campus Scientifique, BP 239
29  *     54506 VANDOEUVRE LES NANCY CEDEX
30  *     FRANCE
31  *
32  *  Note that the GNU General Public License does not permit incorporating
33  *  the Software into proprietary programs.
34  *
35  * As an exception to the GPL, Graphite can be linked with the following
36  * (non-GPL) libraries:
37  *     Qt, tetgen, SuperLU, WildMagic and CGAL
38  */
39 
40 #ifndef H_HEXDOM_ALGO_FRAME_H
41 #define H_HEXDOM_ALGO_FRAME_H
42 
43 #include <exploragram/basic/common.h>
44 #include <exploragram/hexdom/basic.h>
45 #include <exploragram/hexdom/spherical_harmonics_l4.h> // to compute average_frame(vector<mat3>& data) and representative_frame
46 #include <cmath>
47 
48 
49 namespace GEO {
50 
51     /***
52      *               ___     __        __     __
53      *     |\/|  /\   |     |__)  /\  /__` | /  `
54      *     |  | /~~\  |     |__) /~~\ .__/ | \__,
55      *
56      */
57 
58     inline bool is_identity_auvp(const mat3& m, double eps = 1e-15) {
59 	// [BL] TODO: test extra-diagonal elements ? (can be a big cow without that !!!)
60         return std::abs(m(0, 0) - 1.) < eps && std::abs(m(1, 1) - 1.) < eps && std::abs(m(2, 2) - 1.) < eps;
61     }
62 
63     mat3 EXPLORAGRAM_API normalize_columns(const mat3& B);
64     mat3 EXPLORAGRAM_API invert_columns_norm(const mat3& B);
65 
66     /***
67      *               ___     ___            ___  __      __   __  ___
68      *     |\/|  /\   |     |__  |  | |    |__  |__)    |__) /  \  |
69      *     |  | /~~\  |     |___ \__/ |___ |___ |  \    |  \ \__/  |
70      *
71      */
72 
73     mat3 EXPLORAGRAM_API rotx(double angle);
74     mat3 EXPLORAGRAM_API roty(double angle);
75     mat3 EXPLORAGRAM_API rotz(double angle);
76 
77     // non optimized version is  "return rotz(xyz[2]) *roty(xyz[1]) *rotx(xyz[0]);"
78     mat3 euler_to_mat3(vec3 xyz);
79 
80     //http://www.staff.city.ac.uk/~sbbh653/publications/euler.pdf
81     vec3 mat3_to_euler(const mat3& r);
82 
83     /***
84      *                __      __   ___  __             ___      ___    __
85      *     /\  \_/ | /__`    |__) |__  |__)  |\/| |  |  |   /\   |  | /  \ |\ |
86      *    /~~\ / \ | .__/    |    |___ |  \  |  | \__/  |  /~~\  |  | \__/ | \|
87      *
88      */
89 
90 
91     struct EXPLORAGRAM_API AxisPermutation {
92         AxisPermutation(index_t id=0) {  mid = id; }
93         void aligns_B_wrt_ref(mat3 ref, mat3 B);
94 	void make_col2_equal_to_z(mat3 B, vec3 z);
95         const mat3& get_mat() const;
is_identityAxisPermutation96         bool is_identity() { return mid == 0; }
operatorAxisPermutation97         double operator()(index_t i, index_t j) {return get_mat()(i, j); }
98         AxisPermutation inverse();
99 
100         index_t mid;
101     };
102 
103     inline vec3i operator*(const AxisPermutation& p, const vec3i& v) { return p.get_mat()*v; }
104     inline vec3 operator*(const AxisPermutation& p, const vec3& v) { return p.get_mat()*v; }
105 
106     /***
107      *     ___  __              ___
108      *    |__  |__)  /\   |\/| |__
109      *    |    |  \ /~~\  |  | |___
110      *
111      */
112 
113     struct EXPLORAGRAM_API Frame {
114         mat3& r;
FrameFrame115         Frame(mat3& M) :r(M) {}
116 
apply_permutationFrame117         inline mat3 apply_permutation(AxisPermutation& ap) {return r*ap.get_mat();}
118 
119 	void make_z_equal_to(vec3 z);
120 
121 	static mat3 average_frame(vector<mat3>& data);
122 	static mat3 representative_frame(vector<vec3>& bunch_of_vectors, vector<double>& w);
123 	static mat3 representative_frame(vector<vec3>& bunch_of_vectors);
124     };
125 
126     /***
127      *     ___  ___    ___  __   __        __
128      *    |__  |__      |  /  \ /  \ |    /__`
129      *    |    |        |  \__/ \__/ |___ .__/
130      *
131      */
132 
133     AxisPermutation EXPLORAGRAM_API Rij(Mesh* m, Attribute<mat3>& B, index_t i, index_t j);
134 
135     bool EXPLORAGRAM_API triangle_is_frame_singular(Mesh* m, Attribute<mat3>& B, index_t c, index_t cf);
136 
137 	bool triangle_is_frame_singular___give_stable_direction(Mesh* m, int& stable_dir_index, Attribute<mat3>& B, index_t c, index_t cf, index_t cfv=0);
138 	bool triangle_is_frame_singular___give_stable_direction(Mesh* m, vec3& stable_dir_geom, Attribute<mat3>& B, index_t c, index_t cf, index_t cfv=0);
139 }
140 
141 #endif
142