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