Developer Documentation
HoleFillerPlugin.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 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 #include "HoleFillerPlugin.hh"
51 
53 
54 #if QT_VERSION >= 0x050000
55 #else
56 #include <QtGui>
57 #endif
58 
59 #include "HoleInfoT.hh"
60 
61 #define HOLEINFO "HoleInfoData"
62 
65  tool_(0)
66 {
67 
68 }
69 
72 {
74  QSize size(300, 300);
75  tool_->resize(size);
76 
77  connect(tool_->tableWidget,SIGNAL(itemSelectionChanged()),this,SLOT(slotItemSelectionChanged()));
78 
79  connect(tool_->tableWidget,SIGNAL(cellDoubleClicked(int,int)),this,SLOT(slotCellDoubleClicked(int,int)));
80 
81  connect(tool_->detect,SIGNAL(clicked()),this,SLOT(detectButton()));
82  connect(tool_->fillButton, SIGNAL(clicked()), this, SLOT(slotFillSelection()) );
83 
84  QIcon* toolIcon = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"holefilling.png");
85 
86  emit addToolbox( tr("Hole Filler") , tool_ , toolIcon);
87 }
88 
91 {
92  emit addPickMode("Separator");
93  emit addPickMode("Hole Filler");
94 
95  emit setSlotDescription("fillAllHoles(int)", tr("Fill all holes from a given Mesh"),
96  QString("objectId").split(","), QString("Id of the mesh").split(","));
97 
98  emit setSlotDescription("fillHole(int,int)", tr("Fill a holes from a given Mesh where edgeHandle is on the boundary"),
99  QString("objectId,edgeHandle").split(","), QString("Id of the mesh,Handle of one boundary edge of the hole").split(","));
100 
101  //build the tableWidget with headers
102  update_menu();
103 }
104 
105 void HoleFillerPlugin::getSelectedHoles(std::vector<int>& _holeIds, std::vector<int>& _objIds)
106 {
107  QModelIndexList indices = tool_->tableWidget->selectionModel()->selectedRows();
108 
109  //get a map from objectID to (selected) holeIDs
110  for (int i=0; i < indices.size(); i++){
111  int objID = holeMapping_[ indices[i].row() ].first;
112  int holeID = holeMapping_[ indices[i].row() ].second;
113 
114  _holeIds.push_back ( holeID );
115  _objIds.push_back( objID );
116  }
117 }
118 
121 
122  //get a map from objectID to (selected) holeIDs
123  std::vector< int > holes;
124  std::vector< int > objects;
125  getSelectedHoles(holes,objects);
126 
127  //init progressDialog
128  QProgressDialog progress(tr("Filling holes..."), tr("Abort"), 0, holes.size(), 0);
129  progress.setWindowModality(Qt::ApplicationModal);
130  progress.setValue(0);
131 
132  int counter = 0;
133 
134  //iterate over all objects with holes that should be filled
136 
137  // TYPE is TRIMESH
138  if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
139 
140  TriMesh* mesh = PluginFunctions::triMesh(o_it);
141 
142  //get perObjectData
143  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( o_it->objectData(HOLEINFO) );
144 
145  if (holeInfo == 0){
146  holeInfo = new HoleInfo< TriMesh >( mesh );
147  o_it->setObjectData(HOLEINFO, holeInfo);
148  }
149 
150  //fill the holes
151  for (uint i = 0; i < objects.size(); i++)
152  if ( objects[i] == o_it->id() ){
153  holeInfo->fillHole( holes[i]);
154 
155  if (progress.wasCanceled())
156  break;
157  else
158  progress.setValue(++counter);
159  }
160 
161  //update the object
162  emit updatedObject(o_it->id(),UPDATE_ALL);
163 
164  holeInfo->getHoles();
165 
166  update_menu();
167  emit createBackup( o_it->id(), "Hole Filling", UPDATE_GEOMETRY | UPDATE_TOPOLOGY | UPDATE_SELECTION);
168  }
169  // DATATYPE is POLYMESH
170  else if ( o_it->dataType( DATA_POLY_MESH ) ) {
171  emit log(LOGWARN, tr("HoleFilling unsupported for poly meshes") );
172  continue;
173  }
174 
175  //abort if user wants to
176  if (progress.wasCanceled())
177  break;
178  }
179 
180  progress.close();
181 
182  emit updateView();
183 }
184 
187 
188  std::vector< int > holes;
189  std::vector< int > objects;
190  getSelectedHoles(holes,objects);
191 
192  //iterate over all objects with holes that should be displayed
194 
195  // TYPE is TRIMESH
196  if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
197 
199  TriMesh* mesh = PluginFunctions::triMesh(o_it);
200 
201  //get perObjectData
202  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( o_it->objectData(HOLEINFO) );
203 
204  if (holeInfo == 0){
205  holeInfo = new HoleInfo< TriMesh >( mesh );
206  o_it->setObjectData(HOLEINFO, holeInfo);
207  }
208 
209  //clear the edge selection
210  MeshSelection::clearEdgeSelection(mesh);
211 
212  //select the holes
213  for (uint i = 0; i < objects.size(); i++)
214  if ( objects[i] == o_it->id() )
215  holeInfo->selectHole( holes[i] );
216 
217  // We only fly if we have exacly one object and one hole
218  if ( (objects.size() == 1) && (holes.size() == 1) && ( objects[0] == o_it->id() ) ){
219 
220  TriMesh::Point center;
221  TriMesh::Normal normal;
222  holeInfo->getHolePostitionInfo(holes[0], normal, center);
223 
224  // Get bounding box to get a scaling for the movement
225  TriMesh::Point _bbMin;
226  TriMesh::Point _bbMax;
227 
228  object->boundingBox(_bbMin, _bbMax);
229 
230  PluginFunctions::flyTo(center + normal * (_bbMax-_bbMin).length() , center, 10.0);
231  }
232 
233  //update the object
234  emit updatedObject(o_it->id(),UPDATE_SELECTION);
235  }
236  // DATATYPE is POLYMESH
237  else if ( o_it->dataType( DATA_POLY_MESH ) ) {
238 
240  PolyMesh* mesh = PluginFunctions::polyMesh(o_it);
241 
242  //get perObjectData
243  HoleInfo< PolyMesh >* holeInfo = dynamic_cast< HoleInfo< PolyMesh >* > ( o_it->objectData(HOLEINFO) );
244 
245  if (holeInfo == 0){
246  holeInfo = new HoleInfo< PolyMesh >( mesh );
247  o_it->setObjectData(HOLEINFO, holeInfo);
248  }
249 
250  //clear the edge selection
251  MeshSelection::clearEdgeSelection(mesh);
252 
253  //select the holes
254  for (uint i = 0; i < objects.size(); i++)
255  if ( objects[i] == o_it->id() )
256  holeInfo->selectHole( holes[i] );
257 
258  // We only fly if we have exacly one object and one hole
259  if ( (objects.size() == 1) && (holes.size() == 1) && ( objects[0] == o_it->id() ) ){
260 
261  PolyMesh::Point center;
262  PolyMesh::Normal normal;
263  holeInfo->getHolePostitionInfo(holes[0], normal, center);
264 
265  // Get bounding box to get a scaling for the movement
266  PolyMesh::Point _bbMin;
267  PolyMesh::Point _bbMax;
268 
269  object->boundingBox(_bbMin, _bbMax);
270 
271  PluginFunctions::flyTo(center + normal * (_bbMax-_bbMin).length() , center, 10.0);
272  }
273 
274  //update the object
275  emit updatedObject(o_it->id(),UPDATE_SELECTION);
276 
277  }
278  }
279 
280  emit updateView();
281 }
282 
284 void HoleFillerPlugin::slotCellDoubleClicked(int _row , int /*_col*/) {
285 
286  if ( _row > (int)holeMapping_.size() ) {
287  emit log(LOGWARN, tr("Error for holeMapping_ vector size") );
288  return;
289  }
290 
291  BaseObjectData* object;
292  int objID = holeMapping_[_row].first;
293  int holeID = holeMapping_[_row].second;
294 
295  if ( !PluginFunctions::getObject( objID, object ) ) {
296  emit log(LOGWARN, tr("Unable to find object for hole (should not happen!!)") );
297  return;
298  }
299 
300  // TYPE is TRIMESH
301  if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
302 
303  TriMesh* mesh = PluginFunctions::triMesh(object);
304 
305  //get perObjectData
306  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( object->objectData(HOLEINFO) );
307 
308  if (holeInfo == 0){
309  holeInfo = new HoleInfo< TriMesh >( mesh );
310  object->setObjectData(HOLEINFO, holeInfo);
311  }
312 
313  //fill the hole
314  holeInfo->fillHole( holeID );
315 
316  emit updatedObject(object->id(),UPDATE_ALL);
317 
318  holeInfo->getHoles();
319 
320  update_menu();
321 
322  emit updateView();
323  }
324  // DATATYPE is POLYMESH
325  else if ( object->dataType( DATA_POLY_MESH ) ) {
326 
327  emit log(LOGWARN,tr("HoleFilling unsupported for poly meshes"));
328 
329  return;
330  }
331 }
332 
335 {
337 
338  //case TRIMESH
339  if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
340 
341  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( o_it->objectData(HOLEINFO) );
342 
343  if ( holeInfo == 0 ){
344  TriMesh* mesh = PluginFunctions::triMesh(*o_it);
345  holeInfo = new HoleInfo< TriMesh >( mesh );
346  o_it->setObjectData(HOLEINFO, holeInfo);
347  }
348 
349  holeInfo->getHoles();
350  }
351 
352  //case POLYMESH
353  if ( o_it->dataType( DATA_POLY_MESH ) ) {
354 
355  HoleInfo< PolyMesh >* holeInfo = dynamic_cast< HoleInfo< PolyMesh >* > ( o_it->objectData(HOLEINFO) );
356 
357  if (holeInfo == 0){
358  PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
359  holeInfo = new HoleInfo< PolyMesh >( mesh );
360  o_it->setObjectData(HOLEINFO, holeInfo);
361  }
362 
363  holeInfo->getHoles();
364  }
365  }
366 
367  update_menu();
368 }
369 
371 void HoleFillerPlugin::slotObjectUpdated( int _identifier, const UpdateType& _type ) {
372 
373  BaseObjectData* object;
374 
375  // Check if this is a usable Object
376  if ( !PluginFunctions::getObject(_identifier,object) )
377  return;
378 
379  bool updated = false;
380 
381  if ( _type.contains(UPDATE_TOPOLOGY) ) {
382 
383  // get holes for TRIMESH
384  if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
385 
386  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( object->objectData(HOLEINFO) );
387 
388  if ( holeInfo ) {
389  holeInfo->getHoles();
390  updated = true;
391  }
392  }
393 
394  // get holes for POLYMESH
395  else if ( object->dataType( DATA_POLY_MESH ) ) {
396 
397  HoleInfo< PolyMesh >* holeInfo = dynamic_cast< HoleInfo< PolyMesh >* > ( object->objectData(HOLEINFO) );
398 
399  if ( holeInfo ) {
400  holeInfo->getHoles();
401  updated = true;
402  }
403  }
404  }
405 
406  // Only update if something has changed!
407  if ( updated )
408  update_menu();
409 }
410 
413 
414  holeMapping_.clear();
415 
416  tool_->tableWidget->clear();
417 
418  tool_->tableWidget->setRowCount ( 0 );
419  tool_->tableWidget->setColumnCount ( 4 );
420 
421  QStringList headerdata;
422  headerdata << "Object" << "Edges" << "Boundary Length" << "BB Diagonal";
423 
424  tool_->tableWidget->setHorizontalHeaderLabels(headerdata);
425  tool_->updateGeometry();
426 
427  int elements = 0;
428  int count = 0;
429 
430  //iterate over all objects
432 
433  // DATATYPE is TRIMESH
434  if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
435 
436  //get perObjectData
437  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( o_it->objectData(HOLEINFO) );
438 
439  if (holeInfo != 0){
440  elements += holeInfo->holes()->size();
441  tool_->tableWidget->setRowCount ( elements );
442 
443  //add holes to the table
444  for (uint i = 0 ; i < holeInfo->holes()->size() ; ++i ) {
445  // Set Name of the object
446  QTableWidgetItem* name = new QTableWidgetItem( o_it->name() );
447  name->setFlags( 0 );
448  name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
449  tool_->tableWidget->setItem(count,0,name);
450 
451  size_t egde_count = 0;
452  double boundaryLength = 0.0;
453  TriMesh::Scalar bbDiagonal = 0.0;
454 
455  holeInfo->getHoleInfo(i, egde_count, boundaryLength, bbDiagonal);
456 
457  // Set Number of the edges
458  QTableWidgetItem* size = new QTableWidgetItem( QString::number( egde_count ) );
459  size->setFlags( 0 );
460  size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
461  tool_->tableWidget->setItem(count,1,size);
462 
463  // Set boundary Length
464  QTableWidgetItem* boundaryLengthWidget = new QTableWidgetItem( QString::number(boundaryLength) );
465  boundaryLengthWidget->setFlags( 0 );
466  boundaryLengthWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
467  tool_->tableWidget->setItem(count,2,boundaryLengthWidget);
468 
469  QTableWidgetItem* bbDiagonalWidget = new QTableWidgetItem( QString::number(bbDiagonal) );
470  bbDiagonalWidget->setFlags( 0 );
471  bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
472  tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
473 
474  // remember the id for the hole
475  holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
476 
477  ++count;
478  }
479  }
480  }
481  // DATATYPE is POLYMESH
482  else if ( o_it->dataType( DATA_POLY_MESH ) ) {
483 
484  //get perObjectData
485  HoleInfo< PolyMesh >* holeInfo = dynamic_cast< HoleInfo< PolyMesh >* > ( o_it->objectData(HOLEINFO) );
486 
487  if (holeInfo != 0){
488  elements += holeInfo->holes()->size();
489  tool_->tableWidget->setRowCount ( elements );
490 
491  //add holes to the table
492  for (uint i = 0 ; i < holeInfo->holes()->size() ; ++i ) {
493  // Set Name of the object
494  QTableWidgetItem* name = new QTableWidgetItem( o_it->name() );
495  name->setFlags( 0 );
496  name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
497  tool_->tableWidget->setItem(count,0,name);
498 
499  size_t egde_count = 0;
500  double boundaryLength = 0.0;
501  TriMesh::Scalar bbDiagonal = 0.0;
502 
503  holeInfo->getHoleInfo(i, egde_count, boundaryLength, bbDiagonal);
504 
505  // Set Number of the edges
506  QTableWidgetItem* size = new QTableWidgetItem( QString::number( egde_count ) );
507  size->setFlags( 0 );
508  size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
509  tool_->tableWidget->setItem(count,1,size);
510 
511  // Set Bounding box diagonal
512  QTableWidgetItem* radius = new QTableWidgetItem( QString::number(boundaryLength) );
513  radius->setFlags( 0 );
514  radius->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
515  tool_->tableWidget->setItem(count,2,radius);
516 
517  // Set Bounding box diagonal
518  QTableWidgetItem* bbDiagonalWidget = new QTableWidgetItem( QString::number(bbDiagonal) );
519  bbDiagonalWidget->setFlags( 0 );
520  bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
521  tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
522 
523  // remember the id for the hole
524  holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
525 
526  ++count;
527  }
528  }
529  }
530  }
531 
532  tool_->tableWidget->resizeColumnToContents ( 1 );
533 }
534 
536 void HoleFillerPlugin::fillAllHoles(int _objectID){
537  BaseObjectData* object = 0;
538  PluginFunctions::getObject( _objectID , object );
539 
540  if (object == 0){
541  emit log(LOGERR, tr("Could not get object from ID.") );
542  return;
543  }
544 
545  emit scriptInfo( "fillAllHoles( ObjectId )" );
546 
547 
548  // TYPE is TRIMESH
549  if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
550 
551  TriMesh* mesh = PluginFunctions::triMesh(object);
552 
553  //get perObjectData
554  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( object->objectData(HOLEINFO) );
555 
556  if (holeInfo == 0){
557  holeInfo = new HoleInfo< TriMesh >( mesh );
558  object->setObjectData(HOLEINFO, holeInfo);
559  }
560 
561  //fill the hole
562  holeInfo->fillAllHoles();
563 
564  //and update everything
565  emit updatedObject(object->id(),UPDATE_ALL);
566 
567  holeInfo->getHoles();
568 
569  update_menu();
570 
571  emit updateView();
572  }
573  // DATATYPE is POLYMESH
574  else if ( object->dataType( DATA_POLY_MESH ) ) {
575  emit log(LOGERR, tr("HoleFilling unsopported for poly meshes.") );
576  return;
577  }
578 }
579 
580 
582 void HoleFillerPlugin::fillHole(int _objectID, int _edgeHandle){
583  BaseObjectData* object = 0;
584  PluginFunctions::getObject( _objectID , object );
585 
586  if (object == 0){
587  emit log(LOGERR, tr("Could not get object from ID.") );
588  return;
589  }
590 
591  emit scriptInfo( "fillHole( ObjectId , EdgeHandle )" );
592 
593 
594  // TYPE is TRIMESH
595  if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
596 
597  TriMesh* mesh = PluginFunctions::triMesh(object);
598 
599  //get perObjectData
600  HoleInfo< TriMesh >* holeInfo = dynamic_cast< HoleInfo< TriMesh >* > ( object->objectData(HOLEINFO) );
601 
602  if (holeInfo == 0){
603  holeInfo = new HoleInfo< TriMesh >( mesh );
604  object->setObjectData(HOLEINFO, holeInfo);
605  }
606 
607  //check edgeHandle
608  TriMesh::EdgeHandle eh(_edgeHandle);
609 
610  if ( !eh.is_valid() || !mesh->is_boundary(eh) ){
611  emit log(LOGERR, tr("Invalid edge handle.") );
612  return;
613  }
614 
615  //fill the hole
616  holeInfo->fillHole( eh );
617 
618  //and update everything
619  emit updatedObject(object->id(),UPDATE_ALL);
620 
621  holeInfo->getHoles();
622 
623  update_menu();
624 
625  emit updateView();
626  }
627  // DATATYPE is POLYMESH
628  else if ( object->dataType( DATA_POLY_MESH ) ) {
629  emit log(LOGERR, tr("HoleFilling unsopported for poly meshes.") );
630  return;
631  }
632 }
633 
634 #if QT_VERSION < 0x050000
635 Q_EXPORT_PLUGIN2( holefillerplugin , HoleFillerPlugin );
636 #endif
637 
std::vector< std::pair< int, int > > holeMapping_
map from the index in the table to (object-id, hole-id)
void slotItemSelectionChanged()
slot for displaying selected holes
void fillHole(int _objectID, int _edgeHandle)
fill a hole in given object where _edgeHandle is on the boundary
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:73
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
void fillAllHoles(int _stages=3)
fill all holes
Definition: HoleInfoT.cc:215
void pluginsInitialized()
add PickModes after initialization
bool getObject(int _identifier, BSplineCurveObject *&_object)
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
void detectButton()
detect holes on all objects
void slotFillSelection()
Fill all selected holes.
void getHoleInfo(const unsigned int _index, size_t &_edges, typename MeshT::Scalar &_diagonal, typename MeshT::Scalar &_boundaryLength) const
Definition: HoleInfoT.cc:264
void slotCellDoubleClicked(int _row, int _col)
Slot for filling holes from double-clicked rows.
int id() const
Definition: BaseObject.cc:201
const QStringList ALL_OBJECTS
Iterable object range.
Update type class.
Definition: UpdateType.hh:70
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:117
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
void flyTo(const ACG::Vec3d &_position, const ACG::Vec3d &_center, double _time)
Fly to point and viewing direction (animated).
QString name()
Return a name for the plugin.
Functions for selection on a mesh.
bool contains(const UpdateType &_type) const
Check if this update contains the given UpdateType.
Definition: UpdateType.cc:111
HoleFillerToolbarWidget * tool_
Widget for Toolbox.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
void slotObjectUpdated(int _identifier, const UpdateType &_type)
check for holes if an object has changed
void initializePlugin()
Initialize the toolbox widget.
void getHolePostitionInfo(const int _index, typename MeshT::Normal &_holeNormal, typename MeshT::Point &_holeCenter) const
Collect information to fly to a hole.
Definition: HoleInfoT.cc:242
void fillHole(int _index, int _stages=3)
fill hole with given index
Definition: HoleInfoT.cc:177
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
void fillAllHoles(int _objectID)
fill all holes from a given object
void getSelectedHoles(std::vector< int > &_holeIds, std::vector< int > &_objIds)
get a map from objectID to (selected) holeIDs
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:70
void getHoles()
get all holes and store them internally
Definition: HoleInfoT.cc:75
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
std::vector< std::vector< typename MeshT::EdgeHandle > > * holes()
get the holes vector
Definition: HoleInfoT.cc:298
HoleFillerPlugin()
Constructor.
void selectHole(int _index)
select a hole with given index
Definition: HoleInfoT.cc:227
void update_menu()
update the entries in the tableWidget
Kernel::Scalar Scalar
Scalar type.
Definition: PolyMeshT.hh:113
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.