improved performance for face search -- some debugging required
[engrid-github.git] / src / libengrid / optimisenormalvector.cpp
blobfb868812cd775aa9e29fe8fd6f306bd28b4a49ae
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008-2013 enGits GmbH +
7 // + +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
12 // + +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
17 // + +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // + +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 //
23 #include "optimisenormalvector.h"
25 void OptimiseNormalVector::addConstraint(vec3_t n)
27 m_Constraints.append(n);
30 void OptimiseNormalVector::addFace(vec3_t n)
32 m_Faces.append(n);
35 double OptimiseNormalVector::func(vec3_t n)
37 double hf = 1;
38 double hc = 0;
39 vec3_t n0 = n;
40 n0.normalise();
41 foreach (vec3_t nc, m_Constraints) {
42 nc.normalise();
43 double h = nc*n0;
44 hc = max(h, fabs(hc));
46 foreach (vec3_t nf, m_Faces) {
47 nf.normalise();
48 double h = nf*n0;
49 hf = min(h, hf);
51 return sqr(hc) + sqr(1 - hf);
54 vec3_t OptimiseNormalVector::optimise(vec3_t n)
56 int count = 0;
57 computeDerivatives(n);
58 n.normalise();
59 double scale = 1;
60 while (count < 100 && scale > 2e-4) {
61 double ag = grad_f.abs();
62 double err1 = func(n);
63 vec3_t dn = -1.0*grad_f;
64 dn -= (n*dn)*n;
65 if (grad_f.abs() > 1e-10) {
66 dn.normalise();
68 double relax = min(scale, scale*grad_f.abs());
69 dn *= relax;
70 n += dn;
71 n.normalise();
72 double err2 = func(n);
73 if (err2 > err1) {
74 scale *= 0.1;
76 ++count;
77 computeDerivatives(n);
79 return n;
82 vec3_t OptimiseNormalVector::operator()(vec3_t n)
84 vec3_t n_opt = optimise(n);
85 if (!checkVector(n_opt)) {
86 n_opt = n;
88 n_opt.normalise();
89 return n_opt;