Developer Documentation
HalfedgeSelection.cc
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 * *
44 * $Revision$ *
45 * $Author$ *
46 * $Date$ *
47 * *
48\*===========================================================================*/
49
50#include "MeshObjectSelectionPlugin.hh"
51
53
54//=========================================================
55//==== Halfedge selections
56//=========================================================
57
58void MeshObjectSelectionPlugin::selectHalfedges(int objectId , IdList _halfedgeList) {
59
60 if(_halfedgeList.empty() ) return;
61
62 BaseObjectData* object = 0;
63 if (! PluginFunctions::getObject(objectId,object)) {
64 emit log(LOGERR,tr("selectHalfedges: unable to get object"));
65 return;
66 }
67
68 if (object->dataType() == DATA_TRIANGLE_MESH)
69 MeshSelection::selectHalfedges(PluginFunctions::triMesh(object), _halfedgeList);
70 else if (object->dataType() == DATA_POLY_MESH)
71 MeshSelection::selectHalfedges(PluginFunctions::polyMesh(object), _halfedgeList);
72 else {
73 emit log(LOGERR,tr("selectHalfedges: Unsupported object Type"));
74 return;
75 }
76
77 QString selection = "selectHalfedges(ObjectId(" + QString::number(objectId) + ") , [ " + QString::number(_halfedgeList[0]);
78
79 for (uint i = 1 ; i < _halfedgeList.size(); ++i) {
80 selection += " , " + QString::number(_halfedgeList[i]);
81 }
82
83 selection += " ])";
84
85 emit updatedObject(object->id(), UPDATE_SELECTION_EDGES);
86 emit scriptInfo(selection);
87}
88
89//=========================================================
90
91bool MeshObjectSelectionPlugin::selectHalfedge(int _objectId, int _idx, bool _fly_to_halfedge)
92{
93 return selectElement(_objectId, OpenMesh::HalfedgeHandle(_idx), _fly_to_halfedge);
94}
95
96//=========================================================
97
98void MeshObjectSelectionPlugin::unselectHalfedges(int objectId , IdList _halfedgeList) {
99
100 if(_halfedgeList.empty() ) return;
101
102 BaseObjectData* object = 0;
103 if (! PluginFunctions::getObject(objectId,object)) {
104 emit log(LOGERR,tr("unselectHalfedges: unable to get object"));
105 return;
106 }
107
108 if (object->dataType() == DATA_TRIANGLE_MESH)
109 MeshSelection::unselectHalfedges(PluginFunctions::triMesh(object), _halfedgeList);
110 else if (object->dataType() == DATA_POLY_MESH)
111 MeshSelection::unselectHalfedges(PluginFunctions::polyMesh(object), _halfedgeList);
112 else {
113 emit log(LOGERR,tr("unselectHalfedges: Unsupported object Type"));
114 return;
115 }
116
117 QString selection = "unselectVertices(ObjectId(" + QString::number(objectId) + ") , [ " + QString::number(_halfedgeList[0]);
118
119 for (uint i = 1 ; i < _halfedgeList.size(); ++i) {
120 selection += " , " + QString::number(_halfedgeList[i]);
121 }
122
123 selection += " ])";
124
125 emit updatedObject(object->id(), UPDATE_SELECTION_EDGES);
126 emit scriptInfo(selection);
127}
128
129//=========================================================
130
132
133 BaseObjectData* object;
134 if (! PluginFunctions::getObject(objectId,object)) {
135 emit log(LOGERR,tr("selectAllVertices: unable to get object"));
136 return;
137 }
138
139 if (object->dataType() == DATA_TRIANGLE_MESH)
140 MeshSelection::selectAllHalfedges(PluginFunctions::triMesh(object));
141 else if (object->dataType() == DATA_POLY_MESH)
142 MeshSelection::selectAllHalfedges(PluginFunctions::polyMesh(object));
143 else {
144 emit log(LOGERR,tr("selectAllHalfedges: Unsupported object Type"));
145 return;
146 }
147
148 emit updatedObject(object->id(), UPDATE_SELECTION_EDGES);
149 emit scriptInfo("selectAllHalfedges(ObjectId(" + QString::number(objectId) + "))");
150}
151
152//=========================================================
153
155
156 BaseObjectData* object;
157 if (! PluginFunctions::getObject(objectId,object)) {
158 emit log(LOGERR,tr("clearHalfedgeSelection: unable to get object"));
159 return;
160 }
161
162 if (object->dataType() == DATA_TRIANGLE_MESH)
163 MeshSelection::clearHalfedgeSelection(PluginFunctions::triMesh(object));
164 else if (object->dataType() == DATA_POLY_MESH)
165 MeshSelection::clearHalfedgeSelection(PluginFunctions::polyMesh(object));
166 else {
167 emit log(LOGERR,tr("clearHalfedgeSelection: Unsupported object Type"));
168 return;
169 }
170
171 emit updatedObject(object->id(), UPDATE_SELECTION_EDGES);
172 emit scriptInfo("clearHalfedgeSelection(ObjectId(" + QString::number(objectId) + "))");
173}
174
175//=========================================================
176
178
179 BaseObjectData* object;
180 if (! PluginFunctions::getObject(objectId,object)) {
181 emit log(LOGERR,tr("invertHalfedgeSelection: unable to get object"));
182 return;
183 }
184
185 if (object->dataType() == DATA_TRIANGLE_MESH)
186 MeshSelection::invertHalfedgeSelection(PluginFunctions::triMesh(object));
187 else if (object->dataType() == DATA_POLY_MESH)
188 MeshSelection::invertHalfedgeSelection(PluginFunctions::polyMesh(object));
189 else {
190 emit log(LOGERR,tr("invertHalfedgeSelection: Unsupported object Type"));
191 return;
192 }
193
194 emit updatedObject(object->id(), UPDATE_SELECTION_EDGES);
195 emit scriptInfo("invertHalfedgeSelection(ObjectId(" + QString::number(objectId) + "))");
196}
197
198//=========================================================
199
201
202 BaseObjectData* object;
203 if (! PluginFunctions::getObject(objectId,object)) {
204 emit log(LOGERR,tr("selectBoundaryHalfedges: unable to get object"));
205 return;
206 }
207
208 if (object->dataType() == DATA_TRIANGLE_MESH)
209 MeshSelection::selectBoundaryHalfedges(PluginFunctions::triMesh(object));
210 else if (object->dataType() == DATA_POLY_MESH)
211 MeshSelection::selectBoundaryHalfedges(PluginFunctions::polyMesh(object));
212 else {
213 emit log(LOGERR,tr("selectBoundaryHalfedges: Unsupported object Type"));
214 return;
215 }
216
217 emit updatedObject(object->id(), UPDATE_SELECTION_EDGES);
218 emit scriptInfo("selectBoundaryHalfedges(ObjectId(" + QString::number(objectId) + "))");
219}
220
221//=========================================================
222
224
225 BaseObjectData* object;
226 if (! PluginFunctions::getObject(objectId,object)) {
227 emit log(LOGERR,tr("getHalfedgeSelection: unable to get object"));
228 return IdList(0);
229 }
230
231 emit scriptInfo("getHalfedgeSelection(ObjectId(" + QString::number(objectId) + "))");
232
233 if (object->dataType() == DATA_TRIANGLE_MESH)
234 return MeshSelection::getHalfedgeSelection(PluginFunctions::triMesh(object));
235 else if (object->dataType() == DATA_POLY_MESH)
236 return MeshSelection::getHalfedgeSelection(PluginFunctions::polyMesh(object));
237 else {
238 emit log(LOGERR,tr("getHalfedgeSelection: Unsupported object Type"));
239 return IdList(0);
240 }
241
242 return IdList(0);
243
244}
245
246//=========================================================
247
249
250 IdList vertex_pairs;
251
252 BaseObjectData* object = 0;
253 if ( !PluginFunctions::getObject(_id,object) ) {
254 emit log(LOGERR,tr("Cannot find object for id ") + QString::number(_id));
255 return IdList(0);
256 }
257
258 if(object->dataType() == DATA_TRIANGLE_MESH) {
259
260 TriMeshObject* obj = 0;
261 if(!PluginFunctions::getObject(_id, obj)) {
262 emit log(LOGERR, "Could not get mesh object!");
263 return IdList(0);
264 }
265
266 TriMesh* mesh = obj->mesh();
267
268 for(auto it : _halfedges) {
269 vertex_pairs.push_back(mesh->from_vertex_handle(TriMesh::HalfedgeHandle(it)).idx());
270 vertex_pairs.push_back(mesh->to_vertex_handle(TriMesh::HalfedgeHandle(it)).idx());
271 }
272
273 } else if(object->dataType() == DATA_POLY_MESH) {
274
275 PolyMeshObject* obj = 0;
276 if(!PluginFunctions::getObject(_id, obj)) {
277 emit log(LOGERR, "Could not get mesh object!");
278 return IdList(0);
279 }
280
281 PolyMesh* mesh = obj->mesh();
282
283 for(auto it : _halfedges) {
284 vertex_pairs.push_back(mesh->from_vertex_handle(PolyMesh::HalfedgeHandle(it)).idx());
285 vertex_pairs.push_back(mesh->to_vertex_handle(PolyMesh::HalfedgeHandle(it)).idx());
286 }
287 }
288
289 return vertex_pairs;
290}
291
292//=========================================================
293
295
296 if(_vertices.size() % 2 != 0) {
297 emit log(LOGERR, "Number of vertices is not even!");
298 return IdList(0);
299 }
300
301 IdList halfedges;
302
303 BaseObjectData* object = 0;
304 if ( !PluginFunctions::getObject(_id,object) ) {
305 emit log(LOGERR,tr("Cannot find object for id ") + QString::number(_id));
306 return IdList(0);
307 }
308
309 if(object->dataType() == DATA_TRIANGLE_MESH) {
310
311 TriMeshObject* obj = 0;
312 if(!PluginFunctions::getObject(_id, obj)) {
313 emit log(LOGERR, "Could not get mesh object!");
314 return IdList(0);
315 }
316
317 TriMesh* mesh = obj->mesh();
318
319 for(IdList::const_iterator it = _vertices.begin(); it != _vertices.end(); it+=2) {
321 if(!vh.is_valid()) continue;
322 for(auto voh_it : vh.outgoing_halfedges()) {
323 if(voh_it.to().idx() == *(it+1)) {
324 halfedges.push_back(voh_it.idx());
325 continue;
326 }
327 }
328 }
329
330 } else if(object->dataType() == DATA_POLY_MESH) {
331
332 PolyMeshObject* obj = 0;
333 if(!PluginFunctions::getObject(_id, obj)) {
334 emit log(LOGERR, "Could not get mesh object!");
335 return IdList(0);
336 }
337
338 PolyMesh* mesh = obj->mesh();
339
340 for(IdList::const_iterator it = _vertices.begin(); it != _vertices.end(); it+=2) {
342 if(!vh.is_valid()) continue;
343 for(auto voh_it : vh.outgoing_halfedges()) {
344 if(voh_it.to().idx() == *(it+1)) {
345 halfedges.push_back(voh_it.idx());
346 continue;
347 }
348 }
349 }
350 }
351
352 return halfedges;
353}
354
355//=========================================================
356
358void MeshObjectSelectionPlugin::colorizeHalfedgeSelection(int objectId, int r, int g, int b, int a) {
359
360 BaseObjectData* object;
361 if (! PluginFunctions::getObject(objectId,object)) {
362 emit log(LOGERR,"colorizeHalfedgeSelection: unable to get object");
363 return;
364 }
365
366 if (object->dataType() == DATA_TRIANGLE_MESH) {
368 } else if (object->dataType() == DATA_POLY_MESH) {
370 } else {
371 emit log(LOGERR,"colorizeHalfedgeSelection: Unsupported object Type");
372 return;
373 }
374
375 emit scriptInfo("colorizeHalfedgeSelection(ObjectId(" + QString::number(objectId) + "), "
376 + QString::number(r) + ", " + QString::number(g) + ", " + QString::number(b) + ")");
377
378 emit updatedObject(object->id(), UPDATE_COLOR);
379}
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:181
@ LOGERR
Functions for selection on a mesh.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
bool dataType(DataType _type) const
Definition: BaseObject.cc:219
int id() const
Definition: BaseObject.cc:188
void colorizeSelection(MeshT *_mesh, PrimitiveType _primitiveTypes, int _red, int _green, int _blue, int _alpha)
Colorize the selection.
void selectBoundaryHalfedges(int objectId)
Select boundary edges.
bool selectHalfedge(int _objectId, int _idx, bool _fly_to_halfedge)
Select halfedge with id _idx and maybe fly to it.
bool selectElement(int _objectId, HandleT _handle, bool _fly_to_element)
set dihedral angle threshold for edge selection
void selectAllHalfedges(int objectId)
Select all Halfedges.
IdList getHalfedgeSelection(int objectId)
Return a list of all selected edges.
void invertHalfedgeSelection(int objectId)
Unselect all Halfedges.
IdList convertVertexPairsToHalfedges(int _id, const IdList &_vertices)
Inverse of function above.
void selectHalfedges(int objectId, IdList _vertexList)
Select given Halfedges.
void clearHalfedgeSelection(int objectId)
Invert the current edge selection.
IdList convertHalfedgesToVertexPairs(int _id, const IdList &_halfedges)
Convert halfedge ids to vertex pairs.
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.
void colorizeHalfedgeSelection(int objectId, int r, int g, int b, int a)
Colorize the edge selection.
void unselectHalfedges(int objectId, IdList _vertexList)
Unselect given Halfedges.
MeshT * mesh()
return a pointer to the mesh
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136
Kernel::HalfedgeHandle HalfedgeHandle
Scalar type.
Definition: PolyMeshT.hh:137
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:65
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:67
const UpdateType UPDATE_SELECTION_EDGES(UpdateTypeSet(64))
Edge selection has changed.
const UpdateType UPDATE_COLOR(UpdateTypeSet(1024))
Colors have changed.
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
Handle for a halfedge entity.
Definition: Handles.hh:128
Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access t...
PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const
Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_range())