Developer Documentation
MeshObjectSelectionPlugin.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 #include "MeshObjectSelectionPlugin.hh"
43 #include "widgets/ParameterWidget.hh"
44 
46 
47 
48 #include <QDesktopWidget>
49 #include <QColorDialog>
50 #include <QInputDialog>
51 
52 // Primitive type icons
53 #define VERTEX_TYPE "selection_vertex.png"
54 #define EDGE_TYPE "selection_edge.png"
55 #define HEDGE_TYPE "selection_halfedge.png"
56 #define FACE_TYPE "selection_face.png"
57 // =======================================
58 // Define operations
59 // =======================================
60 // General:
61 #define G_CLEAR_HANDLE "Clear Handle Region"
62 #define G_CLEAR_MODEL "Clear Modeling Region"
63 #define G_CONVERT "Convert Selection"
64 // Vertices:
65 #define V_SELECT_ALL "Select All Vertices"
66 #define V_CLEAR "Clear Vertex Selection"
67 #define V_INVERT "Invert Vertex Selection"
68 #define V_BOUNDARY "Select Boundary Vertices"
69 #define V_SHRINK "Shrink Vertex Selection"
70 #define V_GROW "Grow Vertex Selection"
71 #define V_DELETE "Delete selected Vertices"
72 #define V_COLORIZE "Colorize selected Vertices"
73 #define V_COPYSELECTION "Create mesh from Vertex Selection"
74 #define V_HANDLE "Set to Handle Region"
75 #define V_MODELING "Set to Modeling Region"
76 #define V_LOAD_FLIPPER "Load Flipper Selection"
77 // Edges
78 #define E_SELECT_ALL "Select All Edges"
79 #define E_CLEAR "Clear Edge Selection"
80 #define E_INVERT "Invert Edge Selection"
81 #define E_DELETE "Delete selected Edges"
82 #define E_BOUNDARY "Select Boundary Edges"
83 #define E_COLORIZE "Colorize selected Edges"
84 #define E_COPYSELECTION "Create mesh from Edge Selection"
85 #define E_TRACE_PATH "Trace Edge Path"
86 
87 // Halfedges
88 #define HE_SELECT_ALL "Select All Halfedges"
89 #define HE_CLEAR "Clear Halfedge Selection"
90 #define HE_INVERT "Invert Halfedge Selection"
91 #define HE_BOUNDARY "Select Boundary Halfedges"
92 #define HE_COLORIZE "Colorize selected Halfedges"
93 // Faces
94 #define F_SELECT_ALL "Select All Faces"
95 #define F_CLEAR "Clear Face Selection"
96 #define F_INVERT "Invert Face Selection"
97 #define F_DELETE "Delete selected Faces"
98 #define F_BOUNDARY "Select Boundary Faces"
99 #define F_SHRINK "Shrink Face Selection"
100 #define F_GROW "Grow Face Selection"
101 #define F_COLORIZE "Colorize selected Faces"
102 #define F_COPYSELECTION "Create mesh from Face Selection"
103 
104 //Colorize
105 #define C_SELECTIONCOLOR "Selection Color"
106 #define C_FEATURECOLOR "Feature Color"
107 #define C_HANDLECOLOR "Handle Color"
108 #define C_AREACOLOR "Area Color"
109 
112 vertexType_(0),
113 edgeType_(0),
114 halfedgeType_(0),
115 faceType_(0),
116 allSupportedTypes_(0u),
117 conversionDialog_(0),
118 parameterWidget_(nullptr),
119 colorButtonSelection_(0),
120 colorButtonArea_(0),
121 colorButtonHandle_(0),
122 colorButtonFeature_(0),
123 dihedral_angle_threshold_(0.0),
124 max_angle_( 2*M_PI)
125 {
126 }
127 
129 
130  delete conversionDialog_;
131  delete parameterWidget_;
132 }
133 
134 void MeshObjectSelectionPlugin::initializePlugin() {
135 
136  // Tell core about all scriptable slots
138 
139  // Create conversion dialog
140  if(!OpenFlipper::Options::nogui()) {
142  conversionDialog_->hide();
143  connect(conversionDialog_->convertButton, SIGNAL(clicked()), this, SLOT(conversionRequested()));
144  // Fill in combo boxes
145  conversionDialog_->convertFromBox->addItems(
146  QString("Vertex Selection;Edge Selection;Halfedge Selection;Face Selection;" \
147  "Feature Vertices;Feature Edges;Feature Faces;Handle Region;Modeling Region").split(";"));
148  conversionDialog_->convertToBox->addItems(
149  QString("Vertex Selection;Edge Selection;Halfedge Selection;Face Selection;" \
150  "Feature Vertices;Feature Edges;Feature Faces;Handle Region;Modeling Region").split(";"));
151 
152  parameterWidget_ = new ParameterWidget(nullptr);
153 
154  }
155 }
156 
157 void MeshObjectSelectionPlugin::pluginsInitialized() {
158  // Create new selection environment for mesh objects
159  // and register mesh types tri- and polymeshes for
160  // the environment.
161 
162  QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
163 
164  emit addSelectionEnvironment("Mesh Object Selections", "Select mesh object primitives such as vertices, (half-)edges and faces.",
165  iconPath + "selections.png", environmentHandle_);
166 
167  // Register mesh object types
168  emit registerType(environmentHandle_, DATA_POLY_MESH);
169  emit registerType(environmentHandle_, DATA_TRIANGLE_MESH);
170 
171  // Register mesh primitive types
172  emit addPrimitiveType(environmentHandle_, "Select Vertices", iconPath + VERTEX_TYPE, vertexType_);
173  emit addPrimitiveType(environmentHandle_, "Select Edges", iconPath + EDGE_TYPE, edgeType_);
174  emit addPrimitiveType(environmentHandle_, "Select Halfedges", iconPath + HEDGE_TYPE, halfedgeType_);
175  emit addPrimitiveType(environmentHandle_, "Select Faces", iconPath + FACE_TYPE, faceType_);
176 
177  // Combine all supported types
179 
180  // Determine, which selection modes are requested
181  emit showToggleSelectionMode(environmentHandle_, true, allSupportedTypes_);
182  emit showSphereSelectionMode(environmentHandle_, true, allSupportedTypes_);
183 
184  emit showLassoSelectionMode(environmentHandle_, true, allSupportedTypes_);
185  emit showVolumeLassoSelectionMode(environmentHandle_, true, allSupportedTypes_);
186 
187  emit showFloodFillSelectionMode(environmentHandle_, true, allSupportedTypes_);
188  emit showComponentsSelectionMode(environmentHandle_, true, allSupportedTypes_);
189  emit showClosestBoundarySelectionMode(environmentHandle_, true, allSupportedTypes_);
190 
191  // Define general operations
192  QStringList generalOperations;
193  generalOperations.append(G_CLEAR_HANDLE);
194  generalOperations.append(G_CLEAR_MODEL);
195  generalOperations.append(G_CONVERT);
196 
197  // Define vertex operations
198  QStringList vertexOperations;
199  vertexOperations.append(V_SELECT_ALL);
200  vertexOperations.append(V_CLEAR);
201  vertexOperations.append(V_INVERT);
202  vertexOperations.append(V_BOUNDARY);
203  vertexOperations.append(V_SHRINK);
204  vertexOperations.append(V_GROW);
205  vertexOperations.append(V_DELETE);
206  vertexOperations.append(V_COLORIZE);
207  vertexOperations.append(V_COPYSELECTION);
208  vertexOperations.append(V_HANDLE);
209  vertexOperations.append(V_MODELING);
210  vertexOperations.append(V_LOAD_FLIPPER);
211 
212  // Define edge operations
213  QStringList edgeOperations;
214  edgeOperations.append(E_SELECT_ALL);
215  edgeOperations.append(E_CLEAR);
216  edgeOperations.append(E_INVERT);
217  edgeOperations.append(E_DELETE);
218  edgeOperations.append(E_BOUNDARY);
219  edgeOperations.append(E_COLORIZE);
220  edgeOperations.append(E_COPYSELECTION);
221  edgeOperations.append(E_TRACE_PATH);
222 
223  // Define halfedge operations
224  QStringList hedgeOperations;
225  hedgeOperations.append(HE_SELECT_ALL);
226  hedgeOperations.append(HE_CLEAR);
227  hedgeOperations.append(HE_INVERT);
228  hedgeOperations.append(HE_BOUNDARY);
229  hedgeOperations.append(HE_COLORIZE);
230 
231  // Define face operations
232  QStringList faceOperations;
233  faceOperations.append(F_SELECT_ALL);
234  faceOperations.append(F_CLEAR);
235  faceOperations.append(F_INVERT);
236  faceOperations.append(F_DELETE);
237  faceOperations.append(F_BOUNDARY);
238  faceOperations.append(F_SHRINK);
239  faceOperations.append(F_GROW);
240  faceOperations.append(F_COLORIZE);
241  faceOperations.append(F_COPYSELECTION);
242 
243  // Define colorize operations
244  QStringList colorOperations;
245  colorOperations.append(C_SELECTIONCOLOR);
246  colorOperations.append(C_FEATURECOLOR);
247  colorOperations.append(C_AREACOLOR);
248  colorOperations.append(C_HANDLECOLOR);
249 
250  emit addSelectionOperations(environmentHandle_, generalOperations, "Selection Operations");
251  emit addSelectionOperations(environmentHandle_, vertexOperations, "Vertex Operations", vertexType_);
252  emit addSelectionOperations(environmentHandle_, edgeOperations, "Edge Operations", edgeType_);
253  emit addSelectionOperations(environmentHandle_, hedgeOperations, "Halfedge Operations", halfedgeType_);
254  emit addSelectionOperations(environmentHandle_, faceOperations, "Face Operations", faceType_);
255  emit addSelectionOperations(environmentHandle_, colorOperations, "Highlight Operations");
256 
257  if(!OpenFlipper::Options::nogui())
258  emit addSelectionParameters(environmentHandle_, parameterWidget_, "Selection Parameters");
259 
260  // Register key shortcuts:
261 
262  // Select (a)ll
263  emit registerKeyShortcut(Qt::Key_A, Qt::ControlModifier);
264  // (C)lear selection (Only current selection)
265  emit registerKeyShortcut(Qt::Key_C, Qt::NoModifier);
266  // (C)lear all selections
267  emit registerKeyShortcut(Qt::Key_C, Qt::ShiftModifier);
268  // (I)nvert selection
269  emit registerKeyShortcut(Qt::Key_I, Qt::NoModifier);
270  // Delete selected entities
271  emit registerKeyShortcut(Qt::Key_Delete, Qt::NoModifier);
272  // Select a vertex by ID
273  emit registerKeyShortcut(Qt::Key_V, Qt::NoModifier);
274  // Select a halfedge by ID
275  emit registerKeyShortcut(Qt::Key_H, Qt::NoModifier);
276  // Select a edge by ID
277  emit registerKeyShortcut(Qt::Key_E, Qt::NoModifier);
278  // Select a face by ID
279  emit registerKeyShortcut(Qt::Key_F, Qt::NoModifier);
280 
281  // load default Color values
282  std::string statusStr = OpenFlipperQSettings().value("SelectionMeshObject/StatusColor",QString()).toString().toStdString();
283  std::string handleStr = OpenFlipperQSettings().value("SelectionMeshObject/HandleColor",QString()).toString().toStdString();
284  std::string featureStr = OpenFlipperQSettings().value("SelectionMeshObject/FeatureColor",QString()).toString().toStdString();
285  std::string areaStr = OpenFlipperQSettings().value("SelectionMeshObject/AreaColor",QString()).toString().toStdString();
286  if (statusStr.empty() || handleStr.empty() || featureStr.empty() || areaStr.empty())
287  {
289  }
290  else
291  {
292  std::stringstream sstream;
293 
294  sstream.str(statusStr);
295  sstream >> statusColor_;
296 
297  sstream.str("");
298  sstream.clear();
299  sstream.str(handleStr);
300  sstream >> handleColor_;
301 
302  sstream.str("");
303  sstream.clear();
304  sstream.str(featureStr);
305  sstream >> featureColor_;
306 
307  sstream.str("");
308  sstream.clear();
309  sstream.str(areaStr);
310  sstream >> areaColor_;
311  updateColorValues(); //update GUI
312  }
313 
314 }
315 
317 
318  emit setSlotDescription("selectVertices(int,IdList)", tr("Select the specified vertices"),
319  QString("objectId,vertexList").split(","), QString("Id of object,List of vertices").split(","));
320  emit setSlotDescription("unselectVertices(int,IdList)", tr("Unselect the specified vertices"),
321  QString("objectId,vertexList").split(","), QString("Id of object,List of vertices").split(","));
322  emit setSlotDescription("selectAllVertices(int)", tr("Select all vertices of an object"),
323  QStringList("objectId"), QStringList("Id of object"));
324  emit setSlotDescription("clearVertexSelection(int)", tr("Clear vertex selection of an object"),
325  QStringList("objectId"), QStringList("Id of an object"));
326  emit setSlotDescription("invertVertexSelection(int)", tr("Invert vertex selection of an object"),
327  QStringList("objectId"), QStringList("Id of an object"));
328  emit setSlotDescription("selectBoundaryVertices(int)", tr("Select all boundary vertices of an object"),
329  QStringList("objectId"), QStringList("Id of an object"));
330  emit setSlotDescription("selectClosestBoundaryVertices(int,int)", tr("Select boundary vertices closest to a specific vertex"),
331  QString("objectId,vertexId").split(","), QString("Id of an object,Id of closest vertex").split(","));
332  emit setSlotDescription("shrinkVertexSelection(int)", tr("Shrink vertex selection by outer selection ring"),
333  QStringList("objectId"), QStringList("Id of an object"));
334  emit setSlotDescription("growVertexSelection(int)", tr("Grow vertex selection by an-ring of selection"),
335  QStringList("objectId"), QStringList("Id of an object"));
336  emit setSlotDescription("deleteVertexSelection(int)", tr("Delete selected vertices"),
337  QStringList("objectId"), QStringList("Id of an object"));
338  emit setSlotDescription("createMeshFromVertexSelection(int)", tr("Take vertex selection and create a new mesh from it"),
339  QString("objectId").split(","), QString("Id of an object where the selection should be used to create a new mesh").split(","));
340 
341  emit setSlotDescription("selectVerticesByValue(int,QString,bool,double)", tr("Select vertices based on the value of their component"),
342  QString("objectId,component,greater,value").split(","),
343  QString("Id of an object where the selection should be used to create a new mesh,component specification: \"x\" or \"y\" or \"z\" ,true: select vertex if component greater than value; false: select if component less than value ,value to test").split(","));
344 
345  emit setSlotDescription("colorizeVertexSelection(int,int,int,int)", tr("Colorize the selected vertices"),
346  QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
347  emit setSlotDescription("selectHandleVertices(int,IdList)", tr("Add specified vertices to handle area"),
348  QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
349  emit setSlotDescription("unselectHandleVertices(int,IdList)", tr("Remove specified vertices from handle area"),
350  QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
351  emit setSlotDescription("clearHandleVertices(int)", tr("Clear handle area"),
352  QStringList("objectId"), QStringList("Id of an object"));
353  emit setSlotDescription("setAllHandleVertices(int)", tr("Add all vertices of an object to handle area"),
354  QStringList("objectId"), QStringList("Id of an object"));
355  emit setSlotDescription("selectModelingVertices(int,IdList)", tr("Add specified vertices to modeling area"),
356  QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
357  emit setSlotDescription("unselectModelingVertices(int,IdList)", tr("Remove specified vertices to modeling area"),
358  QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
359  emit setSlotDescription("clearModelingVertices(int)", tr("Clear modeling area"),
360  QStringList("objectId"), QStringList("Id of an object"));
361  emit setSlotDescription("setAllModelingVertices(int)", tr("Add al vertices of an object to modeling area"),
362  QStringList("objectId"), QStringList("Id of an object"));
363 
364  emit setSlotDescription("loadSelection(int,QString)", tr("Load selection from selection file"),
365  QString("objectId,filename").split(","), QString("Id of an object,Selection file").split(","));
366 
367  emit setSlotDescription("loadFlipperModelingSelection(int,QString)", tr("Load selection from Flipper selection file"),
368  QString("objectId,filename").split(","), QString("Id of an object,Flipper selection file").split(","));
369  emit setSlotDescription("saveFlipperModelingSelection(int,QString)", tr("Save selection into Flipper selection file"),
370  QString("objectId,filename").split(","), QString("Id of an object,Flipper selection file").split(","));
371 
372  emit setSlotDescription("selectEdges(int,IdList)", tr("Select the specified edges"),
373  QString("objectId,edgeList").split(","), QString("Id of an object,List of edges").split(","));
374  emit setSlotDescription("unselectEdges(int,IdList)", tr("Unselect the specified edges"),
375  QString("objectId,edgeList").split(","), QString("Id of an object,List of edges").split(","));
376  emit setSlotDescription("selectAllEdges(int)", tr("Select all edges of an object"),
377  QStringList("objectId"), QStringList("Id of an object"));
378  emit setSlotDescription("invertEdgeSelection(int)", tr("Invert edge selection of an object"),
379  QStringList("objectId"), QStringList("Id of an object"));
380  emit setSlotDescription("clearEdgeSelection(int)", tr("Clear edge selection of an object"),
381  QStringList("objectId"), QStringList("Id of an object"));
382  emit setSlotDescription("selectBoundaryEdges(int)", tr("Select all boundary edges of an object"),
383  QStringList("objectId"), QStringList("Id of an object"));
384 
385  emit setSlotDescription("colorizeEdgeSelection(int,int,int,int)", tr("Colorize the selected edges"),
386  QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
387  emit setSlotDescription("createMeshFromEdgeSelection(int)", tr("Take edge selection and create a new mesh from it"),
388  QString("objectId").split(","), QString("Id of an object where the selection should be used to create a new mesh").split(","));
389 
390  emit setSlotDescription("selectHalfedges(int,IdList)", tr("Select the specified halfedges"),
391  QString("objectId,halfedgeList").split(","), QString("Id of an object,List of halfedges").split(","));
392  emit setSlotDescription("unselectHalfedges(int,IdList)", tr("Unselect the specified halfedges"),
393  QString("objectId,halfedgeList").split(","), QString("Id of an object,List of halfedges").split(","));
394  emit setSlotDescription("selectAllHalfedges(int)", tr("Select all halfedges of an object"),
395  QStringList("objectId"), QStringList("Id of an object"));
396  emit setSlotDescription("invertHalfedgeSelection(int)", tr("Invert halfedge selection of an object"),
397  QStringList("objectId"), QStringList("Id of an object"));
398  emit setSlotDescription("clearHalfedgeSelection(int)", tr("Clear halfedge selection of an object"),
399  QStringList("objectId"), QStringList("Id of an object"));
400  emit setSlotDescription("selectBoundaryHalfedges(int)", tr("Select all boundary halfedges of an object"),
401  QStringList("objectId"), QStringList("Id of an object"));
402 
403  emit setSlotDescription("colorizeHalfedgeSelection(int,int,int,int)", tr("Colorize the selected halfedges"),
404  QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
405 
406  emit setSlotDescription("selectFaces(int,IdList)", tr("Select the specified faces"),
407  QString("objectId,faceList").split(","), QString("Id of an object,List of faces").split(","));
408  emit setSlotDescription("unselectFaces(int,IdList)", tr("Unselect the specified faces"),
409  QString("objectId,faceList").split(","), QString("Id of an object,List of faces").split(","));
410  emit setSlotDescription("selectAllFaces(int)", tr("Select all vertices of an object"),
411  QStringList("objectId"), QStringList("Id of an object"));
412  emit setSlotDescription("clearFaceSelection(int)", tr("Clear face selection of an object"),
413  QStringList("objectId"), QStringList("Id of an object"));
414  emit setSlotDescription("invertFaceSelection(int)", tr("Invert face selection of an object"),
415  QStringList("objectId"), QStringList("Id of an object"));
416  emit setSlotDescription("selectBoundaryFaces(int)", tr("Select all boundary faces of an object"),
417  QStringList("objectId"), QStringList("Id of an object"));
418  emit setSlotDescription("shrinkFaceSelection(int)", tr("Shrink face selection by outer face ring of selection"),
419  QStringList("objectId"), QStringList("Id of an object"));
420  emit setSlotDescription("growFaceSelection(int)", tr("Grow face selection by an-ring of faces around selection"),
421  QStringList("objectId"), QStringList("Id of an object"));
422  emit setSlotDescription("colorizeFaceSelection(int,int,int,int)", tr("Colorize the selected faces"),
423  QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
424 
425  emit setSlotDescription("createMeshFromFaceSelection(int)", tr("Take face selection and create a new mesh from it"),
426  QString("objectId").split(","), QString("Id of an object where the selection should be used to create a new mesh").split(","));
427 
428 
429  QString conversionStrings = tr(" Possible strings:\n"
430  "- Vertex/Edge/Halfedge/Face Selection\n"
431  "- Model/Handle Region\n"
432  "- Feature Vertices/Edges/Faces");
433 
434  emit setSlotDescription("convertSelection(int,QString,QString,bool)", tr("Convert the selection on given object. Conversion must be given as strings.")+conversionStrings ,
435  QString("objectId,from,to,deselect").split(","), QString("Id of an object,string of selection which will be converted,resulting selection or area,deselect selection after conversion").split(","));
436 
437  emit setSlotDescription("conversion(QString,QString,bool)", tr("Convert selection on all target Objects.")+conversionStrings,
438  QString("from,to,deselect").split(","), QString("string of selection which will be converted,resulting selection region or feature,deselect selection after conversion").split(","));
439 
440  emit setSlotDescription("convertEdgesToVertexPairs(int,IdList)", tr("Convert edge ids to vertex pair ids. Returns vertex Idlist."),
441  QString("objectId, edgeIds").split(","), QString("Id of an object, Ids of edges").split(","));
442  emit setSlotDescription("convertHalfedgesToVertexPairs(int,IdList)", tr("Convert halfedge ids to vertex pair ids. Returns vertex Idlist."),
443  QString("objectId, halfedgeIds").split(","), QString("Id of an object, Ids of halfedges").split(","));
444 
445  emit setSlotDescription("convertVertexPairsToHalfedges(int,IdList)", tr("Convert vertex pair ids to halfedge ids. Returns halfedge Idlist."),
446  QString("objectId, vertexIds").split(","), QString("Id of an object, Ids of paired vertices").split(","));
447  emit setSlotDescription("convertVertexPairsToEdges(int,IdList)", tr("Convert vertex pair ids to edge ids. Returns edge Idlist."),
448  QString("objectId, vertexIds").split(","), QString("Id of an object, Ids of paired vertices").split(","));
449 }
450 
452 
453  SelectionInterface::PrimitiveType type = 0u;
454  emit getActivePrimitiveType(type);
455 
456  if((type & allSupportedTypes_) == 0)
457  return;
458 
459  // Test if operation should be applied to target objects only
460  bool targetsOnly = false;
461  emit targetObjectsOnly(targetsOnly);
464 
465  if(_operation == G_CLEAR_HANDLE) {
466  // Clear handle region
467  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
468  o_it != PluginFunctions::objectsEnd(); ++o_it) {
469  if (o_it->visible())
470  clearHandleVertices(o_it->id());
471  }
472  } else if(_operation == G_CLEAR_MODEL) {
473  // Clear modeling region
474  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
475  o_it != PluginFunctions::objectsEnd(); ++o_it) {
476  if (o_it->visible())
477  clearModelingVertices(o_it->id());
478  }
479  } else if(_operation == G_CONVERT) {
480  // Convert vertex selection
481  if(!OpenFlipper::Options::nogui())
482  conversionDialog_->show();
483  } else if(_operation == V_SELECT_ALL) {
484  // Select all vertices
485  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
486  o_it != PluginFunctions::objectsEnd(); ++o_it) {
487  if (o_it->visible())
488  selectAllVertices(o_it->id());
489  }
490  } else if(_operation == V_CLEAR) {
491  // Clear vertex selection
492  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
493  o_it != PluginFunctions::objectsEnd(); ++o_it) {
494  if (o_it->visible())
495  clearVertexSelection(o_it->id());
496  }
497  } else if(_operation == V_INVERT) {
498  // Invert vertex selection
499  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
500  o_it != PluginFunctions::objectsEnd(); ++o_it) {
501  if (o_it->visible())
502  invertVertexSelection(o_it->id());
503  }
504  } else if(_operation == V_BOUNDARY) {
505  // Select boundary vertices
506  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
507  o_it != PluginFunctions::objectsEnd(); ++o_it) {
508  if (o_it->visible())
509  selectBoundaryVertices(o_it->id());
510  }
511  } else if(_operation == V_SHRINK) {
512  // Shrink vertex selection
513  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
514  o_it != PluginFunctions::objectsEnd(); ++o_it) {
515  if (o_it->visible())
516  shrinkVertexSelection(o_it->id());
517  }
518  } else if(_operation == V_GROW) {
519  // Grow vertex selection
520  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
521  o_it != PluginFunctions::objectsEnd(); ++o_it) {
522  if (o_it->visible())
523  growVertexSelection(o_it->id());
524  }
525  } else if(_operation == V_DELETE) {
526  // Delete vertex selection
527  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
528  o_it != PluginFunctions::objectsEnd(); ++o_it) {
529  if (o_it->visible()){
530  deleteVertexSelection(o_it->id());
531  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
532  emit createBackup(o_it->id(), "Delete Vertices", UPDATE_GEOMETRY);
533  }
534  }
535  } else if(_operation == V_COLORIZE) {
536  // Colorize vertex selection
537  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
538  o_it != PluginFunctions::objectsEnd(); ++o_it) {
539  if (o_it->visible()) {
540  setColorForSelection(o_it->id(), vertexType_);
541  }
542  }
543  } else if(_operation == V_COPYSELECTION) {
544  // Copy vertex selection
545  std::vector<int> objects;
546  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
547  o_it != PluginFunctions::objectsEnd(); ++o_it) {
548  if (o_it->visible()) {
549  objects.push_back(o_it->id());
550  }
551  }
552 
553  for ( unsigned int i = 0 ; i < objects.size() ; ++i)
555 
556  } else if(_operation == V_HANDLE) {
557  // Set vertex selection to be handle region
558  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
559  o_it != PluginFunctions::objectsEnd(); ++o_it) {
560  if (o_it->visible()) {
561  std::vector<int> ids = getVertexSelection(o_it->id());
562  selectHandleVertices(o_it->id(), ids);
563  clearVertexSelection(o_it->id());
564  }
565  }
566  } else if(_operation == V_MODELING) {
567  // Set vertex selection to be modeling
568  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
569  o_it != PluginFunctions::objectsEnd(); ++o_it) {
570  if (o_it->visible()) {
571  std::vector<int> ids = getVertexSelection(o_it->id());
572  selectModelingVertices(o_it->id(), ids);
573  clearVertexSelection(o_it->id());
574  }
575  }
576  } else if(_operation == V_LOAD_FLIPPER) {
577  // Load Flipper selection file
578  QString fileName = QFileDialog::getOpenFileName(0,
579  tr("Open Flipper Selection File"), OpenFlipper::Options::dataDirStr(),
580  tr("Flipper Selection Files (*.sel)"));
581  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
582  o_it != PluginFunctions::objectsEnd(); ++o_it) {
583  if (o_it->visible()) {
584  loadFlipperModelingSelection(o_it->id(), fileName);
585  }
586  }
587  } else if(_operation == E_SELECT_ALL) {
588  // Select all edges
589  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
590  o_it != PluginFunctions::objectsEnd(); ++o_it) {
591  if (o_it->visible())
592  selectAllEdges(o_it->id());
593  }
594  } else if(_operation == E_CLEAR) {
595  // Clear edge selection
596  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
597  o_it != PluginFunctions::objectsEnd(); ++o_it) {
598  if (o_it->visible())
599  clearEdgeSelection(o_it->id());
600  }
601  } else if(_operation == E_INVERT) {
602  // Invert edge selection
603  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
604  o_it != PluginFunctions::objectsEnd(); ++o_it) {
605  if (o_it->visible())
606  invertEdgeSelection(o_it->id());
607  }
608  } else if(_operation == E_DELETE) {
609  // Delete edge selection
610  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
611  o_it != PluginFunctions::objectsEnd(); ++o_it) {
612  if (o_it->visible())
613  deleteEdgeSelection(o_it->id());
614  }
615  } else if(_operation == E_BOUNDARY) {
616  // Select boundary edges
617  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
618  o_it != PluginFunctions::objectsEnd(); ++o_it) {
619  if (o_it->visible())
620  selectBoundaryEdges(o_it->id());
621  }
622  } else if(_operation == E_COLORIZE) {
623  // Colorize edge selection
624  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
625  o_it != PluginFunctions::objectsEnd(); ++o_it) {
626  if (o_it->visible()) {
627  setColorForSelection(o_it->id(), edgeType_);
628  }
629  }
630  } else if(_operation == E_COPYSELECTION) {
631  // Copy edge selection
632  std::vector<int> objects;
633  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
634  o_it != PluginFunctions::objectsEnd(); ++o_it) {
635  if (o_it->visible()) {
636  objects.push_back(o_it->id());
637  }
638  }
639 
640  for ( unsigned int i = 0 ; i < objects.size() ; ++i)
642 
643  } else if (_operation == E_TRACE_PATH) {
644  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
645  o_it != PluginFunctions::objectsEnd(); ++o_it) {
646  if (o_it->visible()) {
647  traceEdgePath(o_it->id(), .9);
648  }
649  }
650  } else if(_operation == HE_SELECT_ALL) {
651  // Select all edges
652  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
653  o_it != PluginFunctions::objectsEnd(); ++o_it) {
654  if (o_it->visible())
655  selectAllHalfedges(o_it->id());
656  }
657  } else if(_operation == HE_CLEAR) {
658  // Clear edge selection
659  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
660  o_it != PluginFunctions::objectsEnd(); ++o_it) {
661  if (o_it->visible())
662  clearHalfedgeSelection(o_it->id());
663  }
664  } else if(_operation == HE_INVERT) {
665  // Invert edge selection
666  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
667  o_it != PluginFunctions::objectsEnd(); ++o_it) {
668  if (o_it->visible())
669  invertHalfedgeSelection(o_it->id());
670  }
671  } else if(_operation == HE_BOUNDARY) {
672  // Select boundary edges
673  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
674  o_it != PluginFunctions::objectsEnd(); ++o_it) {
675  if (o_it->visible())
676  selectBoundaryHalfedges(o_it->id());
677  }
678  } else if(_operation == HE_COLORIZE) {
679  // Colorize halfedge selection
680  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
681  o_it != PluginFunctions::objectsEnd(); ++o_it) {
682  if (o_it->visible()) {
683  setColorForSelection(o_it->id(), halfedgeType_);
684  }
685  }
686  } else if(_operation == F_SELECT_ALL) {
687  // Select all faces
688  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
689  o_it != PluginFunctions::objectsEnd(); ++o_it) {
690  if (o_it->visible())
691  selectAllFaces(o_it->id());
692  }
693  } else if(_operation == F_CLEAR) {
694  // Clear face selection
695  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
696  o_it != PluginFunctions::objectsEnd(); ++o_it) {
697  if (o_it->visible())
698  clearFaceSelection(o_it->id());
699  }
700  } else if(_operation == F_INVERT) {
701  // Invert face selection
702  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
703  o_it != PluginFunctions::objectsEnd(); ++o_it) {
704  if (o_it->visible())
705  invertFaceSelection(o_it->id());
706  }
707  } else if(_operation == F_DELETE) {
708  // Delete face selection
709  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
710  o_it != PluginFunctions::objectsEnd(); ++o_it) {
711  if (o_it->visible())
712  deleteFaceSelection(o_it->id());
713  }
714  } else if(_operation == F_BOUNDARY) {
715  // Select boundary faces
716  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
717  o_it != PluginFunctions::objectsEnd(); ++o_it) {
718  if (o_it->visible())
719  selectBoundaryFaces(o_it->id());
720  }
721  } else if(_operation == F_SHRINK) {
722  // Shrink face selection
723  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
724  o_it != PluginFunctions::objectsEnd(); ++o_it) {
725  if (o_it->visible())
726  shrinkFaceSelection(o_it->id());
727  }
728  } else if(_operation == F_GROW) {
729  // Grow face selection
730  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
731  o_it != PluginFunctions::objectsEnd(); ++o_it) {
732  if (o_it->visible())
733  growFaceSelection(o_it->id());
734  }
735  } else if(_operation == F_COLORIZE) {
736  // Colorize face selection
737  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
738  o_it != PluginFunctions::objectsEnd(); ++o_it) {
739  if (o_it->visible()) {
740  setColorForSelection(o_it->id(), faceType_);
741  }
742  }
743  } else if(_operation == F_COPYSELECTION) {
744  // Copy face selection
745  std::vector<int> objects;
746  for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
747  o_it != PluginFunctions::objectsEnd(); ++o_it) {
748  if (o_it->visible()) {
749  objects.push_back(o_it->id());
750  }
751  }
752 
753  for ( unsigned int i = 0 ; i < objects.size() ; ++i)
755  } else if(_operation == C_SELECTIONCOLOR) {
756  QColor newColor = QColorDialog::getColor(QColor::fromRgbF(statusColor_[0],statusColor_[1],statusColor_[2],statusColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
757  if (newColor.isValid())
758  {
760  o_it != PluginFunctions::objectsEnd(); ++o_it) {
761  PolyMeshObject* poly = 0;
762  PluginFunctions::getObject(o_it->id(),poly);
763  poly->setSelectionColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
764  }
766  o_it != PluginFunctions::objectsEnd(); ++o_it) {
767  TriMeshObject* tri = 0;
768  PluginFunctions::getObject(o_it->id(),tri);
769  tri->setSelectionColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
770  }
771  emit updateView();
772  }
773 
774  }else if(_operation == C_FEATURECOLOR) {
775  QColor newColor = QColorDialog::getColor(QColor::fromRgbF(featureColor_[0],featureColor_[1],featureColor_[2],featureColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
776  if (newColor.isValid())
777  {
779  o_it != PluginFunctions::objectsEnd(); ++o_it) {
780  PolyMeshObject* poly = 0;
781  PluginFunctions::getObject(o_it->id(),poly);
782  poly->setFeatureColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
783  }
785  o_it != PluginFunctions::objectsEnd(); ++o_it) {
786  TriMeshObject* tri = 0;
787  PluginFunctions::getObject(o_it->id(),tri);
788  tri->setFeatureColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
789  }
790  emit updateView();
791  }
792 
793  }else if(_operation == C_HANDLECOLOR) {
794  QColor newColor = QColorDialog::getColor(QColor::fromRgbF(handleColor_[0],handleColor_[1],handleColor_[2],handleColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
795  if (newColor.isValid())
796  {
798  o_it != PluginFunctions::objectsEnd(); ++o_it) {
799  PolyMeshObject* poly = 0;
800  PluginFunctions::getObject(o_it->id(),poly);
801  poly->setHandleColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
802  }
804  o_it != PluginFunctions::objectsEnd(); ++o_it) {
805  TriMeshObject* tri = 0;
806  PluginFunctions::getObject(o_it->id(),tri);
807  tri->setHandleColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
808  }
809  emit updateView();
810  }
811 
812  }else if(_operation == C_AREACOLOR) {
813  QColor newColor = QColorDialog::getColor(QColor::fromRgbF(areaColor_[0],areaColor_[1],areaColor_[2],areaColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
814  if (newColor.isValid())
815  {
817  o_it != PluginFunctions::objectsEnd(); ++o_it) {
818  PolyMeshObject* poly = 0;
819  PluginFunctions::getObject(o_it->id(),poly);
820  poly->setAreaColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
821  }
823  o_it != PluginFunctions::objectsEnd(); ++o_it) {
824  TriMeshObject* tri = 0;
825  PluginFunctions::getObject(o_it->id(),tri);
826  tri->setAreaColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
827  }
828  emit updateView();
829  }
830 
831  }
832 }
833 
834 void MeshObjectSelectionPlugin::setColorForSelection(const int _objectId, const PrimitiveType _primitiveTypes) {
835 
836  QColor c = QColorDialog::getColor(Qt::red, 0, tr("Choose color"),QColorDialog::ShowAlphaChannel);
837 
838  if(c.isValid()) {
839  if(_primitiveTypes & vertexType_) {
840  // Vertex colorization
841  colorizeVertexSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
842  } else if (_primitiveTypes & edgeType_) {
843  // Edge colorization
844  colorizeEdgeSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
845  } else if (_primitiveTypes & halfedgeType_) {
846  // Edge colorization
847  colorizeHalfedgeSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
848  } else if (_primitiveTypes & faceType_) {
849  // Edge colorization
850  colorizeFaceSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
851  }
852  }
853 }
854 
856 
857  conversionDialog_->hide();
858 
859  QString from = conversionDialog_->convertFromBox->currentText();
860  QString to = conversionDialog_->convertToBox->currentText();
861 
862  if(from == to) return;
863 
864  bool deselect = true;
865  if(!OpenFlipper::Options::nogui()) {
866  deselect = conversionDialog_->deselect->isChecked();
867  }
868 
869  conversion(from, to, deselect);
870 }
871 
872 void MeshObjectSelectionPlugin::convertSelection(const int& _objectId ,const QString& _from, const QString& _to, bool _deselect) {
873  BaseObject* object = 0;
874 
875  PluginFunctions::getObject(_objectId,object);
876 
877  if ( object == 0 ) {
878  emit log(LOGERR,"Object not found in convertSelection");
879  return;
880  }
881 
882  if(_from == "Vertex Selection") {
883  if (_to == "Edge Selection") {
884  if(object->dataType() == DATA_TRIANGLE_MESH)
885  MeshSelection::convertVertexToEdgeSelection(PluginFunctions::triMesh(_objectId));
886  else if(object->dataType() == DATA_POLY_MESH)
887  MeshSelection::convertVertexToEdgeSelection(PluginFunctions::polyMesh(_objectId));
888  } else if (_to == "Halfedge Selection") {
889  if(object->dataType() == DATA_TRIANGLE_MESH)
890  MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::triMesh(_objectId));
891  else if(object->dataType() == DATA_POLY_MESH)
892  MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::polyMesh(_objectId));
893  } else if (_to == "Face Selection") {
894  if(object->dataType() == DATA_TRIANGLE_MESH)
895  MeshSelection::convertVertexToFaceSelection(PluginFunctions::triMesh(_objectId));
896  else if(object->dataType() == DATA_POLY_MESH)
897  MeshSelection::convertVertexToFaceSelection(PluginFunctions::polyMesh(_objectId));
898  } else if (_to == "Feature Vertices") {
899  if(object->dataType() == DATA_TRIANGLE_MESH)
900  MeshSelection::convertVertexSelectionToFeatureVertices(PluginFunctions::triMesh(_objectId));
901  else if(object->dataType() == DATA_POLY_MESH)
902  MeshSelection::convertVertexSelectionToFeatureVertices(PluginFunctions::polyMesh(_objectId));
903  } else if (_to == "Handle Region") {
904  selectHandleVertices(_objectId, getVertexSelection(_objectId));
905  } else if (_to == "Modeling Region") {
906  selectModelingVertices(_objectId, getVertexSelection(_objectId));
907  }
908 
909  if(_deselect) {
910  clearVertexSelection(_objectId);
911  }
912 
913  } else if (_from == "Edge Selection") {
914  if(_to == "Vertex Selection") {
915  if(object->dataType() == DATA_TRIANGLE_MESH)
916  MeshSelection::convertEdgeToVertexSelection(PluginFunctions::triMesh(_objectId));
917  else if(object->dataType() == DATA_POLY_MESH)
918  MeshSelection::convertEdgeToVertexSelection(PluginFunctions::polyMesh(_objectId));
919  } else if (_to == "Halfedge Selection") {
920  if(object->dataType() == DATA_TRIANGLE_MESH)
921  MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::triMesh(_objectId));
922  else if(object->dataType() == DATA_POLY_MESH)
923  MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::polyMesh(_objectId));
924  } else if (_to == "Face Selection") {
925  if(object->dataType() == DATA_TRIANGLE_MESH)
926  MeshSelection::convertEdgeToFaceSelection(PluginFunctions::triMesh(_objectId));
927  else if(object->dataType() == DATA_POLY_MESH)
928  MeshSelection::convertEdgeToFaceSelection(PluginFunctions::polyMesh(_objectId));
929  } else if (_to == "Feature Edges") {
930  if(object->dataType() == DATA_TRIANGLE_MESH)
931  MeshSelection::convertEdgeSelectionToFeatureEdges(PluginFunctions::triMesh(_objectId));
932  else if(object->dataType() == DATA_POLY_MESH)
933  MeshSelection::convertEdgeSelectionToFeatureEdges(PluginFunctions::polyMesh(_objectId));
934  } else if (_to == "Handle Region") {
935  if(object->dataType() == DATA_TRIANGLE_MESH) {
936  TriMesh* mesh = PluginFunctions::triMesh(_objectId);
937  std::vector<int> ids;
938  for(TriMesh::EdgeIter e_it = mesh->edges_begin(); e_it != mesh->edges_end(); ++e_it) {
939  if(mesh->status(*e_it).selected()) {
940  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 0)).idx());
941  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 1)).idx());
942  }
943  }
944  selectHandleVertices(_objectId, ids);
945  } else if(object->dataType() == DATA_POLY_MESH) {
946  PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
947  std::vector<int> ids;
948  for(PolyMesh::EdgeIter e_it = mesh->edges_begin(); e_it != mesh->edges_end(); ++e_it) {
949  if(mesh->status(*e_it).selected()) {
950  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 0)).idx());
951  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 1)).idx());
952  }
953  }
954  selectHandleVertices(_objectId, ids);
955  }
956  } else if (_to == "Modeling Region") {
957  if(object->dataType() == DATA_TRIANGLE_MESH) {
958  TriMesh* mesh = PluginFunctions::triMesh(_objectId);
959  std::vector<int> ids;
960  for(TriMesh::EdgeIter e_it = mesh->edges_begin(); e_it != mesh->edges_end(); ++e_it) {
961  if(mesh->status(*e_it).selected()) {
962  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 0)).idx());
963  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 1)).idx());
964  }
965  }
966  selectModelingVertices(_objectId, ids);
967  } else if(object->dataType() == DATA_POLY_MESH) {
968  PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
969  std::vector<int> ids;
970  for(PolyMesh::EdgeIter e_it = mesh->edges_begin(); e_it != mesh->edges_end(); ++e_it) {
971  if(mesh->status(*e_it).selected()) {
972  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 0)).idx());
973  ids.push_back(mesh->to_vertex_handle(mesh->halfedge_handle(*e_it, 1)).idx());
974  }
975  }
976  selectModelingVertices(_objectId, ids);
977  }
978  }
979 
980  if(_deselect) {
981  clearEdgeSelection(_objectId);
982  }
983  } else if (_from == "Halfedge Selection") {
984  if(_to == "Vertex Selection") {
985  if(object->dataType() == DATA_TRIANGLE_MESH)
986  MeshSelection::convertHalfedgeToVertexSelection(PluginFunctions::triMesh(_objectId));
987  else if(object->dataType() == DATA_POLY_MESH)
988  MeshSelection::convertHalfedgeToVertexSelection(PluginFunctions::polyMesh(_objectId));
989  } else if (_to == "Edge Selection") {
990  if(object->dataType() == DATA_TRIANGLE_MESH)
991  MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::triMesh(_objectId));
992  else if(object->dataType() == DATA_POLY_MESH)
993  MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::polyMesh(_objectId));
994  } else if (_to == "Face Selection") {
995  if(object->dataType() == DATA_TRIANGLE_MESH)
996  MeshSelection::convertHalfedgeToFaceSelection(PluginFunctions::triMesh(_objectId));
997  else if(object->dataType() == DATA_POLY_MESH)
998  MeshSelection::convertHalfedgeToFaceSelection(PluginFunctions::polyMesh(_objectId));
999  } else if (_to == "Handle Region") {
1000  if(object->dataType() == DATA_TRIANGLE_MESH) {
1001  TriMesh* mesh = PluginFunctions::triMesh(_objectId);
1002  std::vector<int> ids;
1003  for(TriMesh::HalfedgeIter h_it = mesh->halfedges_begin(); h_it != mesh->halfedges_end(); ++h_it) {
1004  if(mesh->status(*h_it).selected()) {
1005  ids.push_back(mesh->to_vertex_handle(*h_it).idx());
1006  ids.push_back(mesh->from_vertex_handle(*h_it).idx());
1007  }
1008  }
1009  selectHandleVertices(_objectId, ids);
1010  } else if(object->dataType() == DATA_POLY_MESH) {
1011  PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
1012  std::vector<int> ids;
1013  for(PolyMesh::HalfedgeIter h_it = mesh->halfedges_begin(); h_it != mesh->halfedges_end(); ++h_it) {
1014  if(mesh->status(*h_it).selected()) {
1015  ids.push_back(mesh->to_vertex_handle(*h_it).idx());
1016  ids.push_back(mesh->from_vertex_handle(*h_it).idx());
1017  }
1018  }
1019  selectHandleVertices(_objectId, ids);
1020  }
1021  } else if (_to == "Modeling Region") {
1022  if(object->dataType() == DATA_TRIANGLE_MESH) {
1023  TriMesh* mesh = PluginFunctions::triMesh(_objectId);
1024  std::vector<int> ids;
1025  for(TriMesh::HalfedgeIter h_it = mesh->halfedges_begin(); h_it != mesh->halfedges_end(); ++h_it) {
1026  if(mesh->status(*h_it).selected()) {
1027  ids.push_back(mesh->to_vertex_handle(*h_it).idx());
1028  ids.push_back(mesh->from_vertex_handle(*h_it).idx());
1029  }
1030  }
1031  selectModelingVertices(_objectId, ids);
1032  } else if(object->dataType() == DATA_POLY_MESH) {
1033  PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
1034  std::vector<int> ids;
1035  for(PolyMesh::HalfedgeIter h_it = mesh->halfedges_begin(); h_it != mesh->halfedges_end(); ++h_it) {
1036  if(mesh->status(*h_it).selected()) {
1037  ids.push_back(mesh->to_vertex_handle(*h_it).idx());
1038  ids.push_back(mesh->from_vertex_handle(*h_it).idx());
1039  }
1040  }
1041  selectModelingVertices(_objectId, ids);
1042  }
1043  }
1044 
1045  if(_deselect) {
1046  clearHalfedgeSelection(_objectId);
1047  }
1048  } else if (_from == "Face Selection") {
1049  if(_to == "Vertex Selection") {
1050  if(object->dataType() == DATA_TRIANGLE_MESH)
1051  MeshSelection::convertFaceToVertexSelection(PluginFunctions::triMesh(_objectId));
1052  else if(object->dataType() == DATA_POLY_MESH)
1053  MeshSelection::convertFaceToVertexSelection(PluginFunctions::polyMesh(_objectId));
1054  } else if (_to == "Edge Selection") {
1055  if(object->dataType() == DATA_TRIANGLE_MESH)
1056  MeshSelection::convertFaceToEdgeSelection(PluginFunctions::triMesh(_objectId));
1057  else if(object->dataType() == DATA_POLY_MESH)
1058  MeshSelection::convertFaceToEdgeSelection(PluginFunctions::polyMesh(_objectId));
1059  } else if (_to == "Feature Faces") {
1060  if(object->dataType() == DATA_TRIANGLE_MESH)
1061  MeshSelection::convertFaceSelectionToFeatureFaces(PluginFunctions::triMesh(_objectId));
1062  else if(object->dataType() == DATA_POLY_MESH)
1063  MeshSelection::convertFaceSelectionToFeatureFaces(PluginFunctions::polyMesh(_objectId));
1064  } else if (_to == "Halfedge Selection") {
1065  if(object->dataType() == DATA_TRIANGLE_MESH)
1066  MeshSelection::convertFaceToHalfedgeSelection(PluginFunctions::triMesh(_objectId));
1067  else if(object->dataType() == DATA_POLY_MESH)
1068  MeshSelection::convertFaceToHalfedgeSelection(PluginFunctions::polyMesh(_objectId));
1069  } else if (_to == "Handle Region") {
1070  if(object->dataType() == DATA_TRIANGLE_MESH) {
1071  TriMesh* mesh = PluginFunctions::triMesh(_objectId);
1072  std::vector<int> ids;
1073  for(TriMesh::FaceIter f_it = mesh->faces_begin(); f_it != mesh->faces_end(); ++f_it) {
1074  if(mesh->status(*f_it).selected()) {
1075  for(TriMesh::FaceVertexIter fv_it = mesh->fv_iter(*f_it); fv_it.is_valid(); ++fv_it) {
1076  ids.push_back(fv_it->idx());
1077  }
1078  }
1079  }
1080  selectHandleVertices(_objectId, ids);
1081  } else if(object->dataType() == DATA_POLY_MESH) {
1082  PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
1083  std::vector<int> ids;
1084  for(PolyMesh::FaceIter f_it = mesh->faces_begin(); f_it != mesh->faces_end(); ++f_it) {
1085  if(mesh->status(*f_it).selected()) {
1086  for(PolyMesh::FaceVertexIter fv_it = mesh->fv_iter(*f_it); fv_it.is_valid(); ++fv_it) {
1087  ids.push_back(fv_it->idx());
1088  }
1089  }
1090  }
1091  selectHandleVertices(_objectId, ids);
1092  }
1093  } else if (_to == "Modeling Region") {
1094  if(object->dataType() == DATA_TRIANGLE_MESH) {
1095  TriMesh* mesh = PluginFunctions::triMesh(_objectId);
1096  std::vector<int> ids;
1097  for(TriMesh::FaceIter f_it = mesh->faces_begin(); f_it != mesh->faces_end(); ++f_it) {
1098  if(mesh->status(*f_it).selected()) {
1099  for(TriMesh::FaceVertexIter fv_it = mesh->fv_iter(*f_it); fv_it.is_valid(); ++fv_it) {
1100  ids.push_back(fv_it->idx());
1101  }
1102  }
1103  }
1104  selectModelingVertices(_objectId, ids);
1105  } else if(object->dataType() == DATA_POLY_MESH) {
1106  PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
1107  std::vector<int> ids;
1108  for(PolyMesh::FaceIter f_it = mesh->faces_begin(); f_it != mesh->faces_end(); ++f_it) {
1109  if(mesh->status(*f_it).selected()) {
1110  for(PolyMesh::FaceVertexIter fv_it = mesh->fv_iter(*f_it); fv_it.is_valid(); ++fv_it) {
1111  ids.push_back(fv_it->idx());
1112  }
1113  }
1114  }
1115  selectModelingVertices(_objectId, ids);
1116  }
1117  }
1118 
1119  if(_deselect) {
1120  clearFaceSelection(_objectId);
1121  }
1122  } else if (_from == "Feature Vertices") {
1123 
1124  if (_to == "Vertex Selection") {
1125  if(object->dataType() == DATA_TRIANGLE_MESH) {
1126  MeshSelection::convertFeatureVerticesToVertexSelection(PluginFunctions::triMesh(_objectId));
1127  if (_deselect) {
1128  MeshSelection::clearFeatureVertices(PluginFunctions::triMesh(_objectId));
1129  }
1130  } else if(object->dataType() == DATA_POLY_MESH) {
1131  MeshSelection::convertFeatureVerticesToVertexSelection(PluginFunctions::polyMesh(_objectId));
1132  if (_deselect) {
1133  MeshSelection::clearFeatureVertices(PluginFunctions::polyMesh(_objectId));
1134  }
1135  }
1136  }
1137  } else if (_from == "Feature Edges") {
1138 
1139  if (_to == "Edge Selection") {
1140  if(object->dataType() == DATA_TRIANGLE_MESH) {
1141  MeshSelection::convertFeatureEdgesToEdgeSelection(PluginFunctions::triMesh(_objectId));
1142  if (_deselect) {
1143  MeshSelection::clearFeatureEdges(PluginFunctions::triMesh(_objectId));
1144  }
1145  } else if(object->dataType() == DATA_POLY_MESH) {
1146  MeshSelection::convertFeatureEdgesToEdgeSelection(PluginFunctions::polyMesh(_objectId));
1147  if (_deselect) {
1148  MeshSelection::clearFeatureEdges(PluginFunctions::polyMesh(_objectId));
1149  }
1150  }
1151  }
1152  } else if (_from == "Feature Faces") {
1153 
1154  if (_to == "Face Selection") {
1155  if(object->dataType() == DATA_TRIANGLE_MESH) {
1156  MeshSelection::convertFeatureFacesToFaceSelection(PluginFunctions::triMesh(_objectId));
1157  if (_deselect) {
1158  MeshSelection::clearFeatureFaces(PluginFunctions::triMesh(_objectId));
1159  }
1160  } else if(object->dataType() == DATA_POLY_MESH) {
1161  MeshSelection::convertFeatureFacesToFaceSelection(PluginFunctions::polyMesh(_objectId));
1162  if (_deselect) {
1163  MeshSelection::clearFeatureFaces(PluginFunctions::polyMesh(_objectId));
1164  }
1165  }
1166  }
1167  } else if (_from == "Handle Region") {
1168  std::vector<int> ids = getHandleVertices(_objectId);
1169  if(_to == "Vertex Selection") {
1170  selectVertices(_objectId, ids);
1171  } else if (_to == "Edge Selection") {
1172  if(object->dataType() == DATA_TRIANGLE_MESH)
1173  MeshSelection::convertVertexToEdgeSelection(PluginFunctions::triMesh(_objectId), ids);
1174  else if(object->dataType() == DATA_POLY_MESH)
1175  MeshSelection::convertVertexToEdgeSelection(PluginFunctions::polyMesh(_objectId), ids);
1176  } else if (_to == "Halfedge Selection") {
1177  if(object->dataType() == DATA_TRIANGLE_MESH)
1178  MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::triMesh(_objectId), ids);
1179  else if(object->dataType() == DATA_POLY_MESH)
1180  MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::polyMesh(_objectId), ids);
1181  } else if (_to == "Face Selection") {
1182  if(object->dataType() == DATA_TRIANGLE_MESH)
1183  MeshSelection::convertVertexToFaceSelection(PluginFunctions::triMesh(_objectId), ids);
1184  else if(object->dataType() == DATA_POLY_MESH)
1185  MeshSelection::convertVertexToFaceSelection(PluginFunctions::polyMesh(_objectId), ids);
1186  } else if (_to == "Modeling Region") {
1187  selectModelingVertices(_objectId, ids);
1188  }
1189 
1190  if(_deselect) {
1191  clearHandleVertices(_objectId);
1192  }
1193 
1194  } else if (_from == "Modeling Region") {
1195  std::vector<int> ids = getModelingVertices(_objectId);
1196  if(_to == "Vertex Selection") {
1197  selectVertices(_objectId, ids);
1198  } else if (_to == "Edge Selection") {
1199  if(object->dataType() == DATA_TRIANGLE_MESH)
1200  MeshSelection::convertVertexToEdgeSelection(PluginFunctions::triMesh(_objectId), ids);
1201  else if(object->dataType() == DATA_POLY_MESH)
1202  MeshSelection::convertVertexToEdgeSelection(PluginFunctions::polyMesh(_objectId), ids);
1203  } else if (_to == "Halfedge Selection") {
1204  if(object->dataType() == DATA_TRIANGLE_MESH)
1205  MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::triMesh(_objectId), ids);
1206  else if(object->dataType() == DATA_POLY_MESH)
1207  MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::polyMesh(_objectId), ids);
1208  } else if (_to == "Face Selection") {
1209  if(object->dataType() == DATA_TRIANGLE_MESH)
1210  MeshSelection::convertVertexToFaceSelection(PluginFunctions::triMesh(_objectId), ids);
1211  else if(object->dataType() == DATA_POLY_MESH)
1212  MeshSelection::convertVertexToFaceSelection(PluginFunctions::polyMesh(_objectId), ids);
1213  } else if (_to == "Handle Region") {
1214  selectHandleVertices(_objectId, ids);
1215  }
1216 
1217  if(_deselect) {
1218  clearModelingVertices(_objectId);
1219  }
1220  }
1221 
1222  emit updatedObject(_objectId, UPDATE_SELECTION);
1223 
1224 }
1225 
1226 
1227 void MeshObjectSelectionPlugin::conversion(const QString& _from, const QString& _to, bool _deselect) {
1228 
1230  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1231 
1232  convertSelection(o_it->id(),_from,_to,_deselect);
1233  emit createBackup(o_it->id(), "Selection Conversion", UPDATE_SELECTION);
1234  }
1235 }
1236 
1237 void MeshObjectSelectionPlugin::slotToggleSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
1238 
1239  // Return if none of the currently active types is handled by this plugin
1240  if((_currentType & allSupportedTypes_) == 0) return;
1241 
1242  size_t node_idx, target_idx;
1243  ACG::Vec3d hit_point;
1244 
1245  // First of all, pick anything to find all possible objects
1247  _event->pos(), node_idx, target_idx, &hit_point)) {
1248 
1249  BaseObjectData* object(0);
1250  PluginFunctions::getPickedObject(node_idx, object);
1251  if(!object) return;
1252 
1253  if (object->dataType() == DATA_TRIANGLE_MESH) {
1254  // Pick triangle meshes
1255  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
1256 
1257  if (object->dataType(DATA_TRIANGLE_MESH)) {
1258  toggleMeshSelection(object->id(), PluginFunctions::triMesh(object), target_idx, hit_point, _currentType);
1259  }
1260  } else {
1261  // Pick point cloud
1262  TriMesh* mesh = PluginFunctions::triMesh(object);
1263 
1264  if (mesh->n_vertices() && !mesh->n_faces()) {
1265  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_VERTEX, _event->pos(), node_idx, target_idx, &hit_point)) {
1266 
1267  TriMesh::VertexHandle vh = mesh->vertex_handle(target_idx);
1268  mesh->status(vh).set_selected(!mesh->status(vh).selected());
1269 
1270  if (mesh->status(vh).selected())
1271  emit scriptInfo("selectVertices(ObjectId(" + QString::number(object->id()) + ") , [" + QString::number(vh.idx()) + "])");
1272  else
1273  emit scriptInfo("unselectVertices(ObjectId(" + QString::number(object->id()) + ") , [" + QString::number(vh.idx()) + "])");
1274  emit updatedObject(object->id(), UPDATE_SELECTION_VERTICES);
1275  }
1276  }
1277  }
1278  } else if (object->dataType() == DATA_POLY_MESH) {
1279  // Pick poly meshes
1280  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
1281 
1282  if (object->dataType(DATA_POLY_MESH)) {
1283  toggleMeshSelection(object->id(), PluginFunctions::polyMesh(object), target_idx, hit_point, _currentType);
1284  }
1285  }
1286  }
1287  emit updatedObject(object->id(), UPDATE_SELECTION);
1288  emit createBackup(object->id(), "Toggle Selection", UPDATE_SELECTION);
1289  }
1290 }
1291 
1292 void MeshObjectSelectionPlugin::slotLassoSelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
1293 
1294  // Return if none of the currently active types is handled by this plugin
1295  if((_currentType & allSupportedTypes_) == 0) return;
1296 
1297  if(_event->type() == QEvent::MouseButtonPress) {
1298 
1299  // Add picked point
1300  lasso_2Dpoints_.push_back(_event->pos());
1301 
1302  return;
1303 
1304  } else if(_event->type() == QEvent::MouseButtonDblClick) {
1305 
1306  // Finish surface lasso selection
1307  if (lasso_2Dpoints_.size() > 2) {
1308 
1309  QRegion region(lasso_2Dpoints_);
1310 
1311  lassoSelect(region, _currentType, _deselect);
1312  }
1313 
1314  // Clear points
1315  lasso_2Dpoints_.clear();
1316  }
1317 }
1318 
1319 void MeshObjectSelectionPlugin::slotVolumeLassoSelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
1320 
1321  // Return if none of the currently active types is handled by this plugin
1322  if((_currentType & allSupportedTypes_) == 0) return;
1323 
1324  if(_event->type() == QEvent::MouseButtonPress) {
1325 
1326  // Add point on viewing plane to selection polygon
1327  volumeLassoPoints_.append(_event->pos());
1328 
1329  return;
1330 
1331  } else if(_event->type() == QEvent::MouseButtonDblClick) {
1332 
1334  bool updateGL = state.updateGL();
1335  state.set_updateGL (false);
1336 
1337  QPolygon p(volumeLassoPoints_);
1338  QRegion region = QRegion(p);
1339 
1340  SelectVolumeAction action(region, this, _currentType, _deselect, state);
1342 
1343  state.set_updateGL(updateGL);
1344 
1345  // Clear lasso points
1346  volumeLassoPoints_.clear();
1347  }
1348 }
1349 
1350 void MeshObjectSelectionPlugin::slotSphereSelection(QMouseEvent* _event, double _radius, PrimitiveType _currentType, bool _deselect) {
1351 
1352  // Return if none of the currently active types is handled by this plugin
1353  if((_currentType & allSupportedTypes_) == 0) return;
1354 
1355  size_t node_idx, target_idx;
1356  ACG::Vec3d hit_point;
1357 
1358  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx, target_idx, &hit_point)) {
1359 
1360  BaseObjectData* object = 0;
1361 
1362  if (PluginFunctions::getPickedObject(node_idx, object)) {
1363 
1364  if (object->picked(node_idx) && object->dataType(DATA_TRIANGLE_MESH)) {
1365  paintSphereSelection(PluginFunctions::triMesh(object), object->id(), target_idx, hit_point, _radius, _currentType, _deselect);
1366  } else if (object->picked(node_idx) && object->dataType(DATA_POLY_MESH)) {
1367  paintSphereSelection(PluginFunctions::polyMesh(object), object->id(), target_idx, hit_point, _radius, _currentType, _deselect);
1368  }
1369 
1370  emit updatedObject(object->id(), UPDATE_SELECTION);
1371  if ( _event->type() == QEvent::MouseButtonRelease )
1372  emit createBackup(object->id(), "Sphere Selection", UPDATE_SELECTION);
1373  }
1374  }
1375 }
1376 
1377 void MeshObjectSelectionPlugin::slotClosestBoundarySelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
1378 
1379  // Return if none of the currently active types is handled by this plugin
1380  if((_currentType & allSupportedTypes_) == 0) return;
1381 
1382  size_t node_idx, target_idx;
1383  ACG::Vec3d hit_point;
1384 
1385  if(PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos() ,node_idx, target_idx, &hit_point)) {
1386 
1387  BaseObjectData* object = 0;
1388 
1389  if(PluginFunctions::getPickedObject(node_idx, object)) {
1390 
1391  if(object->dataType(DATA_TRIANGLE_MESH)) {
1392 
1393  TriMesh* m = PluginFunctions::triMesh(object);
1394  TriMesh::VertexHandle vh = *(m->fv_iter(m->face_handle(target_idx)));
1395 
1396  closestBoundarySelection(m, vh.idx(), _currentType, _deselect);
1397 
1398  emit updatedObject(object->id(), UPDATE_SELECTION);
1399  emit createBackup(object->id(), "Boundary Selection", UPDATE_SELECTION);
1400 
1401  } else if(object->dataType(DATA_POLY_MESH)) {
1402 
1403  PolyMesh* m = PluginFunctions::polyMesh(object);
1404  PolyMesh::VertexHandle vh = *(m->fv_iter(m->face_handle(target_idx)));
1405 
1406  closestBoundarySelection(m, vh.idx(), _currentType, _deselect);
1407 
1408  emit updatedObject(object->id(), UPDATE_SELECTION);
1409  emit createBackup(object->id(), "Boundary Selection", UPDATE_SELECTION);
1410  }
1411 
1412  emit updateView();
1413  }
1414  }
1415 }
1416 
1417 void MeshObjectSelectionPlugin::slotFloodFillSelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
1418 
1419  // Return if none of the currently active types is handled by this plugin
1420  if((_currentType & allSupportedTypes_) == 0) return;
1421 
1422  size_t node_idx, target_idx;
1423  ACG::Vec3d hit_point;
1424 
1425  if(!OpenFlipper::Options::nogui())
1426  max_angle_ = parameterWidget_->maxAngle->value();
1427 
1428  // pick Anything to find all possible objects
1430  _event->pos(), node_idx, target_idx, &hit_point)) {
1431 
1432  BaseObjectData* object = 0;
1433 
1434  if(PluginFunctions::getPickedObject(node_idx, object)) {
1435 
1436  // TRIANGLE MESHES
1437  if(object->dataType() == DATA_TRIANGLE_MESH) {
1438 
1439  if(PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx, target_idx, &hit_point)) {
1440 
1441  if(PluginFunctions::getPickedObject(node_idx, object)) {
1442 
1443  if(object->dataType(DATA_TRIANGLE_MESH)) {
1445  PluginFunctions::triMesh(object),
1446  object->id(), target_idx, max_angle_,
1447  _currentType, _deselect);
1448  emit updatedObject(object->id(), UPDATE_SELECTION);
1449  emit createBackup(object->id(), "FloodFill Selection", UPDATE_SELECTION);
1450  }
1451  }
1452  }
1453 
1454  // POLY MESHES
1455  } else if(object->dataType() == DATA_POLY_MESH) {
1456 
1457  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx, target_idx, &hit_point)) {
1458 
1459  if(PluginFunctions::getPickedObject(node_idx, object) ) {
1460 
1461  if(object->dataType(DATA_POLY_MESH)) {
1463  PluginFunctions::polyMesh(object),
1464  object->id(), target_idx, max_angle_,
1465  _currentType, _deselect);
1466  emit updatedObject(object->id(), UPDATE_SELECTION);
1467  emit createBackup(object->id(), "FloodFill Selection", UPDATE_SELECTION);
1468  }
1469  }
1470  }
1471  }
1472  else {
1473  emit log(LOGERR,tr("floodFillSelection: Unsupported dataType"));
1474  }
1475  }
1476  }
1477 }
1478 
1479 void MeshObjectSelectionPlugin::slotComponentsSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
1480 
1481  // Return if none of the currently active types is handled by this plugin
1482  if((_currentType & allSupportedTypes_) == 0) return;
1483 
1484  size_t node_idx, target_idx;
1485  ACG::Vec3d hit_point;
1486 
1487  // First of all, pick anything to find all possible objects
1489  _event->pos(), node_idx, target_idx, &hit_point)) {
1490 
1491  BaseObjectData* object(0);
1492  PluginFunctions::getPickedObject(node_idx, object);
1493  if(!object) return;
1494 
1495  if (object->dataType() == DATA_TRIANGLE_MESH) {
1496  // Pick triangle meshes
1497  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
1498 
1499  if (object->dataType(DATA_TRIANGLE_MESH)) {
1501  object->id(), target_idx, hit_point, _currentType);
1502  }
1503  }
1504  } else if (object->dataType() == DATA_POLY_MESH) {
1505  // Pick poly meshes
1506  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
1507 
1508  if (object->dataType(DATA_POLY_MESH)) {
1510  object->id(), target_idx, hit_point, _currentType);
1511  }
1512  }
1513  }
1514  emit updatedObject(object->id(), UPDATE_SELECTION);
1515  emit createBackup(object->id(), "Connected Components Selection", UPDATE_SELECTION);
1516  }
1517 }
1518 
1519 void MeshObjectSelectionPlugin::slotIndexSelection(int _key)
1520 {
1521 
1522  bool targetsOnly = false;
1523  emit targetObjectsOnly(targetsOnly);
1526 
1527  int visible_objects = 0;
1529  o_it != PluginFunctions::objectsEnd(); ++o_it)
1530  {
1531  if (o_it->visible()) {
1532  ++visible_objects;
1533  }
1534  }
1535 
1536  bool fly = visible_objects == 1; // only fly to selection if a single object is processed
1537 
1538  int idx;
1539  switch (_key)
1540  {
1541  case Qt::Key_V:
1542  idx = QInputDialog::getInt(nullptr, tr("Vertex to mark"), tr("Vertex idx:"), -1);
1543  break;
1544  case Qt::Key_H:
1545  idx = QInputDialog::getInt(nullptr, tr("Halfedge to mark"), tr("Halfedge idx:"), -1);
1546  break;
1547  case Qt::Key_E:
1548  idx = QInputDialog::getInt(nullptr, tr("Edge to mark"), tr("Edge idx:"), -1);
1549  break;
1550  case Qt::Key_F:
1551  idx = QInputDialog::getInt(nullptr, tr("Face to mark"), tr("Face idx:"), -1);
1552  break;
1553  default:
1554  idx = -1;
1555  }
1556 
1557  if (idx < 0)
1558  return;
1559 
1561  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1562  bool selected_something = false;
1563  if (o_it->visible()) {
1564  if(_key == Qt::Key_V)
1565  selected_something = selectVertex(o_it->id(), idx, fly);
1566  if(_key == Qt::Key_H)
1567  selected_something = selectHalfedge(o_it->id(), idx, fly);
1568  if(_key == Qt::Key_E)
1569  selected_something = selectEdge(o_it->id(), idx, fly);
1570  if(_key == Qt::Key_F)
1571  selected_something = selectFace(o_it->id(), idx, fly);
1572  }
1573  if (selected_something)
1574  {
1575  emit updatedObject(o_it->id(), UPDATE_SELECTION);
1576  emit createBackup(o_it->id(), "Select Element", UPDATE_SELECTION);
1577  }
1578  }
1579 }
1580 
1581 void MeshObjectSelectionPlugin::loadSelection(int _objId, const QString& _filename) {
1582 
1583  // Load ini file
1584  INIFile file;
1585 
1586  if(!file.connect(_filename, false)) {
1587  emit log(LOGERR, QString("Could not read file '%1'!").arg(_filename));
1588  return;
1589  }
1590 
1591  // Load selection from file
1592  loadIniFile(file, _objId);
1593 }
1594 
1595 void MeshObjectSelectionPlugin::loadIniFile(INIFile& _ini, int _id) {
1596 
1597  BaseObjectData* object = 0;
1598  if (!PluginFunctions::getObject(_id,object)) {
1599  emit log(LOGERR,tr("Cannot find object for id ") + QString::number(_id) + tr(" in saveFile") );
1600  return;
1601  }
1602 
1603  std::vector<int> ids;
1604  bool invert = false;
1605 
1606  bool updated_selection = false;
1607  bool updated_modeling_regions = false;
1608 
1609  QString sectionName = object->name();
1610 
1611  if (_ini.get_entry(ids, sectionName ,"ModelingRegion")) {
1612  invert = false;
1613  _ini.get_entry(invert, sectionName, "InvertModeling");
1614 
1615  if (invert) {
1616  setAllModelingVertices(object->id());
1617  unselectModelingVertices(object->id() , ids);
1618  } else {
1619  clearModelingVertices(object->id());
1620  selectModelingVertices(object->id(), ids);
1621  }
1622 
1623  if(object->dataType(DATA_TRIANGLE_MESH)) {
1625  }
1626 
1627  if(object->dataType(DATA_POLY_MESH)) {
1629  }
1630 
1631  updated_modeling_regions = true;
1632  }
1633 
1634  if(_ini.get_entry(ids, sectionName, "HandleRegion")) {
1635  invert = false;
1636  _ini.get_entry(invert, sectionName, "InvertHandle");
1637 
1638  if(invert) {
1639  setAllHandleVertices(object->id());
1640  unselectHandleVertices(object->id(), ids);
1641  } else {
1642  clearHandleVertices(object->id());
1643  selectHandleVertices(object->id(), ids);
1644  }
1645 
1646  if (object->dataType(DATA_TRIANGLE_MESH)) {
1648  }
1649 
1650  if(object->dataType(DATA_POLY_MESH)) {
1652  }
1653 
1654  updated_modeling_regions = true;
1655  }
1656 
1657  if(_ini.get_entry(ids, sectionName, "VertexSelection")) {
1658  invert = false;
1659  _ini.get_entry(invert, sectionName, "InvertVertexSelection");
1660 
1661  if(invert) {
1662  selectAllVertices(object->id());
1663  unselectVertices(object->id(),ids);
1664  } else {
1665  clearVertexSelection(object->id());
1666  selectVertices(object->id(),ids);
1667  }
1668 
1669  updated_selection = true;
1670  }
1671 
1672  if(_ini.get_entry(ids, sectionName, "EdgeSelection")) {
1673  invert = false;
1674  _ini.get_entry(invert, sectionName, "InvertEdgeSelection");
1675 
1676  ids = convertVertexPairsToEdges(_id, ids);
1677 
1678  if(invert) {
1679  selectAllEdges(object->id());
1680  unselectEdges(object->id(),ids);
1681  } else {
1682  clearEdgeSelection(object->id());
1683  selectEdges(object->id(),ids);
1684  }
1685 
1686  updated_selection = true;
1687  }
1688 
1689  if(_ini.get_entry(ids, sectionName, "FaceSelection")) {
1690  invert = false;
1691  _ini.get_entry(invert, sectionName, "InvertFaceSelection");
1692 
1693  if(invert) {
1694  selectAllFaces(object->id());
1695  unselectFaces(object->id(),ids);
1696  } else {
1697  clearFaceSelection(object->id());
1698  selectFaces(object->id(),ids);
1699  }
1700 
1701  updated_selection = true;
1702  }
1703 
1704  if(updated_modeling_regions) {
1705 
1706  emit updatedObject(object->id(), UPDATE_ALL);
1707  emit updateView();
1708 
1709  } else if(updated_selection) {
1710 
1711  emit updatedObject(object->id(), UPDATE_SELECTION);
1712  emit updateView();
1713  }
1714 
1715  if ( updated_modeling_regions || updated_selection )
1716  emit createBackup(object->id(), "Load Selection", UPDATE_SELECTION);
1717 }
1718 
1719 void MeshObjectSelectionPlugin::saveIniFile(INIFile& _ini, int _id) {
1720 
1721  BaseObjectData* object = 0;
1722  if ( !PluginFunctions::getObject(_id,object) ) {
1723  emit log(LOGERR,tr("Cannot find object for id ") + QString::number(_id) + tr(" in saveFile") );
1724  return;
1725  }
1726 
1727  // The objects section should already exist
1728  QString sectionName = object->name();
1729  if(!_ini.section_exists(sectionName)) {
1730  emit log(LOGERR,tr("Cannot find object section id ") + QString::number(_id) + tr(" in saveFile") );
1731  return;
1732  }
1733 
1734  _ini.add_entry(sectionName, "VertexSelection", getVertexSelection(object->id()));
1735  _ini.add_entry(sectionName, "EdgeSelection", convertEdgesToVertexPairs(_id, getEdgeSelection(object->id())));
1736 
1737  if(object->dataType(DATA_POLY_MESH ) || object->dataType( DATA_TRIANGLE_MESH)) {
1738  _ini.add_entry(sectionName, "FaceSelection", getFaceSelection(object->id()));
1739  _ini.add_entry(sectionName, "HandleRegion", getHandleVertices(object->id()));
1740  _ini.add_entry(sectionName, "ModelingRegion", getModelingVertices(object->id()));
1741  }
1742 }
1743 
1745 
1746  // Iterate over all mesh objects in the scene and save
1747  // the selections for all supported entity types
1749  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1750 
1751  // Read section for each object
1752  // Append object name to section identifier
1753  QString section = QString("MeshObjectSelection") + "//" + o_it->name();
1754  if(!_file.section_exists(section)) {
1755  continue;
1756  }
1757 
1758  std::vector<int> ids;
1759  // Load vertex selection:
1760  _file.get_entry(ids, section, "VertexSelection");
1761  selectVertices(o_it->id(), ids);
1762  ids.clear();
1763  // Load edge selection:
1764  _file.get_entry(ids, section, "EdgeSelection");
1765  selectEdges(o_it->id(), convertVertexPairsToEdges(o_it->id(), ids));
1766  ids.clear();
1767  // Load halfedge selection:
1768  _file.get_entry(ids, section, "HalfedgeSelection");
1769  selectHalfedges(o_it->id(), convertVertexPairsToHalfedges(o_it->id(), ids));
1770  ids.clear();
1771  // Load face selection:
1772  _file.get_entry(ids, section, "FaceSelection");
1773  selectFaces(o_it->id(), ids);
1774  ids.clear();
1775  // Load handle region:
1776  _file.get_entry(ids, section, "HandleRegion");
1777  selectHandleVertices(o_it->id(), ids);
1778  ids.clear();
1779  // Load modeling region:
1780  _file.get_entry(ids, section, "ModelingRegion");
1781  selectModelingVertices(o_it->id(), ids);
1782  ids.clear();
1783 
1784  emit updatedObject(o_it->id(), UPDATE_SELECTION);
1785  emit createBackup(o_it->id(), "Load Selection", UPDATE_SELECTION);
1786  }
1787 }
1788 
1790 
1791  // Iterate over all mesh objects in the scene and save
1792  // the selections for all supported entity types
1794  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1795 
1796  // Create section for each object
1797  // Append object name to section identifier
1798  QString section = QString("MeshObjectSelection") + "//" + o_it->name();
1799 
1800  // Store vertex selection:
1801  _file.add_entry(section, "VertexSelection", getVertexSelection(o_it->id()));
1802  // Store edge selection:
1803  _file.add_entry(section, "EdgeSelection", convertEdgesToVertexPairs(o_it->id(), getEdgeSelection(o_it->id())));
1804  // Store halfedge selection:
1805  _file.add_entry(section, "HalfedgeSelection", convertHalfedgesToVertexPairs(o_it->id(), getHalfedgeSelection(o_it->id())));
1806  // Store face selection:
1807  _file.add_entry(section, "FaceSelection", getFaceSelection(o_it->id()));
1808  // Store handle region:
1809  _file.add_entry(section, "HandleRegion", getHandleVertices(o_it->id()));
1810  // Store modeling region:
1811  _file.add_entry(section, "ModelingRegion", getModelingVertices(o_it->id()));
1812  }
1813 }
1814 
1815 void MeshObjectSelectionPlugin::slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) {
1816 
1817  if (((_key == Qt::Key_V) || (_key == Qt::Key_H) || (_key == Qt::Key_E) || (_key == Qt::Key_F)) && _modifiers == Qt::NoModifier)
1818  slotIndexSelection(_key);
1819 
1820  SelectionInterface::PrimitiveType type = 0u;
1821  emit getActivePrimitiveType(type);
1822 
1823  if((type & allSupportedTypes_) == 0)
1824  {
1825  // No supported type is active
1826  return;
1827  }
1828 
1829  bool targetsOnly = false;
1830  emit targetObjectsOnly(targetsOnly);
1833 
1834  if(_key == Qt::Key_A && _modifiers == Qt::ControlModifier) {
1835 
1837  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1838  if (o_it->visible()) {
1839 
1840  if(type & vertexType_)
1841  selectAllVertices(o_it->id());
1842  if(type & edgeType_)
1843  selectAllEdges(o_it->id());
1844  if(type & halfedgeType_)
1845  selectAllHalfedges(o_it->id());
1846  if(type & faceType_)
1847  selectAllFaces(o_it->id());
1848  }
1849  emit updatedObject(o_it->id(), UPDATE_SELECTION);
1850  emit createBackup(o_it->id(), "Select All", UPDATE_SELECTION);
1851  }
1852  } else if (_key == Qt::Key_C && ( _modifiers == Qt::NoModifier || _modifiers == Qt::ShiftModifier) ) {
1853 
1855  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1856  if (o_it->visible()) {
1857 
1858  if ( _modifiers == Qt::NoModifier ) {
1859  if( type & vertexType_ )
1860  clearVertexSelection(o_it->id());
1861  if(type & edgeType_)
1862  clearEdgeSelection(o_it->id());
1863  if(type & halfedgeType_)
1864  clearHalfedgeSelection(o_it->id());
1865  if(type & faceType_)
1866  clearFaceSelection(o_it->id());
1867  } else { // Shift -> Clear All
1868  clearVertexSelection(o_it->id());
1869  clearEdgeSelection(o_it->id());
1870  clearHalfedgeSelection(o_it->id());
1871  clearFaceSelection(o_it->id());
1872  }
1873 
1874  emit updatedObject(o_it->id(), UPDATE_SELECTION);
1875  emit createBackup(o_it->id(), "Clear Selection", UPDATE_SELECTION);
1876  }
1877 
1878  }
1879 
1880  } else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
1881 
1883  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1884  if (o_it->visible()) {
1885 
1886  if(type & vertexType_)
1887  invertVertexSelection(o_it->id());
1888  if(type & edgeType_)
1889  invertEdgeSelection(o_it->id());
1890  if(type & halfedgeType_)
1891  invertHalfedgeSelection(o_it->id());
1892  if(type & faceType_)
1893  invertFaceSelection(o_it->id());
1894  }
1895  emit updatedObject(o_it->id(), UPDATE_SELECTION);
1896  emit createBackup(o_it->id(), "Invert Selection", UPDATE_SELECTION);
1897  }
1898  } else if (_key == Qt::Key_Delete && _modifiers == Qt::NoModifier) {
1899 
1901  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1902  if (o_it->visible()) {
1903  // Delete all selected primitives
1904  if(type & vertexType_)
1905  deleteVertexSelection(o_it->id());
1906  if(type & edgeType_)
1907  deleteEdgeSelection(o_it->id());
1908  if(type & faceType_)
1909  deleteFaceSelection(o_it->id());
1910  }
1911  emit updatedObject(o_it->id(), UPDATE_TOPOLOGY);
1912  emit createBackup(o_it->id(), "Delete Selection", UPDATE_TOPOLOGY);
1913  }
1914  }
1915 }
1916 
1917 void MeshObjectSelectionPlugin::slotMouseWheelEvent(QWheelEvent* event, std::string const& mode) {
1918 
1919  // Get currently active primitive type
1920  SelectionInterface::PrimitiveType type = 0u;
1921  emit getActivePrimitiveType(type);
1922 
1923  // Only handle supported primitive types
1924  if((type & allSupportedTypes_) == 0) {
1925  // No supported type is active
1926  return;
1927  }
1928 
1929  // Decide, if all or only target objects should be handled
1930  bool targetsOnly = false;
1931  emit targetObjectsOnly(targetsOnly);
1934 
1935  if(event->modifiers() == Qt::ShiftModifier) {
1936 
1937  if (event->angleDelta().y() > 0) {
1939  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1940  if (o_it->visible()) {
1941 
1942  if(type & vertexType_)
1943  growVertexSelection(o_it->id());
1944  if(type & faceType_)
1945  growFaceSelection(o_it->id());
1946  }
1947  emit updatedObject(o_it->id(), UPDATE_SELECTION);
1948  emit createBackup(o_it->id(), "Grow Selection", UPDATE_SELECTION);
1949  }
1950  } else {
1951 
1953  o_it != PluginFunctions::objectsEnd(); ++o_it) {
1954  if (o_it->visible()) {
1955 
1956  if(type & vertexType_)
1957  shrinkVertexSelection(o_it->id());
1958  if(type & faceType_)
1959  shrinkFaceSelection(o_it->id());
1960  }
1961  emit updatedObject(o_it->id(), UPDATE_SELECTION);
1962  emit createBackup(o_it->id(), "Shrink Selection", UPDATE_SELECTION);
1963  }
1964  }
1965  }
1966 }
1967 
1969  PrimitiveType _primitiveType,
1970  bool _deselection) {
1971 
1972  // <object id, primitive id>
1973  QList <QPair<size_t, size_t> > list;
1974 
1975  if(_primitiveType & vertexType_) {
1977 
1978  std::set<int> alreadySelectedObjects;
1979 
1980  for(int i = 0; i < list.size(); ++i) {
1981 
1982  if(alreadySelectedObjects.count(list[i].first) != 0)
1983  continue;
1984 
1985  BaseObjectData* bod = 0;
1986  PluginFunctions::getPickedObject(list[i].first, bod);
1987 
1988  if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
1989  IdList elements;
1990  for(int j = 0; j < list.size(); ++j) {
1991  if(list[j].first == list[i].first) {
1992 
1993  elements.push_back(list[j].second);
1994  }
1995  }
1996  if (!_deselection)
1997  selectVertices(bod->id(), elements);
1998  else
1999  unselectVertices(bod->id(), elements);
2000  alreadySelectedObjects.insert(list[i].first);
2001  emit updatedObject(bod->id(), UPDATE_SELECTION);
2002  emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
2003  }
2004  }
2005  }
2006  if(_primitiveType & edgeType_) {
2008 
2009  std::set<int> alreadySelectedObjects;
2010 
2011  for(int i = 0; i < list.size(); ++i) {
2012 
2013  if(alreadySelectedObjects.count(list[i].first) != 0)
2014  continue;
2015 
2016  BaseObjectData* bod = 0;
2017  PluginFunctions::getPickedObject(list[i].first, bod);
2018 
2019  if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
2020  IdList elements;
2021  for(int j = 0; j < list.size(); ++j) {
2022  if(list[j].first == list[i].first) {
2023 
2024  elements.push_back(list[j].second);
2025  }
2026  }
2027  if (!_deselection)
2028  selectEdges(bod->id(), elements, dihedral_angle_threshold_);
2029  else
2030  unselectEdges(bod->id(), elements);
2031  alreadySelectedObjects.insert(list[i].first);
2032  emit updatedObject(bod->id(), UPDATE_SELECTION);
2033  emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
2034  }
2035  }
2036  }
2037  if(_primitiveType & halfedgeType_) {
2039 
2040  std::set<int> alreadySelectedObjects;
2041 
2042  for(int i = 0; i < list.size(); ++i) {
2043 
2044  if(alreadySelectedObjects.count(list[i].first) != 0)
2045  continue;
2046 
2047  BaseObjectData* bod = 0;
2048  PluginFunctions::getPickedObject(list[i].first, bod);
2049 
2050  if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
2051  IdList elements;
2052  for(int j = 0; j < list.size(); ++j) {
2053  if(list[j].first == list[i].first) {
2054 
2055  elements.push_back(list[j].second);
2056  }
2057  }
2058  IdList oldEdgeSelection = getEdgeSelection(bod->id());
2059  clearEdgeSelection(bod->id());
2060 
2061  if (!_deselection)
2062  {
2063  //on selection: select picked edges, convert to halfedge selection
2065  selectEdges(bod->id(), elements, dihedral_angle_threshold_);
2066  }
2067  else
2068  {
2069  //on deselection: get current Halfedge Selection, unselect edge, convert back
2070  if(bod->dataType() == DATA_TRIANGLE_MESH)
2071  MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::triMesh(bod));
2072  else if(bod->dataType() == DATA_POLY_MESH)
2073  MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::polyMesh(bod));
2074 
2075  clearHalfedgeSelection(bod->id());
2076  unselectEdges(bod->id(), elements);
2077  }
2078 
2079 
2080  if(bod->dataType() == DATA_TRIANGLE_MESH)
2081  MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::triMesh(bod));
2082  else if(bod->dataType() == DATA_POLY_MESH)
2083  MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::polyMesh(bod));
2084 
2085  clearEdgeSelection(bod->id());
2086  selectEdges(bod->id(), oldEdgeSelection);
2087 
2088  alreadySelectedObjects.insert(list[i].first);
2089  emit updatedObject(bod->id(), UPDATE_SELECTION);
2090  emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
2091  }
2092  }
2093  }
2094  if(_primitiveType & faceType_) {
2096 
2097  std::set<int> alreadySelectedObjects;
2098 
2099  for(int i = 0; i < list.size(); ++i) {
2100 
2101  if(alreadySelectedObjects.count(list[i].first) != 0)
2102  continue;
2103 
2104  BaseObjectData* bod = 0;
2105  PluginFunctions::getPickedObject(list[i].first, bod);
2106 
2107  if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
2108  IdList elements;
2109  for(int j = 0; j < list.size(); ++j) {
2110  if(list[j].first == list[i].first) {
2111 
2112  elements.push_back(list[j].second);
2113  }
2114  }
2115  if (!_deselection)
2116  selectFaces(bod->id(), elements);
2117  else
2118  unselectFaces(bod->id(), elements);
2119  alreadySelectedObjects.insert(list[i].first);
2120  emit updatedObject(bod->id(), UPDATE_SELECTION);
2121  emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
2122  }
2123  }
2124  }
2125 }
2126 
2129 
2130  BaseObjectData* object = 0;
2131  if(PluginFunctions::getPickedObject(_node->id(), object)) {
2132 
2133  bool selected = false;
2134  if (object->dataType(DATA_TRIANGLE_MESH)) {
2135 
2136  TriMesh* m = PluginFunctions::triMesh(object);
2137  selected = plugin_->volumeSelection(m, object->id(), state_, &region_, type_, deselection_);
2138 
2139  } else if(object->dataType(DATA_POLY_MESH)) {
2140 
2141  PolyMesh* m = PluginFunctions::polyMesh(object);
2142  selected = plugin_->volumeSelection(m, object->id(), state_, &region_, type_, deselection_);
2143  }
2144 
2145  if (selected){
2146  emit plugin_->updatedObject(object->id(), UPDATE_SELECTION);
2147  emit plugin_->createBackup( object->id(), "Lasso Selection", UPDATE_SELECTION);
2148  }
2149  }
2150  return true;
2151 }
2152 
2154 int MeshObjectSelectionPlugin::createMeshFromSelection(int _objectId, PrimitiveType _primitiveType)
2155 {
2156 
2157  // get object
2158  BaseObjectData *obj = 0;
2159  PluginFunctions::getObject(_objectId, obj);
2160 
2161  if (obj == 0) {
2162  emit log(LOGERR, tr("Unable to get object"));
2163  return -1;
2164  }
2165 
2166  if (obj->dataType(DATA_TRIANGLE_MESH)) {
2167  TriMesh* mesh = PluginFunctions::triMesh(obj);
2168 
2169  if (mesh == 0) {
2170  emit log(LOGERR, tr("Unable to get mesh"));
2171  return -1;
2172  }
2173 
2174  //add an empty mesh
2175  int id = -1;
2176  emit addEmptyObject(DATA_TRIANGLE_MESH, id);
2177 
2178  if (id == -1) {
2179  emit log(LOGERR, tr("Unable to add empty object"));
2180  return -1;
2181  }
2182 
2183  BaseObjectData *newObj;
2184  PluginFunctions::getObject(id, newObj);
2185 
2186  TriMesh* newMesh = PluginFunctions::triMesh(newObj);
2187 
2188  if (newMesh == 0) {
2189  emit log(LOGERR, tr("Unable to get mesh"));
2190  return -1;
2191  }
2192 
2193  //fill the empty mesh with the selection
2194  createMeshFromSelection(*mesh, *newMesh,_primitiveType);
2195 
2196  emit updatedObject(id, UPDATE_ALL);
2197 
2198  return id;
2199 
2200  } else if (obj->dataType(DATA_POLY_MESH)) {
2201  PolyMesh* mesh = PluginFunctions::polyMesh(obj);
2202 
2203  if (mesh == 0) {
2204  emit log(LOGERR, tr("Unable to get mesh"));
2205  return -1;
2206  }
2207 
2208  //add an empty mesh
2209  int id;
2210  emit addEmptyObject(DATA_POLY_MESH, id);
2211 
2212  if (id == -1) {
2213  emit log(LOGERR, tr("Unable to add empty object"));
2214  return -1;
2215  }
2216 
2217  BaseObjectData *newObj;
2218  PluginFunctions::getObject(id, newObj);
2219 
2220  PolyMesh* newMesh = PluginFunctions::polyMesh(newObj);
2221 
2222  if (newMesh == 0) {
2223  emit log(LOGERR, tr("Unable to get mesh"));
2224  return -1;
2225  }
2226 
2227  //fill the empty mesh with the selection
2228  createMeshFromSelection(*mesh, *newMesh,_primitiveType);
2229 
2230  emit updatedObject(id, UPDATE_ALL);
2231 
2232  return id;
2233  } else {
2234  emit log(LOGERR, tr("DataType not supported"));
2235  return -1;
2236  }
2237 }
2238 
2240 {
2241  // apply color values to the gui
2242  if (OpenFlipper::Options::gui())
2243  {
2244  colorButtonSelection_->setColor(QColor::fromRgbF(statusColor_[0],statusColor_[1],statusColor_[2],statusColor_[3]));
2245  colorButtonHandle_->setColor(QColor::fromRgbF(handleColor_[0], handleColor_[1], handleColor_[2], handleColor_[3]));
2246  colorButtonArea_->setColor(QColor::fromRgbF(areaColor_[0],areaColor_[1],areaColor_[2],areaColor_[3]));
2247  colorButtonFeature_->setColor(QColor::fromRgbF(featureColor_[0],featureColor_[1],featureColor_[2],featureColor_[3]));
2248  }
2249 
2250  // save new color values
2251  std::stringstream sstream;
2252  sstream << statusColor_;
2253  OpenFlipperQSettings().setValue("SelectionMeshObject/StatusColor",QString(sstream.str().c_str()));
2254  sstream.str("");
2255  sstream.clear();
2256 
2257  sstream << handleColor_;
2258  OpenFlipperQSettings().setValue("SelectionMeshObject/HandleColor",QString(sstream.str().c_str()));
2259  sstream.str("");
2260  sstream.clear();
2261 
2262  sstream << areaColor_;
2263  OpenFlipperQSettings().setValue("SelectionMeshObject/AreaColor",QString(sstream.str().c_str()));
2264  sstream.str("");
2265  sstream.clear();
2266 
2267  sstream << featureColor_;
2268  OpenFlipperQSettings().setValue("SelectionMeshObject/FeatureColor",QString(sstream.str().c_str()));
2269 }
2270 
2271 
2273 {
2274  statusColor_ = ACG::Vec4f(1.0f,0.0f,0.0f,1.0f);
2275  areaColor_ = ACG::Vec4f(0.4f, 0.4f, 1.0f, 1.0f);
2276  handleColor_ = ACG::Vec4f(0.2f, 1.0f, 0.2f, 1.0f);
2277  featureColor_ = ACG::Vec4f(1.0f, 0.2f, 1.0f, 1.0f);
2278 
2280 }
2281 
2283 {
2284  _widget = new QWidget();
2285  QVBoxLayout* vLayout = new QVBoxLayout();
2286  QHBoxLayout* hLayout = new QHBoxLayout();
2287 
2288  hLayout->addWidget(new QLabel("Select default colors for newly created objects. Does not affect already created objects."));
2289  vLayout->addLayout(hLayout);
2290 
2291  hLayout = new QHBoxLayout();
2293  hLayout->addWidget(new QLabel("Selection Color: "));
2294  hLayout->addWidget(colorButtonSelection_);
2295  vLayout->addLayout(hLayout);
2296 
2297  hLayout = new QHBoxLayout();
2299  hLayout->addWidget(new QLabel("Handle Color: "));
2300  hLayout->addWidget(colorButtonHandle_);
2301  vLayout->addLayout(hLayout);
2302 
2303  hLayout = new QHBoxLayout();
2305  hLayout->addWidget(new QLabel("Feature Color: "));
2306  hLayout->addWidget(colorButtonFeature_);
2307  vLayout->addLayout(hLayout);
2308 
2309  hLayout = new QHBoxLayout();
2311  hLayout->addWidget(new QLabel("Area Color: "));
2312  hLayout->addWidget(colorButtonArea_);
2313  vLayout->addLayout(hLayout);
2314 
2315  hLayout = new QHBoxLayout();
2316  QPushButton* restoreDefault = new QPushButton();
2317  connect(restoreDefault, SIGNAL(clicked()), this, SLOT(setDefaultColorValues()));
2318  restoreDefault->setText("Restore Default");
2319  hLayout->addWidget(restoreDefault);
2320  hLayout->addStretch();
2321  vLayout->addLayout(hLayout);
2322 
2323  _widget->setLayout(vLayout);
2324 
2325  return true;
2326 }
2327 
2328 void MeshObjectSelectionPlugin::applyOptions()
2329 {
2330  statusColor_ = ACG::Vec4f(colorButtonSelection_->color().redF(),colorButtonSelection_->color().greenF(),colorButtonSelection_->color().blueF(),1.f);
2331  areaColor_ = ACG::Vec4f(colorButtonArea_->color().redF(),colorButtonArea_->color().greenF(),colorButtonArea_->color().blueF(),1.f);
2332  handleColor_ = ACG::Vec4f(colorButtonHandle_->color().redF(),colorButtonHandle_->color().greenF(),colorButtonHandle_->color().blueF(),1.f);
2333  featureColor_ = ACG::Vec4f(colorButtonFeature_->color().redF(),colorButtonFeature_->color().greenF(),colorButtonFeature_->color().blueF(),1.f);
2334 
2336 }
2337 
2339 {
2340  if (OpenFlipper::Options::nogui())
2341  return;
2342 
2343  PolyMeshObject* polyObj = 0;
2344  TriMeshObject* triObj = 0;
2345 
2346  triObj = PluginFunctions::triMeshObject(_id);
2347  polyObj = PluginFunctions::polyMeshObject(_id);
2348 
2349  if (triObj)
2350  {
2352  triObj->setHandleColor(handleColor_);
2353  triObj->setAreaColor(areaColor_);
2354  triObj->setFeatureColor(featureColor_);
2355  }else if (polyObj)
2356  {
2357  polyObj->setSelectionColor(statusColor_);
2358  polyObj->setHandleColor(handleColor_);
2359  polyObj->setAreaColor(areaColor_);
2360  polyObj->setFeatureColor(featureColor_);
2361  }
2362 
2363 }
2364 
2366 {
2367  dihedral_angle_threshold_ = OpenMesh::deg_to_rad(_a);
2368 }
2369 
2371 {
2373 }
2374 
2376 {
2377  max_angle_ = _a;
2378 }
2379 
2381 {
2382  return max_angle_;
2383 }
2384 
2386 {
2387  set_dihedral_angle_threshold( parameterWidget_->minDihedralAngle->value());
2388 }
2389 
2390 
2391 
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
void unselectModelingVertices(int objectId, IdList _vertexList)
Remove vertices from modeling area.
void slotSelectionOperation(QString _operation)
A specific operation is requested.
void selectEdges(int objectId, IdList _edgeList, const double _dihedral_angle_threshold=0.0)
Select given Edges.
void selectBoundaryFaces(int objectId)
Select all boundary faces of the given object.
void selectHandleVertices(int objectId, IdList _vertexList)
Set vertices to be part of the handle area.
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(8))
Topology updated.
void deleteEdgeSelection(int _objectId)
Delete edges that are currently selected.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
QVector< QPoint > volumeLassoPoints_
Used for volume lasso tool.
void conversion(const QString &_from, const QString &_to, bool _deselect)
Convert the selection on all target objects.
void selectBoundaryEdges(int objectId)
select boundary edges
void updateColorValues()
Set descriptions for local public slots.
ConversionDialog * conversionDialog_
Handle to selection environment.
void shrinkVertexSelection(int _objectId)
Shrink the current vertex selection.
virtual bool picked(uint _node_idx)
detect if the node has been picked
void setDefaultColorValues()
sets the default color values for selection/handle/region/feature nodes for all objects of this type ...
void unselectFaces(int objectId, IdList _facesList)
Unselect given faces.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers)
One of the previously registered keys has been pressed.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void unselectHandleVertices(int objectId, IdList _vertexList)
Remove vertices from handle area.
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
picks faces (should be implemented for all nodes)
Definition: PickTarget.hh:78
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:65
ACG::Vec4f handleColor_
Handle to selection environment.
void invertFaceSelection(int objectId)
Invert the current face selection.
void growFaceSelection(int objectId)
Grow the current face selection.
Kernel::FaceVertexIter FaceVertexIter
Circulator.
Definition: PolyMeshT.hh:167
ACG::SceneGraph::BaseNode * getRootNode()
Get the root node for data objects.
void setAllHandleVertices(int objectId)
Set all vertices to be part of the handle area.
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
double get_dihedral_angle_threshold()
get dihedral angle threshold for edge selection
double dihedral_angle_threshold_
Handle to selection environment.
QPolygon lasso_2Dpoints_
Used for lasso selection tool.
void slotFloodFillSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a flood fill selection.
void selectModelingVertices(int objectId, IdList _vertexList)
Set vertices to be part of the modeling area.
picks only visible front verices (may not be implemented for all nodes)
Definition: PickTarget.hh:89
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
void selectAllEdges(int objectId)
Select all Edges.
void slotMouseWheelEvent(QWheelEvent *event, std::string const &mode)
Wheel Event from main application.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(16))
Selection updated.
IdList convertVertexPairsToEdges(int _id, const IdList &_vertices)
Inverse of function above.
bool scenegraphRegionPick(ACG::SceneGraph::PickTarget _pickTarget, const QRegion &_region, QList< QPair< size_t, size_t > > &_list, QVector< float > *_depths, QVector< ACG::Vec3d > *_points)
void setHandleColor(const ACG::Vec4f &_color)
set color for handles
void slotLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a lasso selection.
QtColorChooserButton * colorButtonArea_
Handle to selection environment.
void selectAllHalfedges(int objectId)
Select all Halfedges.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
const QStringList ALL_OBJECTS
Iterable object range.
ACG::Vec4f statusColor_
Handle to selection environment.
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a toggle selection.
ACG::Vec4f featureColor_
Handle to selection environment.
Predefined datatypes.
Definition: DataTypes.hh:83
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a volume lasso selection.
bool selectFace(int _objectId, int _idx, bool _fly_to_face)
Select face with id _idx and maybe fly to it.
void invertHalfedgeSelection(int objectId)
Unselect all Halfedges.
int id() const
Definition: BaseObject.cc:190
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
Definition: GLState.hh:235
QtColorChooserButton * colorButtonHandle_
Handle to selection environment.
SelectionInterface::PrimitiveType faceType_
Handle to selection environment.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
void deleteFaceSelection(int _objectId)
Delete face that are currently selected.
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
SelectionInterface::PrimitiveType vertexType_
Primitive type handles:
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
void slotSaveSelection(INIFile &_file)
Save selection for all objects in the scene.
void invertVertexSelection(int _objectId)
Invert the current vertex selection.
double max_angle_
Handle to selection environment.
void convertSelection(const int &_objectId, const QString &_from, const QString &_to, bool _deselect)
Convert the selection on one object.
bool updateGL() const
should GL matrices be updated after each matrix operation
Definition: GLState.hh:233
void unselectVertices(int objectId, IdList _vertexList)
unselect given vertices
void slotComponentsSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a connected components selection.
void setAllModelingVertices(int objectId)
Set all vertices to be part of the modeling area.
void selectBoundaryVertices(int _objectId)
Select all boundary vertices of the given object.
IdList getHandleVertices(int objectId)
Get a list of all handle vertices.
void addedEmptyObject(int _id)
An empty object has been added.
void slotSphereSelection(QMouseEvent *_event, double _radius, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a sphere selection.
void update_dihedral_angle_threshold_from_ui()
set dihedral angle threshold for edge selection
bool operator()(BaseNode *_node)
Traverse the scenegraph and call the selection function for all mesh nodes.
QString environmentHandle_
Handle to selection environment.
QtColorChooserButton * colorButtonSelection_
Options.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
IdList convertHalfedgesToVertexPairs(int _id, const IdList &_halfedges)
Convert halfedge ids to vertex pairs.
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
void deleteVertexSelection(int _objectId)
Delete vertices and faces that are currently selected.
IdList getModelingVertices(int objectId)
Get a list of all modeling vertices.
void traceEdgePath(int objectId, double threshold)
Trace Edge Path.
void colorizeEdgeSelection(int objectId, int r, int g, int b, int a)
Colorize the edge selection.
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
void selectBoundaryHalfedges(int objectId)
Select boundary edges.
void set_dihedral_angle_threshold(const double _a)
set dihedral angle threshold for edge selection
void slotLoadSelection(const INIFile &_file)
Load selection for specific objects in the scene.
void setAreaColor(const ACG::Vec4f &_color)
set color for areas
picks only visible front edges (may not be implemented for all nodes)
Definition: PickTarget.hh:87
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
double get_max_angle()
get max angle for flood fill selection
void selectVertices(int objectId, IdList _vertexList)
select given vertices
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.
void unselectEdges(int objectId, IdList _edgeList)
Unselect given Edges.
QStringList IteratorRestriction
Iterable object range.
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:67
bool selectVertex(int _objectId, int _idx, bool _fly_to_vertex)
select vertex with id _idx and maybe fly to it
MeshObjectSelectionPlugin()
Default constructor.
IdList getFaceSelection(int objectId)
Return a list of all selected faces.
QtColorChooserButton * colorButtonFeature_
Handle to selection environment.
SelectionInterface::PrimitiveType edgeType_
Handle to selection environment.
void createMeshFromSelection(MeshT &_mesh, MeshT &_newMesh, PrimitiveType _primitiveType)
Create a new mesh from the selection.
IdList getHalfedgeSelection(int objectId)
Return a list of all selected edges.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
void selectFaces(int objectId, IdList _facesList)
Select given faces.
bool selectEdge(int _objectId, int _idx, bool _fly_to_edge)
Select edge with id _idx and maybe fly to it.
unsigned int id() const
Definition: BaseNode.hh:423
void componentsMeshSelection(MeshT *_mesh, int _objectId, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Connected component mesh selection.
void clearHandleVertices(int objectId)
Clear handle Area.
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.
void updateSlotDescriptions()
Set descriptions for local public slots.
Class for the handling of simple configuration files.
Definition: INIFile.hh:99
SelectionInterface::PrimitiveType allSupportedTypes_
Handle to selection environment.
IdList getVertexSelection(int _objectId)
Return a list of all selected vertices.
void set_max_angle(const double _a)
set max angle for flood fill selection
void shrinkFaceSelection(int objectId)
Shrink the current face selection.
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:70
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void closestBoundarySelection(MeshT *_mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are incident to closest boundary.
void setColorForSelection(const int _objectId, const PrimitiveType _primitiveType)
Set color for selection.
void clearModelingVertices(int objectId)
Clear Modeling Area.
void paintSphereSelection(MeshT *_mesh, int _objectId, int _target_idx, typename MeshT::Point _hitpoint, double _radius, PrimitiveType _primitiveTypes, bool _deselection)
Use the event to paint selection with a sphere.
ParameterWidget * parameterWidget_
Handle to selection environment.
void selectAllVertices(int _objectId)
Select all Vertices.
IdList convertEdgesToVertexPairs(int _id, const IdList &_edges)
Convert edge ids to vertex pairs.
bool selectHalfedge(int _objectId, int _idx, bool _fly_to_halfedge)
Select halfedge with id _idx and maybe fly to it.
void setFeatureColor(const ACG::Vec4f &_color)
set color for features
void selectHalfedges(int objectId, IdList _vertexList)
Select given Halfedges.
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void setSelectionColor(const ACG::Vec4f &_color)
set color for selection
void selectAllFaces(int objectId)
Select all faces.
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
void conversionRequested()
Show selection conversion dialog.
void clearFaceSelection(int objectId)
Unselect all faces.
void toggleMeshSelection(int _objectId, MeshT *_mesh, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Toggle mesh selection.
void slotClosestBoundarySelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a closest boundary selection.
~MeshObjectSelectionPlugin()
Default destructor.
void colorizeHalfedgeSelection(int objectId, int r, int g, int b, int a)
Colorize the edge selection.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
void lassoSelect(QRegion &_region, PrimitiveType _primitiveType, bool _deselection)
Lasso selection tool.
IdList getEdgeSelection(int objectId)
Return a list of all selected edges.
void invertEdgeSelection(int objectId)
Unselect all Edges.
void update_regions(MeshT *_mesh)
Update face selection to correspond to the vertex selection.
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
void floodFillSelection(MeshT *_mesh, int _objectId, uint _fh, double _maxAngle, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are connected (and do not exceed the maximum dihedral angle) ...
void clearVertexSelection(int _objectId)
Unselect all vertices.
void clearEdgeSelection(int objectId)
Invert the current edge selection.
void growVertexSelection(int _objectId)
Grow the current vertex selection.
void loadFlipperModelingSelection(int _objectId, QString _filename)
Load a selection from an Flipper selection file for the given object.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:137
void colorizeVertexSelection(int _objectId, int _r, int _g, int _b, int a)
Colorize the vertex selection.
ACG::Vec4f areaColor_
Handle to selection environment.
Traverse the scenegraph and call the selection function for all mesh nodes.
ACG::GLState & glState()
Get the glState of the Viewer.
const UpdateType UPDATE_SELECTION_VERTICES(UpdateTypeSet(32))
Vertex selection has changed.
bool initializeOptionsWidget(QWidget *&_widget)
Initialize the Options Widget.
void colorizeFaceSelection(int objectId, int r, int g, int b, int a)
Colorize the face selection.