NormalAttribT_impl.hh 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