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