42 #include "HoleFillerPlugin.hh" 43 #include "holefillerToolbar.hh" 46 #include "HoleInfoT.hh" 48 #include <QProgressDialog> 50 #define HOLEINFO "HoleInfoData" 62 if ( OpenFlipper::Options::gui()) {
74 QIcon* toolIcon =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"holefilling.png");
76 emit addToolbox( tr(
"Hole Filler") ,
tool_ , toolIcon);
83 if ( OpenFlipper::Options::gui()) {
84 emit addPickMode(
"Separator");
85 emit addPickMode(
"Hole Filler");
91 emit setSlotDescription(
"fillAllHoles(int)", tr(
"Fill all holes from a given Mesh"),
92 QString(
"objectId").split(
","), QString(
"Id of the mesh").split(
","));
94 emit setSlotDescription(
"fillHole(int,int)", tr(
"Fill a holes from a given Mesh where edgeHandle is on the boundary"),
95 QString(
"objectId,edgeHandle").split(
","), QString(
"Id of the mesh,Handle of one boundary edge of the hole").split(
","));
101 QModelIndexList indices =
tool_->tableWidget->selectionModel()->selectedRows();
104 for (
int i=0; i < indices.size(); i++){
108 _holeIds.push_back ( holeID );
109 _objIds.push_back( objID );
117 std::vector< int > holes;
118 std::vector< int > objects;
122 QProgressDialog progress(tr(
"Filling holes..."), tr(
"Abort"), 0, holes.size(), 0);
123 progress.setWindowModality(Qt::ApplicationModal);
124 progress.setValue(0);
141 o_it->setObjectData(HOLEINFO, holeInfo);
145 for (uint i = 0; i < objects.size(); i++)
146 if ( objects[i] == o_it->id() ){
149 if (progress.wasCanceled())
152 progress.setValue(++counter);
165 emit log(
LOGWARN, tr(
"HoleFilling unsupported for poly meshes") );
170 if (progress.wasCanceled())
182 std::vector< int > holes;
183 std::vector< int > objects;
200 o_it->setObjectData(HOLEINFO, holeInfo);
204 MeshSelection::clearEdgeSelection(mesh);
207 for (uint i = 0; i < objects.size(); i++)
208 if ( objects[i] == o_it->id() )
212 if ( (objects.size() == 1) && (holes.size() == 1) && ( objects[0] == o_it->id() ) ){
222 object->boundingBox(_bbMin, _bbMax);
241 o_it->setObjectData(HOLEINFO, holeInfo);
245 MeshSelection::clearEdgeSelection(mesh);
248 for (uint i = 0; i < objects.size(); i++)
249 if ( objects[i] == o_it->id() )
253 if ( (objects.size() == 1) && (holes.size() == 1) && ( objects[0] == o_it->id() ) ){
263 object->boundingBox(_bbMin, _bbMax);
281 emit log(
LOGWARN, tr(
"Error for holeMapping_ vector size") );
290 emit log(
LOGWARN, tr(
"Unable to find object for hole (should not happen!!)") );
304 object->setObjectData(HOLEINFO, holeInfo);
321 emit log(
LOGWARN,tr(
"HoleFilling unsupported for poly meshes"));
337 if ( holeInfo == 0 ){
340 o_it->setObjectData(HOLEINFO, holeInfo);
354 o_it->setObjectData(HOLEINFO, holeInfo);
373 bool updated =
false;
410 tool_->tableWidget->clear();
412 tool_->tableWidget->setRowCount ( 0 );
413 tool_->tableWidget->setColumnCount ( 4 );
415 QStringList headerdata;
416 headerdata <<
"Object" <<
"Edges" <<
"Boundary Length" <<
"BB Diagonal";
418 tool_->tableWidget->setHorizontalHeaderLabels(headerdata);
419 tool_->updateGeometry();
434 elements += holeInfo->
holes()->size();
435 tool_->tableWidget->setRowCount ( elements );
438 for (uint i = 0 ; i < holeInfo->
holes()->size() ; ++i ) {
440 QTableWidgetItem*
name =
new QTableWidgetItem( o_it->name() );
441 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 444 name->setFlags( Qt::ItemFlags() );
446 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
447 tool_->tableWidget->setItem(count,0,name);
449 size_t egde_count = 0;
451 double boundaryLength = 0.0;
453 holeInfo->
getHoleInfo(i, egde_count, bbDiagonal, boundaryLength);
456 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( egde_count ) );
457 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 460 size->setFlags( Qt::ItemFlags() );
462 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
463 tool_->tableWidget->setItem(count,1,size);
466 QTableWidgetItem* boundaryLengthWidget =
new QTableWidgetItem( QString::number(boundaryLength) );
467 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 468 boundaryLengthWidget->setFlags( 0 );
470 boundaryLengthWidget->setFlags( Qt::ItemFlags() );
472 boundaryLengthWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
473 tool_->tableWidget->setItem(count,2,boundaryLengthWidget);
475 QTableWidgetItem* bbDiagonalWidget =
new QTableWidgetItem( QString::number(bbDiagonal) );
476 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 477 bbDiagonalWidget->setFlags( 0 );
479 bbDiagonalWidget->setFlags( Qt::ItemFlags() );
481 bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
482 tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
485 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
498 elements += holeInfo->
holes()->size();
499 tool_->tableWidget->setRowCount ( elements );
502 for (uint i = 0 ; i < holeInfo->
holes()->size() ; ++i ) {
504 QTableWidgetItem*
name =
new QTableWidgetItem( o_it->name() );
505 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 508 name->setFlags( Qt::ItemFlags() );
510 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
511 tool_->tableWidget->setItem(count,0,name);
513 size_t egde_count = 0;
514 double boundaryLength = 0.0;
517 holeInfo->
getHoleInfo(i, egde_count, boundaryLength, bbDiagonal);
520 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( egde_count ) );
521 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 524 size->setFlags( Qt::ItemFlags() );
526 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
527 tool_->tableWidget->setItem(count,1,size);
530 QTableWidgetItem* radius =
new QTableWidgetItem( QString::number(boundaryLength) );
531 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 532 radius->setFlags( 0 );
534 radius->setFlags( Qt::ItemFlags() );
536 radius->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
537 tool_->tableWidget->setItem(count,2,radius);
540 QTableWidgetItem* bbDiagonalWidget =
new QTableWidgetItem( QString::number(bbDiagonal) );
541 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 542 bbDiagonalWidget->setFlags( 0 );
544 bbDiagonalWidget->setFlags( Qt::ItemFlags() );
546 bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
547 tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
550 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
558 tool_->tableWidget->resizeColumnToContents ( 1 );
567 emit log(
LOGERR, tr(
"Could not get object from ID.") );
571 emit scriptInfo(
"fillAllHoles( ObjectId )" );
584 object->setObjectData(HOLEINFO, holeInfo);
601 emit log(
LOGERR, tr(
"HoleFilling unsopported for poly meshes.") );
613 emit log(
LOGERR, tr(
"Could not get object from ID.") );
617 emit scriptInfo(
"fillHole( ObjectId , EdgeHandle )" );
630 object->setObjectData(HOLEINFO, holeInfo);
634 TriMesh::EdgeHandle eh(_edgeHandle);
636 if ( !eh.is_valid() || !mesh->is_boundary(eh) ){
637 emit log(
LOGERR, tr(
"Invalid edge handle.") );
655 emit log(
LOGERR, tr(
"HoleFilling unsopported for poly meshes.") );
void getSelectedHoles(std::vector< int > &_holeIds, std::vector< int > &_objIds)
get a map from objectID to (selected) holeIDs
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(8))
Topology updated.
#define DATA_TRIANGLE_MESH
void detectButton()
detect holes on all objects
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void initializePlugin()
Initialize the toolbox widget.
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
Kernel::Normal Normal
Normal type.
Type for a Meshobject containing a poly mesh.
HoleFillerPlugin()
Constructor.
Kernel::Point Point
Coordinate type.
void slotItemSelectionChanged()
slot for displaying selected holes
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(16))
Selection updated.
void getHoleInfo(const unsigned int _index, size_t &_edges, typename MeshT::Scalar &_diagonal, typename MeshT::Scalar &_boundaryLength) const
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
const QStringList ALL_OBJECTS
Iterable object range.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
bool dataType(DataType _type) const
void selectHole(int _index)
select a hole with given index
QString name()
Return a name for the plugin.
void slotObjectUpdated(int _identifier, const UpdateType &_type)
check for holes if an object has changed
std::vector< std::pair< int, int > > holeMapping_
map from the index in the table to (object-id, hole-id)
void fillAllHoles(int _stages=3)
fill all holes
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
Functions for selection on a mesh.
void fillAllHoles(int _objectID)
fill all holes from a given object
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
Type for a MeshObject containing a triangle mesh.
Kernel::Scalar Scalar
Scalar type.
ObjectRange objects(IteratorRestriction _restriction, DataType _dataType)
Iterable object range.
void fillHole(int _index, int _stages=3)
fill hole with given index
bool contains(const UpdateType &_type) const
Check if this update contains the given UpdateType.
void getHoles()
get all holes and store them internally
void getHolePostitionInfo(const int _index, typename MeshT::Normal &_holeNormal, typename MeshT::Point &_holeCenter) const
Collect information to fly to a hole.
std::vector< std::vector< typename MeshT::EdgeHandle > > * holes()
get the holes vector
void fillHole(int _objectID, int _edgeHandle)
fill a hole in given object where _edgeHandle is on the boundary
void pluginsInitialized()
add PickModes after initialization
void slotCellDoubleClicked(int _row, int _col)
Slot for filling holes from double-clicked rows.
void slotFillSelection()
Fill all selected holes.
HoleFillerToolbarWidget * tool_
Widget for Toolbox.
void update_menu()
update the entries in the tableWidget
void flyTo(const ACG::Vec3d &_position, const ACG::Vec3d &_center, double _time)
Fly to point and viewing direction (animated).