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
59 template<class MeshT>
60 bool 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 VertexIter v_it(_mesh->vertices_begin()), v_end(_mesh->vertices_end());
70 for (; v_it != v_end; ++v_it)
71 status[*v_it].set_tagged(false);
72
73 //tag all vertices that are projected into region
74 for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it) {
75
76 proj = _state.project(_mesh->vertex(*v_it));
77
78 if (_region->contains(QPoint((int)proj[0], _state.context_height()- (int)proj[1]))) {
79
80 status[*v_it].set_tagged(true);
81 if (_primitiveType & vertexType_) {
82 rv = true;
83 status[*v_it].set_selected(!_deselection);
84 }
85 }
86 }
87
88 if (_primitiveType & edgeType_) {
89 EdgeIter e_it(_mesh->edges_begin()), e_end(_mesh->edges_end());
90
91 for (; e_it != e_end; ++e_it)
92 {
93 VertexHandle v1 = _mesh->halfedge(_mesh->halfedge_handle(*e_it, 0)).to_vertex();
94 VertexHandle v2 = _mesh->halfedge(_mesh->halfedge_handle(*e_it, 1)).to_vertex();
95
96 // select only edges whose both vertices are within the selection region
97 if (status[v1].tagged() && status[v2].tagged()) {
98 rv = true;
99 status[*e_it].set_selected(!_deselection);
100 }
101 }
102 }
103
104 if (_primitiveType & faceType_) {
105 FaceIter f_it(_mesh->faces_begin()), f_end(_mesh->faces_end());
106
107 for (; f_it != f_end; ++f_it) {
108 const std::vector<HalfEdgeHandle>& halfedges = _mesh->face(*f_it).halfedges();
109 bool all_fv_tagged = true;
110
111 for (std::size_t i = 0; i < halfedges.size(); ++i) {
112 VertexHandle v = _mesh->halfedge(halfedges[i]).to_vertex();
113 all_fv_tagged &= status[v].tagged();
114 }
115
116 // select only faces that are completely within the selection region
117 if (all_fv_tagged) {
118 rv = true;
119 status[*f_it].set_selected(!_deselection);
120 }
121 }
122 }
123
124 if (_primitiveType & cellType_) {
125 CellIter c_it(_mesh->cells_begin()), c_end(_mesh->cells_end());
126
127 for (; c_it != c_end; ++c_it) {
128 bool all_cv_tagged = true;
129 for (CellVertexIter cv_it(_mesh->cv_iter(*c_it)); cv_it.valid(); ++cv_it) {
130 all_cv_tagged &= status[*cv_it].tagged();
131 }
132
133 if (all_cv_tagged) {
134 rv = true;
135 status[*c_it].set_selected(!_deselection);
136 }
137 }
138 }
139
140 return rv;
141 }
142
143 //***********************************************************************************
144
153 template<class MeshT>
154 void VolumeMeshSelectionPlugin::floodFillSelection(MeshT* _mesh, uint _fh, double _maxAngle,
155 PrimitiveType _primitiveTypes, bool _deselection)
156 {
157 using namespace OpenVolumeMesh;
158
159 FaceHandle hitFace(_fh);
160
161 if (!_mesh->is_boundary(hitFace))
162 return;
163
164 HalfFaceHandle hitHalfFace = _mesh->halfface_handle(hitFace, 0);
165
166 if (!_mesh->is_boundary(hitHalfFace))
167 hitHalfFace = _mesh->halfface_handle(hitFace, 1);
168
169 StatusAttrib status(*_mesh);
170
171 // reset tagged status
172 HalfFaceIter hf_it(_mesh->halffaces_begin()), hf_end(_mesh->halffaces_end());
173 for (; hf_it != hf_end; ++hf_it)
174 {
175 status[*hf_it].set_tagged(false);
176 }
177
178 status[hitHalfFace].set_tagged(true);
179
180 std::stack<HalfFaceHandle> hf_handles;
181 hf_handles.push(hitHalfFace);
182
183 NormalAttrib<MeshT> normals(*_mesh);
184 typename MeshT::PointT n1 = normals[hitHalfFace];
185 double maxAngle = _maxAngle / 180.0 * M_PI;
186
187 // tag all half-faces whose normal does not deviate too much from the
188 // initial face
189 while (!hf_handles.empty())
190 {
191 HalfFaceHandle hf = hf_handles.top();
192 hf_handles.pop();
193
194 for (BoundaryHalfFaceHalfFaceIter bhfhf_it(hf, _mesh) ; bhfhf_it.valid() ; ++bhfhf_it)
195 {
196 if (status[*bhfhf_it].tagged())
197 continue;
198
199 typename MeshT::PointT n2 = normals[*bhfhf_it];
200
201 double angle = std::acos(n1 | n2);
202
203 if (angle <= maxAngle) {
204 status[*bhfhf_it].set_tagged(true);
205 hf_handles.push(*bhfhf_it);
206 }
207 }
208 }
209
210 // now select all tagged primitives
211 for (hf_it = _mesh->halffaces_begin(); hf_it != hf_end; ++hf_it)
212 {
213 if (status[*hf_it].tagged())
214 {
215 FaceHandle fh = _mesh->face_handle(*hf_it);
216
217 if (_primitiveTypes & vertexType_)
218 for (HalfFaceVertexIter hfv_it(*hf_it, _mesh); hfv_it.valid(); ++hfv_it)
219 status[*hfv_it].set_selected(!_deselection);
220
221 if (_primitiveTypes & edgeType_)
222 {
223 std::vector<HalfEdgeHandle> const& halfedges = _mesh->face(fh).halfedges();
224
225 for (std::size_t i = 0; i < halfedges.size(); ++i)
226 status[_mesh->edge_handle(halfedges[i])].set_selected(!_deselection);
227 }
228
229 if (_primitiveTypes & faceType_)
230 status[fh].set_selected(!_deselection);
231 }
232 }
233 }
234
OpenVolumeMesh
Definition: ColorAttrib.hh:53
OpenVolumeMesh::VertexIter
Definition: Iterators.hh:837
ACG::GLState
Definition: GLState.hh:213
OpenVolumeMesh::EdgeIter
Definition: Iterators.hh:891
OpenVolumeMesh::StatusAttrib
Definition: StatusAttrib.hh:57
OpenVolumeMesh::HandleT< Entity::HalfFace >
ACG::GLState::project
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
OpenMesh::VectorT
Definition: Vector11T.hh:83
OpenVolumeMesh::HalfFaceIter
Definition: Iterators.hh:1053
OpenVolumeMesh::CellVertexIter
Definition: Iterators.hh:603
VolumeMeshSelectionPlugin::volumeSelection
bool volumeSelection(MeshT *_mesh, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
Definition: VolumeMeshSelectionPluginT_impl.hh:60
OpenVolumeMesh::BoundaryHalfFaceHalfFaceIter
Definition: Iterators.hh:777
VolumeMeshSelectionPlugin::floodFillSelection
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) ...
Definition: VolumeMeshSelectionPluginT_impl.hh:154
VolumeMeshSelectionPlugin::faceType_
PrimitiveType faceType_
Handle to selection environment.
Definition: VolumeMeshSelectionPlugin.hh:362
VolumeMeshSelectionPlugin::cellType_
PrimitiveType cellType_
Handle to selection environment.
Definition: VolumeMeshSelectionPlugin.hh:363
VolumeMeshSelectionPlugin::edgeType_
PrimitiveType edgeType_
Handle to selection environment.
Definition: VolumeMeshSelectionPlugin.hh:361
OpenVolumeMesh::NormalAttrib< MeshT >
VolumeMeshSelectionPlugin::vertexType_
PrimitiveType vertexType_
Primitive type handles:
Definition: VolumeMeshSelectionPlugin.hh:360
OpenVolumeMesh::FaceIter
Definition: Iterators.hh:999
ACG::GLState::context_height
int context_height() const
get gl context height
Definition: GLState.hh:830
OpenVolumeMesh::HalfFaceVertexIter
Definition: Iterators.hh:719
OpenVolumeMesh::CellIter
Definition: Iterators.hh:1107