NormalAttribT.cc 6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*===========================================================================*\
 *                                                                           *
 *                            OpenVolumeMesh                                 *
 *        Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen         *
 *                        www.openvolumemesh.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenVolumeMesh.                                     *
 *                                                                           *
 *  OpenVolumeMesh is free software: you can redistribute it and/or modify   *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenVolumeMesh is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenVolumeMesh.  If not,                              *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                         *
 *   $Date$                    *
 *   $LastChangedBy$                                                *
 *                                                                           *
\*===========================================================================*/

#define NORMALATTRIBT_CC

#include <set>

#include "NormalAttrib.hh"

#include "../Core/GeometryKernel.hh"

namespace OpenVolumeMesh {

53
54
template <class GeomKernelT>
NormalAttrib<GeomKernelT>::NormalAttrib(GeomKernelT& _kernel) :
55
kernel_(_kernel),
56
v_normals_(_kernel.template request_vertex_property<typename GeomKernelT::PointT>("vertex_normals")),
57
f_normals_(_kernel.template request_face_property<typename GeomKernelT::PointT>("face_normals"))
58
{
59
60
61

}

62
63
template <class GeomKernelT>
NormalAttrib<GeomKernelT>::~NormalAttrib() {
64
65
66

}

67
68
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::update_vertex_normals() {
69

70
71
    if(!kernel_.has_face_bottom_up_incidences()) {
        std::cerr << "Error: update_vertex_normals() needs bottom-up incidences!" << std::endl;
72
73
74
75
76
77
78
79
80
81
82
        return;
    }

    // Compute face normals
    update_face_normals();

    for(VertexIter v_it = kernel_.v_iter(); v_it.valid(); ++v_it) {
        compute_vertex_normal(*v_it);
    }
}

83
84
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::update_face_normals() {
85

86
87
    if(!kernel_.has_face_bottom_up_incidences()) {
        std::cerr << "Error: update_normals() needs bottom-up incidences!" << std::endl;
88
89
90
        return;
    }

91
92
93
94
95
96
97
    for(FaceIter f_it = kernel_.f_iter(); f_it.valid(); ++f_it) {
        // Assume the face is planar, so just take the
        // first two edges
        compute_face_normal(*f_it);
    }
}

98
99
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::compute_vertex_normal(const VertexHandle& _vh) {
100

101
    std::set<HalfFaceHandle> halffaces;
102
103
104
105
106
107
    for(VertexOHalfEdgeIter voh_it = kernel_.voh_iter(_vh);
            voh_it.valid(); ++voh_it) {

        for(HalfEdgeHalfFaceIter hehf_it = kernel_.hehf_iter(*voh_it);
                hehf_it.valid(); ++hehf_it) {
            if(kernel_.is_boundary(*hehf_it)) {
108
                halffaces.insert(*hehf_it);
109
110
111
            }
        }
    }
112
113
114
115
    typename GeomKernelT::PointT normal = typename GeomKernelT::PointT(0.0);
    for(std::set<HalfFaceHandle>::const_iterator hf_it = halffaces.begin();
            hf_it != halffaces.end(); ++hf_it) {
        normal += (*this)[*hf_it];
116
117
118
119
    }

    normal.normalize();

120
    v_normals_[_vh] = normal;
121
122
}

123
124
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::compute_face_normal(const FaceHandle& _fh) {
125
126
127
128
129
130

    if(kernel_.face(_fh).halfedges().size() < 3) {
        std::cerr << "Warning: Degenerate face detected!" << std::endl;
        return;
    }

131
    const std::vector<HalfEdgeHandle>& halfedges = kernel_.face(_fh).halfedges();
132
133
    std::vector<HalfEdgeHandle>::const_iterator he_it = halfedges.begin();

134
135
    typename GeomKernelT::PointT p1 = kernel_.vertex(kernel_.halfedge(*he_it).from_vertex());
    typename GeomKernelT::PointT p2 = kernel_.vertex(kernel_.halfedge(*he_it).to_vertex());
136
    ++he_it;
137
    typename GeomKernelT::PointT p3 = kernel_.vertex(kernel_.halfedge(*he_it).to_vertex());
138

139
    typename GeomKernelT::PointT n = (p2 - p1) % (p3 - p2);
140
141
    n.normalize();

142
    f_normals_[_fh] = n;
143
144
145
}

} // Namespace OpenVolumeMesh