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