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