1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #include "optimisenormalvector.h"
23 #include "geometrytools.h"
25 OptimiseNormalVector::OptimiseNormalVector(bool use_grouping
, double grouping_angle
)
27 m_UseGrouping
= use_grouping
;
28 m_GroupingAngle
= grouping_angle
;
31 void OptimiseNormalVector::addConstraint(vec3_t n
)
33 m_Constraints
.append(n
);
36 void OptimiseNormalVector::addFace(vec3_t n
)
40 foreach (vec3_t nf
, m_Faces
) {
41 if (GeometryTools::angle(n
, nf
) < m_GroupingAngle
) {
54 double OptimiseNormalVector::func(vec3_t n
)
62 foreach (vec3_t nc
, m_Constraints
) {
65 hc
= max(h
, fabs(hc
));
67 foreach (vec3_t nf
, m_Faces
) {
70 hf_min
= min(h
, hf_min
);
71 hf_max
= max(h
, hf_max
);
77 err
= sqr(hc
) + sqr(1 - hf_min
) + sqr(1 - hf_max
);
82 vec3_t
OptimiseNormalVector::optimise(vec3_t n
)
85 computeDerivatives(n
);
88 while (count
< 100 && scale
> 1e-4) {
89 double err1
= func(n
);
90 vec3_t dn
= -1.0*grad_f
;
92 if (grad_f
.abs() > 1e-10) {
95 double relax
= min(scale
, scale
*grad_f
.abs());
100 double err2
= func(n
);
106 computeDerivatives(n
);
111 vec3_t
OptimiseNormalVector::operator()(vec3_t n
)
113 vec3_t n_opt
= optimise(n
);
114 if (!checkVector(n_opt
)) {