NormalAttribT_impl.hh 5.58 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
/*===========================================================================*\
 *                                                                           *
 *                            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/>.                                      *
 *                                                                           *
\*===========================================================================*/

#define NORMALATTRIBT_CC

#include <set>

#include "NormalAttrib.hh"

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

namespace OpenVolumeMesh {

45 46
template <class GeomKernelT>
NormalAttrib<GeomKernelT>::NormalAttrib(GeomKernelT& _kernel) :
47
kernel_(_kernel),
48 49
v_normals_(_kernel.template request_vertex_property<typename GeomKernelT::PointT>("vertex_normals", typename GeomKernelT::PointT(0.0))),
f_normals_(_kernel.template request_face_property<typename GeomKernelT::PointT>("face_normals", typename GeomKernelT::PointT(0.0)))
50
{
51 52 53

}

54 55
template <class GeomKernelT>
NormalAttrib<GeomKernelT>::~NormalAttrib() {
56 57 58

}

59 60
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::update_vertex_normals() {
61

62 63
    if(!kernel_.has_face_bottom_up_incidences()) {
        std::cerr << "Error: update_vertex_normals() needs bottom-up incidences!" << std::endl;
64 65 66 67 68 69 70 71 72 73 74
        return;
    }

    // Compute face normals
    update_face_normals();

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

75 76
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::update_face_normals() {
77

78 79
    if(!kernel_.has_face_bottom_up_incidences()) {
        std::cerr << "Error: update_normals() needs bottom-up incidences!" << std::endl;
80 81 82
        return;
    }

83 84 85 86 87 88 89
    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);
    }
}

90 91
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::compute_vertex_normal(const VertexHandle& _vh) {
92

93
    std::set<HalfFaceHandle> halffaces;
94 95 96 97 98 99
    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)) {
100
                halffaces.insert(*hehf_it);
101 102 103
            }
        }
    }
104 105 106 107
    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];
108 109 110 111
    }

    normal.normalize();

112
    v_normals_[_vh] = normal;
113 114
}

115 116
template <class GeomKernelT>
void NormalAttrib<GeomKernelT>::compute_face_normal(const FaceHandle& _fh) {
117 118 119 120 121 122

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

123
    const std::vector<HalfEdgeHandle>& halfedges = kernel_.face(_fh).halfedges();
124 125
    std::vector<HalfEdgeHandle>::const_iterator he_it = halfedges.begin();

126 127
    typename GeomKernelT::PointT p1 = kernel_.vertex(kernel_.halfedge(*he_it).from_vertex());
    typename GeomKernelT::PointT p2 = kernel_.vertex(kernel_.halfedge(*he_it).to_vertex());
128
    ++he_it;
129
    typename GeomKernelT::PointT p3 = kernel_.vertex(kernel_.halfedge(*he_it).to_vertex());
130

131
    typename GeomKernelT::PointT n = (p2 - p1) % (p3 - p2);
132 133
    n.normalize();

134
    f_normals_[_fh] = n;
135 136 137
}

} // Namespace OpenVolumeMesh