Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  size_t 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  size_t 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  size_t 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  size_t 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  size_t 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<size_t, size_t> > 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  {
2240  triObj->setSelectionColor(statusColor_);
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 
picks only visible front verices (may not be implemented for all nodes)
Definition: BaseNode.hh:115
SelectionInterface::PrimitiveType vertexType_
Primitive type handles:
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:192
void deleteVertexSelection(int _objectId)
Delete vertices and faces that are currently selected.
bool initializeOptionsWidget(QWidget *&_widget)
Initialize the Options Widget.
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
Definition: GLState.hh:242
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
ACG::Vec4f statusColor_
Handle to selection environment.
IdList getVertexSelection(int _objectId)
Return a list of all selected vertices.
void clearHalfedgeSelection(int objectId)
Invert the current edge selection.
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
void componentsMeshSelection(MeshT *_mesh, int _objectId, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Connected component mesh selection.
void invertVertexSelection(int _objectId)
Invert the current vertex selection.
unsigned int id() const
Definition: BaseNode.hh:454
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a toggle selection.
virtual bool picked(uint _node_idx)
detect if the node has been picked
void invertFaceSelection(int objectId)
Invert the current face selection.
void shrinkVertexSelection(int _objectId)
Shrink the current vertex selection.
void setAllHandleVertices(int objectId)
Set all vertices to be part of the handle area.
void setAreaColor(const ACG::Vec4f &_color)
set color for areas
Definition: MeshObjectT.cc:491
void setSelectionColor(const ACG::Vec4f &_color)
set color for selection
Definition: MeshObjectT.cc:472
IdList getHandleVertices(int objectId)
Get a list of all handle vertices.
bool updateGL() const
should GL matrices be updated after each matrix operation
Definition: GLState.hh:240
void slotFloodFillSelection(QMouseEvent *_event, double _maxAngle, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a flood fill selection.
void clearEdgeSelection(int objectId)
Invert the current edge selection.
IdList getHalfedgeSelection(int objectId)
Return a list of all selected edges.
IdList getEdgeSelection(int objectId)
Return a list of all selected edges.
void addedEmptyObject(int _id)
An empty object has been added.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
void colorizeFaceSelection(int objectId, int r, int g, int b, int a)
Colorize the face selection.
void createMeshFromSelection(MeshT &_mesh, MeshT &_newMesh, PrimitiveType _primitiveType)
Create a new mesh from the selection.
void selectVertices(int objectId, IdList _vertexList)
select given vertices
bool volumeSelection(MeshT *_mesh, int _objectId, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
Traverse the scenegraph and call the selection function for all mesh nodes.
ACG::Vec4f handleColor_
Handle to selection environment.
QVector< QPoint > volumeLassoPoints_
Used for volume lasso tool.
ACG::GLState & glState()
Get the glState of the Viewer.
void selectAllHalfedges(int objectId)
Select all Halfedges.
IdList convertHalfedgesToVertexPairs(int _id, const IdList &_halfedges)
Convert halfedge ids to vertex pairs.
void clearFaceSelection(int objectId)
Unselect all faces.
void selectEdges(int objectId, IdList _vertexList)
Select given Edges.
MeshObjectSelectionPlugin()
Default constructor.
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:439
void update_regions(MeshT *_mesh)
Update face selection to correspond to the vertex selection.
Class for the handling of simple configuration files.
Definition: INIFile.hh:105
bool getObject(int _identifier, BSplineCurveObject *&_object)
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void unselectModelingVertices(int objectId, IdList _vertexList)
Remove vertices from modeling area.
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:263
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
int id() const
Definition: BaseObject.cc:201
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:73
void selectAllFaces(int objectId)
Select all faces.
void updateColorValues()
Set descriptions for local public slots.
void slotLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a lasso selection.
void shrinkFaceSelection(int objectId)
Shrink the current face selection.
void invertEdgeSelection(int objectId)
Unselect all Edges.
void slotSphereSelection(QMouseEvent *_event, double _radius, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a sphere selection.
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
void invertHalfedgeSelection(int objectId)
Unselect all Halfedges.
void traceEdgePath(int objectId, double threshold)
Trace Edge Path.
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:70
SelectionInterface::PrimitiveType edgeType_
Handle to selection environment.
void slotSaveSelection(INIFile &_file)
Save selection for all objects in the scene.
~MeshObjectSelectionPlugin()
Default destructor.
void selectFaces(int objectId, IdList _facesList)
Select given faces.
void colorizeHalfedgeSelection(int objectId, int r, int g, int b, int a)
Colorize the edge selection.
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) ...
ConversionDialog * conversionDialog_
Handle to selection environment.
void deleteFaceSelection(int _objectId)
Delete face that are currently selected.
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.
IdList getModelingVertices(int objectId)
Get a list of all modeling vertices.
void unselectVertices(int objectId, IdList _vertexList)
unselect given vertices
void setColorForSelection(const int _objectId, const PrimitiveType _primitiveType)
Set color for selection.
void growVertexSelection(int _objectId)
Grow the current vertex selection.
void selectHalfedges(int objectId, IdList _vertexList)
Select given Halfedges.
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
ACG::SceneGraph::BaseNode * getRootNode()
Get the root node for data objects.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
ACG::Vec4f featureColor_
Handle to selection environment.
void toggleMeshSelection(int _objectId, MeshT *_mesh, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Toggle mesh selection.
void setAllModelingVertices(int objectId)
Set all vertices to be part of the modeling area.
void deleteEdgeSelection(int _objectId)
Delete edges that are currently selected.
void clearHandleVertices(int objectId)
Clear handle Area.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
void slotLoadSelection(const INIFile &_file)
Load selection for specific objects in the scene.
void growFaceSelection(int objectId)
Grow the current face selection.
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers)
One of the previously registered keys has been pressed.
void convertSelection(const int &_objectId, const QString &_from, const QString &_to, bool _deselect)
Convert the selection on one object.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a volume lasso selection.
picks faces (should be implemented for all nodes)
Definition: BaseNode.hh:104
void slotSelectionOperation(QString _operation)
A specific operation is requested.
void unselectHandleVertices(int objectId, IdList _vertexList)
Remove vertices from handle area.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
void unselectFaces(int objectId, IdList _facesList)
Unselect given faces.
IdList convertEdgesToVertexPairs(int _id, const IdList &_edges)
Convert edge ids to vertex pairs.
QtColorChooserButton * colorButtonSelection_
Options.
SelectionInterface::PrimitiveType faceType_
Handle to selection environment.
picks only visible front edges (may not be implemented for all nodes)
Definition: BaseNode.hh:113
Functions for selection on a mesh.
void conversion(const QString &_from, const QString &_to, bool _deselect)
Convert the selection on all target objects.
QtColorChooserButton * colorButtonFeature_
Handle to selection environment.
IdList getFaceSelection(int objectId)
Return a list of all selected faces.
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
Predefined datatypes.
Definition: DataTypes.hh:96
void colorizeEdgeSelection(int objectId, int r, int g, int b, int a)
Colorize the edge 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
IdList convertVertexPairsToEdges(int _id, const IdList &_vertices)
Inverse of function above.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
const QStringList ALL_OBJECTS
Iterable object range.
void updateSlotDescriptions()
Set descriptions for local public slots.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
void conversionRequested()
Show selection conversion dialog.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
void setHandleColor(const ACG::Vec4f &_color)
set color for handles
Definition: MeshObjectT.cc:527
SelectionInterface::PrimitiveType allSupportedTypes_
Handle to selection environment.
void closestBoundarySelection(MeshT *_mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are incident to closest boundary.
void lassoSelect(QRegion &_region, PrimitiveType _primitiveType, bool _deselection)
Lasso selection tool.
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:143
bool operator()(BaseNode *_node)
Traverse the scenegraph and call the selection function for all mesh nodes.
QtColorChooserButton * colorButtonHandle_
Handle to selection environment.
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:76
QStringList IteratorRestriction
Iterable object range.
QString environmentHandle_
Handle to selection environment.
void setFeatureColor(const ACG::Vec4f &_color)
set color for features
Definition: MeshObjectT.cc:509
void slotClosestBoundarySelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a closest boundary selection.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
void colorizeVertexSelection(int _objectId, int _r, int _g, int _b, int a)
Colorize the vertex selection.
IdList convertVertexPairsToHalfedges(int _id, const IdList &_vertices)
Inverse of function above.
void selectBoundaryFaces(int objectId)
Select all boundary faces of the given object.
void selectBoundaryVertices(int _objectId)
Select all boundary vertices of the given object.
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::Vec4f areaColor_
Handle to selection environment.
void setDefaultColorValues()
sets the default color values for selection/handle/region/feature nodes for all objects of this type ...
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
void slotComponentsSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a connected components selection.
QtColorChooserButton * colorButtonArea_
Handle to selection environment.
void slotMouseWheelEvent(QWheelEvent *event, std::string const &mode)
Wheel Event from main application.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
void selectBoundaryEdges(int objectId)
select boundary edges
bool scenegraphRegionPick(ACG::SceneGraph::PickTarget _pickTarget, const QRegion &_region, QList< QPair< size_t, size_t > > &_list, QVector< float > *_depths, QVector< ACG::Vec3d > *_points)
void selectBoundaryHalfedges(int objectId)
Select boundary edges.
void selectAllEdges(int objectId)
Select all Edges.
void clearModelingVertices(int objectId)
Clear Modeling Area.
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.
Kernel::FaceVertexIter FaceVertexIter
Circulator.
Definition: PolyMeshT.hh:170
void selectHandleVertices(int objectId, IdList _vertexList)
Set vertices to be part of the handle area.
void selectAllVertices(int _objectId)
Select all Vertices.
void unselectEdges(int objectId, IdList _vertexList)
Unselect given Edges.
void clearVertexSelection(int _objectId)
Unselect all vertices.