Developer Documentation
BSplineSurfaceSelectionPlugin.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43  * *
44  * $Revision$ *
45  * $Author$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 #include "BSplineSurfaceSelectionPlugin.hh"
51 
53 
54 // Primitive type icons
55 #define CONTROL_POINT_TYPE "bscontrolpointselection.png"
56 #define KNOT_TYPE "bsknotselection.png"
57 // =======================================
58 // Define operations
59 // =======================================
60 // General Operations:
61 #define G_CP_MODE "Control Point Selection View"
62 #define G_K_MODE "Knot Selection View"
63 
64 // Control points:
65 #define CP_SELECT_ALL "Select All Control Points"
66 #define CP_DESELECT_ALL "Deselect All Control Points"
67 #define CP_INVERT "Invert Control Point Selection"
68 //#define CP_DELETE_U "Delete Selected Control Points in U"
69 //#define CP_DELETE_V "Delete Selected Control Points in V"
70 
71 // Knots:
72 #define K_SELECT_ALL "Select All Knots"
73 #define K_DESELECT_ALL "Deselect All Knots"
74 #define K_INVERT "Invert Knot Selection"
75 //#define K_DELETE_U "Delete Selected Knots in U"
76 //#define K_DELETE_V "Delete Selected Knots in V"
77 
80 controlPointType_(0),
81 knotType_(0),
82 allSupportedTypes_(0) {
83 }
84 
85 //==============================================================================================
86 
88 }
89 
90 //==============================================================================================
91 
92 void BSplineSurfaceSelectionPlugin::initializePlugin() {
93 
94  // Tell core about all scriptable slots
96 }
97 
98 //==============================================================================================
99 
100 void BSplineSurfaceSelectionPlugin::pluginsInitialized() {
101  // Create new selection environment for skeletons
102  // and register skeleton data type for the environment.
103 
104  QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
105 
106  emit addSelectionEnvironment("B-Spline Surface Selections", "Select B-Spline surface primitives.",
107  iconPath + "bsplinesurface.png", environmentHandle_);
108 
109  // Register mesh object types
110  emit registerType(environmentHandle_, DATA_BSPLINE_SURFACE);
111 
112  emit addPrimitiveType(environmentHandle_, "Select Control Points", iconPath + CONTROL_POINT_TYPE, controlPointType_);
113  emit addPrimitiveType(environmentHandle_, "Select Knots", iconPath + KNOT_TYPE, knotType_);
114 
116 
117  // Determine, which selection modes are requested
118  emit showToggleSelectionMode(environmentHandle_, true, allSupportedTypes_);
119  emit showVolumeLassoSelectionMode(environmentHandle_, true, allSupportedTypes_);
120 
121  QStringList generalOperations;
122  generalOperations.append(G_CP_MODE);
123  generalOperations.append(G_K_MODE);
124 
125  // Define control point and knot operations
126  QStringList controlPointOperations;
127  controlPointOperations.append(CP_SELECT_ALL);
128  controlPointOperations.append(CP_DESELECT_ALL);
129 // controlPointOperations.append(CP_DELETE_U);
130 // controlPointOperations.append(CP_DELETE_V);
131  controlPointOperations.append(CP_INVERT);
132 
133  QStringList knotOperations;
134  knotOperations.append(K_SELECT_ALL);
135  knotOperations.append(K_DESELECT_ALL);
136 // knotOperations.append(K_DELETE_U);
137 // knotOperations.append(K_DELETE_V);
138  knotOperations.append(K_INVERT);
139 
140  emit addSelectionOperations(environmentHandle_, generalOperations, "Selection Operations");
141  emit addSelectionOperations(environmentHandle_, controlPointOperations, "Control Point Operations", controlPointType_);
142  emit addSelectionOperations(environmentHandle_, knotOperations, "Knot Operations", knotType_);
143 
144  // Register key shortcuts:
145 
146  // Select (a)ll
147  emit registerKeyShortcut(Qt::Key_A, Qt::ControlModifier);
148  // (C)lear selection
149  emit registerKeyShortcut(Qt::Key_C, Qt::NoModifier);
150  // (I)nvert selection
151  emit registerKeyShortcut(Qt::Key_I, Qt::NoModifier);
152 }
153 
154 //==============================================================================================
155 
157 
158  emit setSlotDescription("selectAllControlPoints(int)", tr("Select all control points of a B-spline surface"),
159  QStringList("objectId"), QStringList("Id of object"));
160  emit setSlotDescription("deselectAllControlPoints(int)", tr("Deselect all control points of a B-spline surface"),
161  QStringList("objectId"), QStringList("Id of object"));
162  emit setSlotDescription("invertControlPointSelection(int)", tr("Invert control point selection"),
163  QStringList("objectId"), QStringList("Id of object"));
164  emit setSlotDescription("deleteSelectedControlPoints(int)", tr("Delete selected control points"),
165  QStringList("objectId"), QStringList("Id of object"));
166  emit setSlotDescription("selectControlPoints(int,IdList)", tr("Select the specified control points"),
167  QString("objectId,control pointList").split(","), QString("Id of object,List of control points").split(","));
168 
169  emit setSlotDescription("loadSelection(int,QString)", tr("Load selection from selection file"),
170  QString("objectId,filename").split(","), QString("Id of an object,Selection file").split(","));
171 
172  emit setSlotDescription("selectAllKnots(int)", tr("Select all knots of a B-spline surface"),
173  QStringList("objectId"), QStringList("Id of object"));
174  emit setSlotDescription("deselectAllKnots(int)", tr("Deselect all knots of a B-spline surface"),
175  QStringList("objectId"), QStringList("Id of object"));
176  emit setSlotDescription("invertKnotSelection(int)", tr("Invert knot selection"),
177  QStringList("objectId"), QStringList("Id of object"));
178  emit setSlotDescription("deleteSelectedKnots(int)", tr("Delete selected knots"),
179  QStringList("objectId"), QStringList("Id of object"));
180  emit setSlotDescription("selectKnots(int,IdList)", tr("Select the specified knots"),
181  QString("objectId,knotList").split(","), QString("Id of object,List of knots").split(","));
182 }
183 
184 //==============================================================================================
185 
187 
188  SelectionInterface::PrimitiveType type = 0u;
189  emit getActivePrimitiveType(type);
190 
191  if((type & allSupportedTypes_) == 0)
192  return;
193 
194  // Test if operation should be applied to target objects only
195  bool targetsOnly = false;
196  emit targetObjectsOnly(targetsOnly);
199 
200  if(_operation == G_CP_MODE) {
201  // Set selection view mode
203  } else if(_operation == G_K_MODE) {
204  // Set selection view mode
206  } else if(_operation == CP_SELECT_ALL) {
207  // Select all control points
209  o_it != PluginFunctions::objectsEnd(); ++o_it) {
210  if (o_it->visible()) {
211  selectAllControlPoints(o_it->id());
212  }
213 
214  emit updatedObject(o_it->id(), UPDATE_SELECTION);
215  emit createBackup(o_it->id(), "Select All Controlpoints", UPDATE_SELECTION);
216  }
217  } else if (_operation == CP_DESELECT_ALL) {
218  // Deselect all control points
220  o_it != PluginFunctions::objectsEnd(); ++o_it) {
221  if (o_it->visible()) {
222  deselectAllControlPoints(o_it->id());
223  }
224 
225  emit updatedObject(o_it->id(), UPDATE_SELECTION);
226  emit createBackup(o_it->id(), "Deselect All Controlpoints", UPDATE_SELECTION);
227  }
228  } else if (_operation == CP_INVERT) {
229  // Invert control point selection
231  o_it != PluginFunctions::objectsEnd(); ++o_it) {
232  if (o_it->visible()) {
233  invertControlPointSelection(o_it->id());
234  }
235 
236  emit updatedObject(o_it->id(), UPDATE_SELECTION);
237  emit createBackup(o_it->id(), "Invert Controlpoint Selection", UPDATE_SELECTION);
238  }
239 // } else if (_operation == CP_DELETE_U) {
240 // // Delete control point selection
241 // for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_BSPLINE_SURFACE));
242 // o_it != PluginFunctions::objectsEnd(); ++o_it) {
243 // if (o_it->visible()) {
244 // deleteSelectedControlPointsU(o_it->id());
245 // }
246 //
247 // emit updatedObject(o_it->id(), UPDATE_SELECTION);
248 // }
249 // } else if (_operation == CP_DELETE_V) {
250 // // Delete control point selection
251 // for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_BSPLINE_SURFACE));
252 // o_it != PluginFunctions::objectsEnd(); ++o_it) {
253 // if (o_it->visible()) {
254 // deleteSelectedControlPointsV(o_it->id());
255 // }
256 //
257 // emit updatedObject(o_it->id(), UPDATE_SELECTION);
258 // }
259  } else if(_operation == K_SELECT_ALL) {
260  // Select all control points
262  o_it != PluginFunctions::objectsEnd(); ++o_it) {
263  if (o_it->visible()) {
264  selectAllKnots(o_it->id());
265  }
266 
267  emit updatedObject(o_it->id(), UPDATE_SELECTION);
268  emit createBackup(o_it->id(), "Select All Knots", UPDATE_SELECTION);
269  }
270  } else if (_operation == K_DESELECT_ALL) {
271  // Deselect all control points
273  o_it != PluginFunctions::objectsEnd(); ++o_it) {
274  if (o_it->visible()) {
275  deselectAllKnots(o_it->id());
276  }
277 
278  emit updatedObject(o_it->id(), UPDATE_SELECTION);
279  emit createBackup(o_it->id(), "Deselect All Knots", UPDATE_SELECTION);
280  }
281  } else if (_operation == K_INVERT) {
282  // Invert knot selection
284  o_it != PluginFunctions::objectsEnd(); ++o_it) {
285  if (o_it->visible()) {
286  invertKnotSelection(o_it->id());
287  }
288 
289  emit updatedObject(o_it->id(), UPDATE_SELECTION);
290  emit createBackup(o_it->id(), "Invert Knot Selection", UPDATE_SELECTION);
291  }
292 // } else if (_operation == K_DELETE_U) {
293 // // Delete knot selection
294 // for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_BSPLINE_SURFACE));
295 // o_it != PluginFunctions::objectsEnd(); ++o_it) {
296 // if (o_it->visible()) {
297 // deleteSelectedKnotsU(o_it->id());
298 // }
299 //
300 // emit updatedObject(o_it->id(), UPDATE_SELECTION);
301 // }
302 // } else if (_operation == K_DELETE_V) {
303 // // Delete knot selection
304 // for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_BSPLINE_SURFACE));
305 // o_it != PluginFunctions::objectsEnd(); ++o_it) {
306 // if (o_it->visible()) {
307 // deleteSelectedKnotsV(o_it->id());
308 // }
309 //
310 // emit updatedObject(o_it->id(), UPDATE_SELECTION);
311 // }
312  }
313 }
314 
315 //==============================================================================================
316 
317 void BSplineSurfaceSelectionPlugin::slotToggleSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
318 
319  // Return if none of the currently active types is handled by this plugin
320  if((_currentType & allSupportedTypes_) == 0) return;
321 
322  if (_currentType & controlPointType_) {
323 
324  size_t node_idx, target_idx;
325  ACG::Vec3d hit_point;
326 
327  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_VERTEX, _event->pos(), node_idx, target_idx, &hit_point)) {
328 
329  BaseObjectData* object = 0;
330 
331  if (PluginFunctions::getPickedObject(node_idx, object)) {
332 
334 
335  // toggle selection
337 
338  unsigned int max = bsso->splineSurface()->n_control_points_m() * bsso->splineSurface()->n_control_points_n();
339 
340  if ( target_idx < max) {
341 
342  int idx_m = target_idx / bsso->splineSurface()->n_control_points_n();
343  int idx_n = target_idx % bsso->splineSurface()->n_control_points_n();
344 
345  if (bsso->splineSurface()->controlpoint_selected(idx_m, idx_n) || _deselect) {
346  bsso->splineSurface()->deselect_controlpoint(idx_m, idx_n);
347  } else {
348  bsso->splineSurface()->select_controlpoint(idx_m, idx_n);
349  }
350  }
351  }
353  emit updatedObject(bsso->id(), UPDATE_SELECTION);
354  emit createBackup(bsso->id(), "Toggle Selection", UPDATE_SELECTION);
355  }
356  }
357  }
358 
359  if (_currentType & knotType_) {
360 
361  size_t node_idx, target_idx;
362  ACG::Vec3d hit_point;
363 
364  if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_SPLINE, _event->pos(),node_idx, target_idx, &hit_point)) {
365 
366  BaseObjectData* object = 0;
367 
368  if (PluginFunctions::getPickedObject(node_idx, object)) {
369 
371  BSplineSurface * bss = bsso->splineSurface();
372 
373  // toggle selection
374  if(bss->get_knotvector_m_ref()->selections_available() &&
375  bss->get_knotvector_n_ref()->selections_available()) {
376 
377  // the target index we are getting here refers to the respective texel in the picking-texture
378  // hence, we have to compute the actual u,v coordinates from this texel
379  // given the uv coord, we finally compute the closes knot in u and v direction, respectively
380 
381  int numKnots_m = bss->n_knots_m();
382  int numKnots_n = bss->n_knots_n();
383  int order_m = bss->degree_m() + 1;
384  int order_n = bss->degree_n() + 1;
385 
386  Knotvector * knotvec_u = bss->get_knotvector_m_ref();
387  Knotvector * knotvec_v = bss->get_knotvector_n_ref();
388 
389  double minu = knotvec_u->getKnot(bss->degree_m());
390  double minv = knotvec_v->getKnot(bss->degree_n());
391  double maxu = knotvec_u->getKnot(numKnots_m - order_m);
392  double maxv = knotvec_v->getKnot(numKnots_n - order_n);
393 
394  double udiff = maxu - minu;
395  double vdiff = maxv - minv;
396 
397  int texres = bsso->splineSurfaceNode()->pick_texture_res();
398  double curu = double (target_idx / texres) / double(texres) * udiff + minu;
399  double curv = double (target_idx % texres) / double(texres) * vdiff + minv;
400 
401  ACG::Vec2d found_params(curu, curv);
402 
403  // knots closest to parameters of hitpoint on the surface
404  ACG::Vec2i interval_m = bss->interval_m(curu);
405  ACG::Vec2i interval_n = bss->interval_n(curv);
406 
407  int knotIdx_m = interval_m[0];
408  int knotIdx_n = interval_n[0];
409 
410  if ( !bss->get_knotvector_m_ref()->selected( knotIdx_m ) ||
411  !bss->get_knotvector_n_ref()->selected( knotIdx_n )) {
412 
413  bss->get_knotvector_m_ref()->select( knotIdx_m );
414  bss->get_knotvector_n_ref()->select( knotIdx_n );
415  }
416  else {
417  bss->get_knotvector_m_ref()->deselect( knotIdx_m );
418  bss->get_knotvector_n_ref()->deselect( knotIdx_n );
419  }
420 
421  } // end of if selections available
422 
424  emit updatedObject(bsso->id(), UPDATE_SELECTION);
425  emit createBackup(bsso->id(), "Toggle Selection", UPDATE_SELECTION);
426  }
427  }
428  }
429 }
430 
431 //==============================================================================================
432 
433 void BSplineSurfaceSelectionPlugin::slotVolumeLassoSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
434 
435  // Return if none of the currently active types is handled by this plugin
436  if((_currentType & allSupportedTypes_) == 0) return;
437 
438  ACG::Vec3d hit_point;
439 
440  if(_event->type() == QEvent::MouseButtonPress) {
441 
443  QPoint p(_event->pos().x(), state.viewport_height() - _event->pos().y());
444 
445  volumeLassoPoints_.append(p);
446 
447  return;
448 
449  } else if(_event->type() == QEvent::MouseButtonDblClick) {
450 
452 
453  QPolygon polygon(volumeLassoPoints_);
454 
455  bool targetsOnly = false;
456  emit targetObjectsOnly(targetsOnly);
459 
460  // Select all primitives that lie in this region
462  o_it != PluginFunctions::objectsEnd(); ++o_it) {
463 
464  if (o_it->visible()) {
465 
468 
469  if(surface) {
470 
471  if(_currentType & controlPointType_) {
472  // Select control points
473  if(!surface->controlpoint_selections_available()) return;
474 
475  // Enable control point texture mode
477 
478  for(unsigned int i = 0; i < surface->n_control_points_m(); ++i) {
479  for(unsigned int j = 0; j < surface->n_control_points_n(); ++j) {
480 
481  ACG::Vec3d c = surface->get_control_point(i, j);
482  ACG::Vec3d pc = state.project(c);
483  QPoint p((int)pc[0], (int)pc[1]);
484  if(polygon.containsPoint(p, Qt::OddEvenFill)) {
485  if(_deselect)
486  surface->deselect_controlpoint(i,j);
487  else
488  surface->select_controlpoint(i,j);
489  }
490  }
491  }
492 
493  }
494 
495  if(_currentType & knotType_) {
496  // Select knots
497  if(!surface->get_knotvector_m_ref()->selections_available()) return;
498  if(!surface->get_knotvector_n_ref()->selections_available()) return;
499 
500  // Enable knot texture mode
502 
503  int numKnots_m = surface->n_knots_m();
504  int numKnots_n = surface->n_knots_n();
505 
506  int order_m = surface->degree_m() + 1;
507  int order_n = surface->degree_n() + 1;
508 
509  Knotvector* knotvec_m = surface->get_knotvector_m_ref();
510  Knotvector* knotvec_n = surface->get_knotvector_n_ref();
511 
512  // Go over all B-spline surface knot midpoints and test
513  // if computed position on surface lies within the polygon
514  if(surface->degree_m() == 0) return;
515  if(surface->degree_n() == 0) return;
516 
517  if((int)surface->n_knots_m() <= ((numKnots_m - order_m) + 1)) return;
518  if((int)surface->n_knots_n() <= ((numKnots_n - order_n) + 1)) return;
519 
520  for(int i = surface->degree_m()-1; i < (numKnots_m - order_m)-1; ++i) {
521  for(int j = surface->degree_n()-1; j < (numKnots_n - order_n)-1; ++j) {
522 
523  double baseKnot_m = knotvec_m->getKnot(i+1);
524  double baseKnot_n = knotvec_n->getKnot(j+1);
525 
526  double dhalfu = 0.5*(knotvec_m->getKnot(i+2) - baseKnot_m);
527  double dhalfv = 0.5*(knotvec_n->getKnot(j+2) - baseKnot_n);
528 
529  double t_u = baseKnot_m + dhalfu;
530  double t_v = baseKnot_n + dhalfv;
531 
532  // Project surface point
533  ACG::Vec3d pcp = state.project(surface->surfacePoint(t_u, t_v));
534 
535  QPoint p((int)pcp[0], (int)pcp[1]);
536 
537  if(polygon.containsPoint(p, Qt::OddEvenFill)) {
538  if(_deselect) {
539  knotvec_m->deselect(i+1);
540  knotvec_n->deselect(j+1);
541  } else {
542  knotvec_m->select(i+1);
543  knotvec_n->select(j+1);
544  }
545  }
546  }
547  }
548  }
549  }
550  }
551 
552  emit updatedObject(o_it->id(), UPDATE_SELECTION);
553  emit createBackup(o_it->id(), "Lasso Selection", UPDATE_SELECTION);
554  }
555 
556  // Clear lasso points
557  volumeLassoPoints_.clear();
558  }
559 }
560 
561 //==============================================================================================
562 
563 void BSplineSurfaceSelectionPlugin::loadSelection(int _objId, const QString& _filename) {
564 
565  // Load ini file
566  INIFile file;
567 
568  if(!file.connect(_filename, false)) {
569  emit log(LOGERR, QString("Could not read file '%1'!").arg(_filename));
570  return;
571  }
572 
573  // Load selection from file
574  loadIniFile(file, _objId);
575 }
576 
577 //==============================================================================================
578 
579 void BSplineSurfaceSelectionPlugin::loadIniFile(INIFile& _ini, int _id) {
580  // From INI Interface
581  // Load plugin specific settings
582 }
583 
584 //==============================================================================================
585 
586 void BSplineSurfaceSelectionPlugin::saveIniFile(INIFile& _ini, int _id) {
587  // From INI Interface
588  // Save plugin specific settings
589 }
590 
591 //==============================================================================================
592 
594 
595  // Iterate over all B-spline surfaces in the scene and save
596  // the selections for all supported entity types
598  o_it != PluginFunctions::objectsEnd(); ++o_it) {
599 
600  // Read section for each object
601  // Append object name to section identifier
602  QString section = QString("BSplineSurfaceSelection") + "//" + o_it->name();
603  if(!_file.section_exists(section)) {
604  continue;
605  }
606 
607  std::vector<int> ids;
608  // Read control point selection:
609  _file.get_entry(ids, section, "ControlPointSelection");
610  selectControlPoints(o_it->id(), ids);
611  ids.clear();
612  // Read knot selection:
613  std::vector<int> ids_u;
614  std::vector<int> ids_v;
615 
616  _file.get_entry(ids_u, section, "KnotSelection_u");
617  _file.get_entry(ids_v, section, "KnotSelection_v");
618 
619  selectKnots(o_it->id(), ids_u, ids_v);
620 
621  emit updatedObject(o_it->id(), UPDATE_SELECTION);
622  emit createBackup(o_it->id(), "Load Selection", UPDATE_SELECTION);
623  }
624 
626 }
627 
628 //==============================================================================================
629 
631 
632  // Iterate over all B-spline surfaces in the scene and save
633  // the selections for all entity types
635  o_it != PluginFunctions::objectsEnd(); ++o_it) {
636 
637  // Create section for each object
638  // Append object name to section identifier
639  QString section = QString("BSplineSurfaceSelection") + "//" + o_it->name();
640 
641  // Store control point selection
642  _file.add_entry(section, "ControlPointSelection", getControlPointSelection(o_it->id()));
643  // Store knot selection
644  _file.add_entry(section, "KnotSelection_u", getKnotSelectionU(o_it->id()));
645  _file.add_entry(section, "KnotSelection_v", getKnotSelectionV(o_it->id()));
646  }
647 }
648 
649 //==============================================================================================
650 
651 void BSplineSurfaceSelectionPlugin::slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) {
652 
653  SelectionInterface::PrimitiveType type = 0u;
654  emit getActivePrimitiveType(type);
655 
656  if((type & allSupportedTypes_) == 0) {
657  // No supported type is active
658  return;
659  }
660 
661  bool targetsOnly = false;
662  emit targetObjectsOnly(targetsOnly);
665 
666  if(_key == Qt::Key_A && _modifiers == Qt::ControlModifier) {
667  // Select all
669  o_it != PluginFunctions::objectsEnd(); ++o_it) {
670  if (o_it->visible()) {
671  if(type & controlPointType_) selectAllControlPoints(o_it->id());
672  if(type & knotType_) selectAllKnots(o_it->id());
673  }
674  emit updatedObject(o_it->id(), UPDATE_SELECTION);
675  emit createBackup(o_it->id(), "Select All", UPDATE_SELECTION);
676  }
677  } else if(_key == Qt::Key_C && _modifiers == Qt::NoModifier) {
678  // Deselect all
680  o_it != PluginFunctions::objectsEnd(); ++o_it) {
681  if (o_it->visible()) {
682  if(type & controlPointType_) deselectAllControlPoints(o_it->id());
683  if(type & knotType_) deselectAllKnots(o_it->id());
684  }
685  emit updatedObject(o_it->id(), UPDATE_SELECTION);
686  emit createBackup(o_it->id(), "Clear Selection", UPDATE_SELECTION);
687  }
688  } else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
689  // Invert selection
691  o_it != PluginFunctions::objectsEnd(); ++o_it) {
692  if (o_it->visible()) {
693  if(type & controlPointType_) invertControlPointSelection(o_it->id());
694  if(type & knotType_) invertKnotSelection(o_it->id());
695  }
696  emit updatedObject(o_it->id(), UPDATE_SELECTION);
697  emit createBackup(o_it->id(), "Invert Selection", UPDATE_SELECTION);
698  }
699  }
700 }
701 
703 
705  o_it != PluginFunctions::objectsEnd(); ++o_it) {
706 
708  if(_mode == CP) {
710  }
711  else {
713  }
714 
715  emit updatedObject(o_it->id(), UPDATE_SELECTION);
716  }
717 }
718 
719 //==============================================================================================
720 
721 
722 
void slotLoadSelection(const INIFile &_file)
Load selection for specific objects in the scene.
bool controlpoint_selections_available() const
Check if control point selection property is available.
Knotvector * get_knotvector_n_ref()
Get a reference to the knotvector in n direction.
ACG::Vec2i interval_n(double _t)
Returns the index of the knots v and v+1 such that t in [v, v+1)
Point & get_control_point(unsigned int _m, unsigned int _n)
Returns a reference to the control point (m, n)
int degree_n() const
Returns the spline degree in n direction.
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
void invertControlPointSelection(int _objectId)
Invert control point selection.
void slotSaveSelection(INIFile &_file)
Save selection for all objects in the scene.
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a toggle selection.
int id() const
Definition: BaseObject.cc:190
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
unsigned int n_knots_n()
Returns the number of knots in n direction.
void selectAllControlPoints(int _objectId)
Select all control points of a curve.
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
Pick spline curve or surface (picks u or u,v coords respectively)
Definition: PickTarget.hh:92
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a volume lasso selection.
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
void selectAllKnots(int _objectId)
Select all knots of a curve.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
QStringList IteratorRestriction
Iterable object range.
IdList getControlPointSelection(int _objectId)
Get current control point selection.
Knotvector * get_knotvector_m_ref()
Get a reference to the knotvector in m direction.
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:70
BSplineSurface * splineSurface(BaseObjectData *_object)
Get a Bspline Surface from an object.
void invertKnotSelection(int _objectId)
Invert knot selection.
void selectKnots(int _objectId, const IdList &_ids_u, const IdList &_ids_v, bool _deselect=false)
Select specific knots of a curve.
const QStringList ALL_OBJECTS
Iterable object range.
IdList getKnotSelectionU(int _objectId)
Get current knot selection.
ACG::Vec2i interval_m(double _t)
Returns the index of the knots u and u+1 such that t in [u, u+1)
Point surfacePoint(double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
IdList getKnotSelectionV(int _objectId)
Select all control points of a curve.
QString environmentHandle_
Handle to selection environment.
void slotSelectionOperation(QString _operation)
A specific operation is requested.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers)
One of the previously registered keys has been pressed.
unsigned int knotType_
Handle to selection environment.
unsigned int controlPointType_
Primitive type handles:
unsigned int n_control_points_n() const
Returns the number of controlpoints in n direction.
int viewport_height() const
get viewport height
Definition: GLState.hh:824
#define DATA_BSPLINE_SURFACE
unsigned int n_control_points_m() const
Returns the number of controlpoints in m direction.
SelectionViewMode
Change selection view mode for every B-spline surface in the scene.
unsigned int n_knots_m()
Returns the number of knots in m direction.
void deselectAllKnots(int _objectId)
Deselect all knots of a curve.
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
Predefined datatypes.
Definition: DataTypes.hh:83
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
void selectControlPoints(int _objectId, const IdList &_ids, bool _deselect=false)
Delete selected control points.
BSplineSurface * splineSurface()
return a pointer to the spline curve
ACG::GLState & glState()
Get the glState of the Viewer.
ACG::SceneGraph::BSplineSurfaceNodeT< BSplineSurface > * splineSurfaceNode()
Return pointer to the bspline surface node.
BSplineSurfaceSelectionPlugin()
Default constructor.
~BSplineSurfaceSelectionPlugin()
Default destructor.
void deselectAllControlPoints(int _objectId)
Deselect all control points of a curve.
BSplineSurfaceObject * bsplineSurfaceObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineSurfaceObject if possible.
void setSelectionViewMode(const SelectionViewMode _mode)
Change selection view mode for every B-spline surface in the scene.
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
int degree_m() const
Returns the spline degree in m direction.
unsigned int allSupportedTypes_
Handle to selection environment.
Class for the handling of simple configuration files.
Definition: INIFile.hh:99
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433