Developer Documentation
VolumeMeshSelectionPluginT_impl.hh
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39* *
40\*===========================================================================*/
41
42
43#include "VolumeMeshSelectionPlugin.hh"
44#include <stack>
45#include <vector>
46#include <cmath>
47
48//***********************************************************************************
49
59template<class MeshT>
60bool VolumeMeshSelectionPlugin::volumeSelection(MeshT* _mesh, ACG::GLState& _state, QRegion *_region,
61 PrimitiveType _primitiveType, bool _deselection) {
62 using namespace OpenVolumeMesh;
63
64 ACG::Vec3d proj;
65 bool rv = false;
66
67 //reset tagged status
68 StatusAttrib status(*_mesh);
69 for (auto v_it : _mesh->vertices())
70 status[v_it].set_tagged(false);
71
72 //tag all vertices that are projected into region
73 for (auto v_it : _mesh->vertices()) {
74
75 proj = _state.project(_mesh->vertex(v_it));
76
77 if (_region->contains(QPoint((int)proj[0], _state.context_height()- (int)proj[1]))) {
78
79 status[v_it].set_tagged(true);
80 if (_primitiveType & vertexType_) {
81 rv = true;
82 status[v_it].set_selected(!_deselection);
83 }
84 }
85 }
86
87 if (_primitiveType & edgeType_) {
88
89 for (auto e_it : _mesh->edges())
90 {
91 VertexHandle v1 = _mesh->halfedge(_mesh->halfedge_handle(e_it, 0)).to_vertex();
92 VertexHandle v2 = _mesh->halfedge(_mesh->halfedge_handle(e_it, 1)).to_vertex();
93
94 // select only edges whose both vertices are within the selection region
95 if (status[v1].tagged() && status[v2].tagged()) {
96 rv = true;
97 status[e_it].set_selected(!_deselection);
98 }
99 }
100 }
101
102 if (_primitiveType & faceType_) {
103
104 for (auto f_it : _mesh->faces()) {
105 const std::vector<HalfEdgeHandle>& halfedges = _mesh->face(f_it).halfedges();
106 bool all_fv_tagged = true;
107
108 for (std::size_t i = 0; i < halfedges.size(); ++i) {
109 VertexHandle v = _mesh->halfedge(halfedges[i]).to_vertex();
110 all_fv_tagged &= status[v].tagged();
111 }
112
113 // select only faces that are completely within the selection region
114 if (all_fv_tagged) {
115 rv = true;
116 status[f_it].set_selected(!_deselection);
117 }
118 }
119 }
120
121 if (_primitiveType & cellType_) {
122
123 for (auto c_it : _mesh->cells()) {
124 bool all_cv_tagged = true;
125 for (CellVertexIter cv_it(_mesh->cv_iter(c_it)); cv_it.valid(); ++cv_it) {
126 all_cv_tagged &= status[*cv_it].tagged();
127 }
128
129 if (all_cv_tagged) {
130 rv = true;
131 status[c_it].set_selected(!_deselection);
132 }
133 }
134 }
135
136 return rv;
137}
138
139//***********************************************************************************
140
149template<class MeshT>
150void VolumeMeshSelectionPlugin::floodFillSelection(MeshT* _mesh, uint _fh, double _maxAngle,
151 PrimitiveType _primitiveTypes, bool _deselection)
152{
153 using namespace OpenVolumeMesh;
154
155 FaceHandle hitFace(_fh);
156
157 if (!_mesh->is_boundary(hitFace))
158 return;
159
160 HalfFaceHandle hitHalfFace = _mesh->halfface_handle(hitFace, 0);
161
162 if (!_mesh->is_boundary(hitHalfFace))
163 hitHalfFace = _mesh->halfface_handle(hitFace, 1);
164
165 StatusAttrib status(*_mesh);
166
167 // reset tagged status
168 for (auto hf_it : _mesh->halffaces())
169 {
170 status[hf_it].set_tagged(false);
171 }
172
173 status[hitHalfFace].set_tagged(true);
174
175 std::stack<HalfFaceHandle> hf_handles;
176 hf_handles.push(hitHalfFace);
177
178 NormalAttrib<MeshT> normals(*_mesh);
179 typename MeshT::PointT n1 = normals[hitHalfFace];
180 double maxAngle = _maxAngle / 180.0 * M_PI;
181
182 // tag all half-faces whose normal does not deviate too much from the
183 // initial face
184 while (!hf_handles.empty())
185 {
186 HalfFaceHandle hf = hf_handles.top();
187 hf_handles.pop();
188
189 for (BoundaryHalfFaceHalfFaceIter bhfhf_it(hf, _mesh) ; bhfhf_it.valid() ; ++bhfhf_it)
190 {
191 if (status[*bhfhf_it].tagged())
192 continue;
193
194 typename MeshT::PointT n2 = normals[*bhfhf_it];
195
196 double angle = std::acos(n1 | n2);
197
198 if (angle <= maxAngle) {
199 status[*bhfhf_it].set_tagged(true);
200 hf_handles.push(*bhfhf_it);
201 }
202 }
203 }
204
205 // now select all tagged primitives
206 for (auto hf_it : _mesh->halffaces())
207 {
208 if (status[hf_it].tagged())
209 {
210 FaceHandle fh = _mesh->face_handle(hf_it);
211
212 if (_primitiveTypes & vertexType_)
213 for (auto hfv_it : _mesh->halfface_vertices(hf_it))
214 status[hfv_it].set_selected(!_deselection);
215
216 if (_primitiveTypes & edgeType_)
217 {
218 std::vector<HalfEdgeHandle> const& halfedges = _mesh->face(fh).halfedges();
219
220 for (std::size_t i = 0; i < halfedges.size(); ++i)
221 status[_mesh->edge_handle(halfedges[i])].set_selected(!_deselection);
222 }
223
224 if (_primitiveTypes & faceType_)
225 status[fh].set_selected(!_deselection);
226 }
227 }
228}
229
int context_height() const
get gl context height
Definition: GLState.hh:855
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
const VecT & vertex(VertexHandle _vh) const
Get point _vh's coordinates.
static HalfEdgeHandle halfedge_handle(EdgeHandle _h, const unsigned char _subIdx)
Conversion function.
static EdgeHandle edge_handle(HalfEdgeHandle _h)
Handle conversion.
static HalfFaceHandle halfface_handle(FaceHandle _h, const unsigned char _subIdx)
Conversion function.
Edge halfedge(HalfEdgeHandle _halfEdgeHandle) const
Get edge that corresponds to halfedge with handle _halfEdgeHandle.
const Face & face(FaceHandle _faceHandle) const
Get face with handle _faceHandle.
PrimitiveType vertexType_
Primitive type handles:
void floodFillSelection(MeshT *_mesh, uint _fh, double _maxAngle, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are connected (and do not exceed the maximum dihedral angle)
PrimitiveType cellType_
Handle to selection environment.
bool volumeSelection(MeshT *_mesh, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
PrimitiveType edgeType_
Handle to selection environment.
PrimitiveType faceType_
Handle to selection environment.