GeometryKernel.hh 8.1 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
/*===========================================================================*\
 *                                                                           *
 *                            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/>.                                      *
 *                                                                           *
\*===========================================================================*/

#ifndef GEOMETRYKERNEL_HH_
#define GEOMETRYKERNEL_HH_

#include <cassert>
39
#include <iostream>
40
41
42
43
44
45

#include "../Geometry/VectorT.hh"
#include "TopologyKernel.hh"

namespace OpenVolumeMesh {

46
47
template <class VecT, class TopologyKernelT = TopologyKernel>
class GeometryKernel : public TopologyKernelT {
48
49
50
public:

    typedef VecT PointT;
51
    typedef TopologyKernelT KernelT;
52
53

    /// Constructor
54
    GeometryKernel() = default;
55
56

    /// Destructor
57
    ~GeometryKernel() override = default;
58

59
60
61
62
63
    template<class OtherTopoKernel>
    void assign(const GeometryKernel<VecT, OtherTopoKernel> *other) {
        TopologyKernelT::assign(other);
        other->clone_vertices(vertices_);
    }
64
65

    /// Override of empty add_vertex function
66
    VertexHandle add_vertex() override { return add_vertex(VecT()); }
67
68
69
70
71
72
73
74

    /// Add a geometric point to the mesh
    VertexHandle add_vertex(const VecT& _p) {

        // Store vertex in list
        vertices_.push_back(_p);

        // Get handle of recently created vertex
75
        return KernelT::add_vertex();
76
77
78
79
80
81
82
    }

    /// Set the coordinates of point _vh
    void set_vertex(const VertexHandle& _vh, const VecT& _p) {

        assert(_vh.idx() < (int)vertices_.size());

83
        vertices_[_vh.idx()] = _p;
84
85
86
87
    }

    /// Get point _vh's coordinates
    const VecT& vertex(const VertexHandle& _vh) const {
88
        return vertices_[_vh.idx()];
89
90
    }

91
    VertexIter delete_vertex(const VertexHandle& _h) override {
92
        assert(_h.idx() < (int)TopologyKernelT::n_vertices());
93

94
        VertexIter nV = TopologyKernelT::delete_vertex(_h);
95

96
97
98
99
100
101
        if (TopologyKernelT::deferred_deletion_enabled())
        {

        }
        else
            vertices_.erase(vertices_.begin() + _h.idx());
102
103
104
105

        return nV;
    }

106
    void collect_garbage() override
107
    {
108
109
110
        if (!TopologyKernelT::needs_garbage_collection())
            return;

111
        if (TopologyKernelT::fast_deletion_enabled()) {
112
113
114
            TopologyKernelT::collect_garbage();
            vertices_.resize(TopologyKernel::n_vertices());
        } else {
Max Lyon's avatar
Max Lyon committed
115
            for (int i = (int)vertices_.size(); i > 0; --i)
116
117
118
119
120
121
                if (TopologyKernelT::is_deleted(VertexHandle(i-1)))
                {
                    vertices_.erase(vertices_.begin() + (i-1));
                }
            TopologyKernelT::collect_garbage();
        }
122
123
124

    }

125
    void swap_vertex_indices(VertexHandle _h1, VertexHandle _h2) override
126
127
128
129
130
131
132
133
134
    {
        assert(_h1.idx() >= 0 && _h1.idx() < (int)vertices_.size());
        assert(_h2.idx() >= 0 && _h2.idx() < (int)vertices_.size());

        if (_h1 == _h2)
            return;

        std::swap(vertices_[_h1.idx()], vertices_[_h2.idx()]);

135
        TopologyKernelT::swap_vertex_indices(_h1, _h2);
136
137
    }

138
139
protected:

140
    void delete_multiple_vertices(const std::vector<bool>& _tag) override{
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

        assert(_tag.size() == TopologyKernelT::n_vertices());

        std::vector<VecT> newVertices;

        typename std::vector<VecT>::const_iterator v_it = vertices_.begin();

        for(std::vector<bool>::const_iterator t_it = _tag.begin(),
                t_end = _tag.end(); t_it != t_end; ++t_it, ++v_it) {

            if(!(*t_it)) {
                // Not marked as deleted

                newVertices.push_back(*v_it);
            }
        }

        // Swap vertices
        vertices_.swap(newVertices);

        TopologyKernelT::delete_multiple_vertices(_tag);
    }

public:

166
    void clear(bool _clearProps = true) override {
167
168

        vertices_.clear();
169
        TopologyKernelT::clear(_clearProps);
170
171
    }

172
173
    typename PointT::value_type length(const EdgeHandle& _eh) const {

Mike Kremer's avatar
Mike Kremer committed
174
        const typename TopologyKernelT::Edge& e = TopologyKernelT::edge(_eh);
175
176
177
178
179
        return (vertex(e.to_vertex()) - vertex(e.from_vertex())).length();
    }

    PointT vector(const EdgeHandle& _eh) const {

Mike Kremer's avatar
Mike Kremer committed
180
        const typename TopologyKernelT::Edge& e = TopologyKernelT::edge(_eh);
181
182
183
        return (vertex(e.to_vertex()) - vertex(e.from_vertex()));
    }

184
185
186
187
188
189
    PointT barycenter(const EdgeHandle& _eh) const {
        return PointT(0.5 * vertex(TopologyKernelT::edge(_eh).from_vertex()) +
                      0.5 * vertex(TopologyKernelT::edge(_eh).to_vertex()));
    }

    PointT barycenter(const FaceHandle& _fh) const {
190
        PointT p(typename PointT::value_type(0));
Mike Kremer's avatar
Mike Kremer committed
191
192
        typename PointT::value_type valence = 0;
        HalfFaceVertexIter hfv_it =
193
194
195
196
197
198
199
200
201
                TopologyKernelT::hfv_iter(TopologyKernelT::halfface_handle(_fh, 0));
        for(; hfv_it.valid(); ++hfv_it, valence += 1) {
            p += vertex(*hfv_it);
        }
        p /= valence;
        return p;
    }

    PointT barycenter(const CellHandle& _ch) const {
202
        PointT p(typename PointT::value_type(0));
Mike Kremer's avatar
Mike Kremer committed
203
204
        typename PointT::value_type valence = 0;
        CellVertexIter cv_it = TopologyKernelT::cv_iter(_ch);
205
206
207
208
209
210
211
        for(; cv_it.valid(); ++cv_it, valence += 1) {
            p += vertex(*cv_it);
        }
        p /= valence;
        return p;
    }

212
    void clone_vertices(std::vector<VecT>& _copy) const {
213
        _copy.clear();
214
215
216
217
        _copy.reserve(vertices_.size());
        std::copy(vertices_.begin(), vertices_.end(), std::back_inserter(_copy));
    }

218
    void swap_vertices(std::vector<VecT>& _copy) {
219
        if(_copy.size() != vertices_.size()) {
220
221
222
            std::cerr << "Vertex vectors differ in size! The size of the copy " <<
            		"is artificially set to the correct one. Some values may not be correctly initialized." << std::endl;
            _copy.resize(vertices_.size());
223
224
225
226
        }
        std::swap(vertices_, _copy);
    }

227
228
229
230
231
232
233
234
private:

    std::vector<VecT> vertices_;
};

} // Namespace OpenVolumeMesh

#endif /* GEOMETRYKERNEL_HH_ */