50 #include "HoleFillerPlugin.hh"
54 #if QT_VERSION >= 0x050000
59 #include "HoleInfoT.hh"
61 #define HOLEINFO "HoleInfoData"
84 QIcon* toolIcon =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"holefilling.png");
86 emit addToolbox( tr(
"Hole Filler") ,
tool_ , toolIcon);
92 emit addPickMode(
"Separator");
93 emit addPickMode(
"Hole Filler");
95 emit setSlotDescription(
"fillAllHoles(int)", tr(
"Fill all holes from a given Mesh"),
96 QString(
"objectId").split(
","), QString(
"Id of the mesh").split(
","));
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(
","));
107 QModelIndexList indices =
tool_->tableWidget->selectionModel()->selectedRows();
110 for (
int i=0; i < indices.size(); i++){
114 _holeIds.push_back ( holeID );
115 _objIds.push_back( objID );
123 std::vector< int > holes;
124 std::vector< int > objects;
128 QProgressDialog progress(tr(
"Filling holes..."), tr(
"Abort"), 0, holes.size(), 0);
129 progress.setWindowModality(Qt::ApplicationModal);
130 progress.setValue(0);
147 o_it->setObjectData(HOLEINFO, holeInfo);
151 for (uint i = 0; i < objects.size(); i++)
152 if ( objects[i] == o_it->id() ){
155 if (progress.wasCanceled())
158 progress.setValue(++counter);
171 emit log(
LOGWARN, tr(
"HoleFilling unsupported for poly meshes") );
176 if (progress.wasCanceled())
188 std::vector< int > holes;
189 std::vector< int > objects;
205 o_it->setObjectData(HOLEINFO, holeInfo);
209 MeshSelection::clearEdgeSelection(mesh);
212 for (uint i = 0; i < objects.size(); i++)
213 if ( objects[i] == o_it->id() )
229 o_it->setObjectData(HOLEINFO, holeInfo);
233 MeshSelection::clearEdgeSelection(mesh);
236 for (uint i = 0; i < objects.size(); i++)
237 if ( objects[i] == o_it->id() )
253 emit log(
LOGWARN, tr(
"Error for holeMapping_ vector size") );
262 emit log(
LOGWARN, tr(
"Unable to find object for hole (should not happen!!)") );
276 object->setObjectData(HOLEINFO, holeInfo);
304 emit log(
LOGWARN,tr(
"HoleFilling unsupported for poly meshes"));
319 if ( holeInfo == 0 ){
322 o_it->setObjectData(HOLEINFO, holeInfo);
355 bool updated =
false;
392 tool_->tableWidget->clear();
394 tool_->tableWidget->setRowCount ( 0 );
395 tool_->tableWidget->setColumnCount ( 4 );
397 QStringList headerdata;
398 headerdata <<
"Object" <<
"Edges" <<
"Boundary Length" <<
"BB Diagonal";
400 tool_->tableWidget->setHorizontalHeaderLabels(headerdata);
401 tool_->updateGeometry();
416 elements += holeInfo->
holes()->size();
417 tool_->tableWidget->setRowCount ( elements );
420 for (uint i = 0 ; i < holeInfo->
holes()->size() ; ++i ) {
422 QTableWidgetItem*
name =
new QTableWidgetItem( o_it->name() );
424 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
425 tool_->tableWidget->setItem(count,0,name);
428 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( (*holeInfo->
holes())[i].size() ) );
430 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
431 tool_->tableWidget->setItem(count,1,size);
434 std::vector< TriMesh::EdgeHandle >::iterator endIter = (*holeInfo->
holes())[i].end();
435 double boundaryLength = 0.0;
438 for (std::vector< TriMesh::EdgeHandle >::iterator edgeIter = (*holeInfo->
holes())[i].begin(); edgeIter != endIter; ++edgeIter)
439 boundaryLength += mesh->calc_edge_length(*edgeIter);
440 QTableWidgetItem* boundaryLengthWidget =
new QTableWidgetItem( QString::number(boundaryLength) );
441 boundaryLengthWidget->setFlags( 0 );
442 boundaryLengthWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
443 tool_->tableWidget->setItem(count,2,boundaryLengthWidget);
446 TriMesh::Point minCoord = TriMesh::Point(std::numeric_limits<TriMesh::Scalar>::max(),std::numeric_limits<TriMesh::Scalar>::max(),std::numeric_limits<TriMesh::Scalar>::max());
447 TriMesh::Point maxCoord = TriMesh::Point(-std::numeric_limits<TriMesh::Scalar>::max(),-std::numeric_limits<TriMesh::Scalar>::max(),-std::numeric_limits<TriMesh::Scalar>::max());
448 for (std::vector< TriMesh::EdgeHandle >::iterator edgeIter = (*holeInfo->
holes())[i].begin(); edgeIter != endIter; ++edgeIter)
450 TriMesh::Point pos = mesh->point(mesh->from_vertex_handle(mesh->halfedge_handle(*edgeIter,0)));
451 minCoord[0] = std::min(minCoord[0],pos[0]);
452 minCoord[1] = std::min(minCoord[1],pos[1]);
453 minCoord[2] = std::min(minCoord[2],pos[2]);
455 maxCoord[0] = std::max(maxCoord[0],pos[0]);
456 maxCoord[1] = std::max(maxCoord[1],pos[1]);
457 maxCoord[2] = std::max(maxCoord[2],pos[2]);
460 TriMesh::Scalar bbDiagonal = (minCoord-maxCoord).length();
462 QTableWidgetItem* bbDiagonalWidget =
new QTableWidgetItem( QString::number(bbDiagonal) );
463 bbDiagonalWidget->setFlags( 0 );
464 bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
465 tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
468 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
481 elements += holeInfo->
holes()->size();
482 tool_->tableWidget->setRowCount ( elements );
485 for (uint i = 0 ; i < holeInfo->
holes()->size() ; ++i ) {
487 QTableWidgetItem*
name =
new QTableWidgetItem( o_it->name() );
489 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
490 tool_->tableWidget->setItem(count,0,name);
493 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( (*holeInfo->
holes())[i].size() ) );
495 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
496 tool_->tableWidget->setItem(count,1,size);
499 QTableWidgetItem* radius =
new QTableWidgetItem(
"TODO" );
500 radius->setFlags( 0 );
501 radius->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
502 tool_->tableWidget->setItem(count,2,radius);
505 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
513 tool_->tableWidget->resizeColumnToContents ( 1 );
522 emit log(
LOGERR, tr(
"Could not get object from ID.") );
526 emit scriptInfo(
"fillAllHoles( ObjectId )" );
539 object->setObjectData(HOLEINFO, holeInfo);
556 emit log(
LOGERR, tr(
"HoleFilling unsopported for poly meshes.") );
568 emit log(
LOGERR, tr(
"Could not get object from ID.") );
572 emit scriptInfo(
"fillHole( ObjectId , EdgeHandle )" );
585 object->setObjectData(HOLEINFO, holeInfo);
589 TriMesh::EdgeHandle eh(_edgeHandle);
591 if ( !eh.is_valid() || !mesh->is_boundary(eh) ){
592 emit log(
LOGERR, tr(
"Invalid edge handle.") );
610 emit log(
LOGERR, tr(
"HoleFilling unsopported for poly meshes.") );
615 #if QT_VERSION < 0x050000
void pluginsInitialized()
add PickModes after initialization
const QStringList ALL_OBJECTS
Iterable object range.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
void selectHole(int _index)
select a hole with given index
void slotItemSelectionChanged()
slot for displaying selected holes
bool getMesh(int _identifier, PolyMesh *&_mesh)
Get the Poly Mesh which has the given identifier.
void slotFillSelection()
Fill all selected holes.
bool contains(const UpdateType &_type) const
Check if this update contains the given UpdateType.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void slotCellDoubleClicked(int _row, int _col)
Slot for filling holes from double-clicked rows.
std::vector< std::vector< typename MeshT::EdgeHandle > > * holes()
get the holes vector
bool getObject(int _identifier, BSplineCurveObject *&_object)
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
void detectButton()
detect holes on all objects
void update_menu()
update the entries in the tableWidget
void fillAllHoles(int _stages=3)
fill all holes of the mesh
bool dataType(DataType _type) const
HoleFillerPlugin()
Constructor.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
std::vector< std::pair< int, int > > holeMapping_
map from the index in the table to (object-id, hole-id)
void slotObjectUpdated(int _identifier, const UpdateType &_type)
check for holes if an object has changed
void fillHole(int _objectID, int _edgeHandle)
fill a hole in given object where _edgeHandle is on the boundary
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
void getHoles()
get all holes and store them internally
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
QString name()
Return a name for the plugin.
Functions for selection on a mesh.
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
#define DATA_TRIANGLE_MESH
void fillHole(int _index, int _stages=3)
fill hole with given index
HoleFillerToolbarWidget * tool_
Widget for Toolbox.
void initializePlugin()
Initialize the toolbox widget.