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 
58 void 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 
91 bool 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 
98 void 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(IdList::const_iterator it = _halfedges.begin(); it != _halfedges.end(); ++it) {
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(IdList::const_iterator it = _halfedges.begin(); it != _halfedges.end(); ++it) {
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(TriMesh::VertexOHalfedgeIter voh_it = mesh->voh_iter(vh);
323  voh_it.is_valid(); ++voh_it) {
324  if(mesh->to_vertex_handle(*voh_it).idx() == *(it+1)) {
325  halfedges.push_back(voh_it->idx());
326  continue;
327  }
328  }
329  }
330 
331  } else if(object->dataType() == DATA_POLY_MESH) {
332 
333  PolyMeshObject* obj = 0;
334  if(!PluginFunctions::getObject(_id, obj)) {
335  emit log(LOGERR, "Could not get mesh object!");
336  return IdList(0);
337  }
338 
339  PolyMesh* mesh = obj->mesh();
340 
341  for(IdList::const_iterator it = _vertices.begin(); it != _vertices.end(); it+=2) {
343  if(!vh.is_valid()) continue;
344  for(PolyMesh::VertexOHalfedgeIter voh_it = mesh->voh_iter(vh);
345  voh_it.is_valid(); ++voh_it) {
346  if(mesh->to_vertex_handle(*voh_it).idx() == *(it+1)) {
347  halfedges.push_back(voh_it->idx());
348  continue;
349  }
350  }
351  }
352  }
353 
354  return halfedges;
355 }
356 
357 //=========================================================
358 
360 void MeshObjectSelectionPlugin::colorizeHalfedgeSelection(int objectId, int r, int g, int b, int a) {
361 
362  BaseObjectData* object;
363  if (! PluginFunctions::getObject(objectId,object)) {
364  emit log(LOGERR,"colorizeHalfedgeSelection: unable to get object");
365  return;
366  }
367 
368  if (object->dataType() == DATA_TRIANGLE_MESH) {
370  } else if (object->dataType() == DATA_POLY_MESH) {
372  } else {
373  emit log(LOGERR,"colorizeHalfedgeSelection: Unsupported object Type");
374  return;
375  }
376 
377  emit scriptInfo("colorizeHalfedgeSelection(ObjectId(" + QString::number(objectId) + "), "
378  + QString::number(r) + ", " + QString::number(g) + ", " + QString::number(b) + ")");
379 
380  emit updatedObject(object->id(), UPDATE_COLOR);
381 }
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:65
void unselectHalfedges(int objectId, IdList _vertexList)
Unselect given Halfedges.
Handle for a halfedge entity.
Definition: Handles.hh:127
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
void selectAllHalfedges(int objectId)
Select all Halfedges.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
void invertHalfedgeSelection(int objectId)
Unselect all Halfedges.
int id() const
Definition: BaseObject.cc:190
MeshT * mesh()
return a pointer to the mesh
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:181
Kernel::VertexOHalfedgeIter VertexOHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:163
IdList convertHalfedgesToVertexPairs(int _id, const IdList &_halfedges)
Convert halfedge ids to vertex pairs.
void selectBoundaryHalfedges(int objectId)
Select boundary edges.
Functions for selection on a mesh.
void clearHalfedgeSelection(int objectId)
Invert the current edge selection.
IdList convertVertexPairsToHalfedges(int _id, const IdList &_vertices)
Inverse of function above.
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:67
IdList getHalfedgeSelection(int objectId)
Return a list of all selected edges.
void colorizeSelection(MeshT *_mesh, PrimitiveType _primitiveTypes, int _red, int _green, int _blue, int _alpha)
Colorize the selection.
bool selectElement(int _objectId, HandleT _handle, bool _fly_to_element)
set dihedral angle threshold for edge selection
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.
const UpdateType UPDATE_COLOR(UpdateTypeSet(1024))
Colors have changed.
const UpdateType UPDATE_SELECTION_EDGES(UpdateTypeSet(64))
Edge selection has changed.
bool selectHalfedge(int _objectId, int _idx, bool _fly_to_halfedge)
Select halfedge with id _idx and maybe fly to it.
void selectHalfedges(int objectId, IdList _vertexList)
Select given Halfedges.
void colorizeHalfedgeSelection(int objectId, int r, int g, int b, int a)
Colorize the edge selection.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136