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() );
442 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
443 tool_->tableWidget->setItem(count,0,name);
445 size_t egde_count = 0;
447 double boundaryLength = 0.0;
449 holeInfo->
getHoleInfo(i, egde_count, bbDiagonal, boundaryLength);
452 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( egde_count ) );
454 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
455 tool_->tableWidget->setItem(count,1,size);
458 QTableWidgetItem* boundaryLengthWidget =
new QTableWidgetItem( QString::number(boundaryLength) );
459 boundaryLengthWidget->setFlags( 0 );
460 boundaryLengthWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
461 tool_->tableWidget->setItem(count,2,boundaryLengthWidget);
463 QTableWidgetItem* bbDiagonalWidget =
new QTableWidgetItem( QString::number(bbDiagonal) );
464 bbDiagonalWidget->setFlags( 0 );
465 bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
466 tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
469 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
482 elements += holeInfo->
holes()->size();
483 tool_->tableWidget->setRowCount ( elements );
486 for (uint i = 0 ; i < holeInfo->
holes()->size() ; ++i ) {
488 QTableWidgetItem*
name =
new QTableWidgetItem( o_it->name() );
490 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
491 tool_->tableWidget->setItem(count,0,name);
493 size_t egde_count = 0;
494 double boundaryLength = 0.0;
497 holeInfo->
getHoleInfo(i, egde_count, boundaryLength, bbDiagonal);
500 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( egde_count ) );
502 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
503 tool_->tableWidget->setItem(count,1,size);
506 QTableWidgetItem* radius =
new QTableWidgetItem( QString::number(boundaryLength) );
507 radius->setFlags( 0 );
508 radius->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
509 tool_->tableWidget->setItem(count,2,radius);
512 QTableWidgetItem* bbDiagonalWidget =
new QTableWidgetItem( QString::number(bbDiagonal) );
513 bbDiagonalWidget->setFlags( 0 );
514 bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
515 tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
518 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
526 tool_->tableWidget->resizeColumnToContents ( 1 );
535 emit log(
LOGERR, tr(
"Could not get object from ID.") );
539 emit scriptInfo(
"fillAllHoles( ObjectId )" );
552 object->setObjectData(HOLEINFO, holeInfo);
569 emit log(
LOGERR, tr(
"HoleFilling unsopported for poly meshes.") );
581 emit log(
LOGERR, tr(
"Could not get object from ID.") );
585 emit scriptInfo(
"fillHole( ObjectId , EdgeHandle )" );
598 object->setObjectData(HOLEINFO, holeInfo);
602 TriMesh::EdgeHandle eh(_edgeHandle);
604 if ( !eh.is_valid() || !mesh->is_boundary(eh) ){
605 emit log(
LOGERR, tr(
"Invalid edge handle.") );
623 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_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry 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.
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 UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
const QStringList ALL_OBJECTS
Iterable object range.
bool dataType(DataType _type) const
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
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.
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
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
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).