42 #include "HoleFillerPlugin.hh" 43 #include "holefillerToolbar.hh" 46 #include "HoleInfoT.hh" 48 #include <QProgressDialog> 50 #define HOLEINFO "HoleInfoData" 73 QIcon* toolIcon =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"holefilling.png");
75 emit addToolbox( tr(
"Hole Filler") ,
tool_ , toolIcon);
81 emit addPickMode(
"Separator");
82 emit addPickMode(
"Hole Filler");
84 emit setSlotDescription(
"fillAllHoles(int)", tr(
"Fill all holes from a given Mesh"),
85 QString(
"objectId").split(
","), QString(
"Id of the mesh").split(
","));
87 emit setSlotDescription(
"fillHole(int,int)", tr(
"Fill a holes from a given Mesh where edgeHandle is on the boundary"),
88 QString(
"objectId,edgeHandle").split(
","), QString(
"Id of the mesh,Handle of one boundary edge of the hole").split(
","));
96 QModelIndexList indices =
tool_->tableWidget->selectionModel()->selectedRows();
99 for (
int i=0; i < indices.size(); i++){
103 _holeIds.push_back ( holeID );
104 _objIds.push_back( objID );
112 std::vector< int > holes;
113 std::vector< int > objects;
117 QProgressDialog progress(tr(
"Filling holes..."), tr(
"Abort"), 0, holes.size(), 0);
118 progress.setWindowModality(Qt::ApplicationModal);
119 progress.setValue(0);
136 o_it->setObjectData(HOLEINFO, holeInfo);
140 for (uint i = 0; i < objects.size(); i++)
141 if ( objects[i] == o_it->id() ){
144 if (progress.wasCanceled())
147 progress.setValue(++counter);
160 emit log(
LOGWARN, tr(
"HoleFilling unsupported for poly meshes") );
165 if (progress.wasCanceled())
177 std::vector< int > holes;
178 std::vector< int > objects;
195 o_it->setObjectData(HOLEINFO, holeInfo);
199 MeshSelection::clearEdgeSelection(mesh);
202 for (uint i = 0; i < objects.size(); i++)
203 if ( objects[i] == o_it->id() )
207 if ( (objects.size() == 1) && (holes.size() == 1) && ( objects[0] == o_it->id() ) ){
217 object->boundingBox(_bbMin, _bbMax);
236 o_it->setObjectData(HOLEINFO, holeInfo);
240 MeshSelection::clearEdgeSelection(mesh);
243 for (uint i = 0; i < objects.size(); i++)
244 if ( objects[i] == o_it->id() )
248 if ( (objects.size() == 1) && (holes.size() == 1) && ( objects[0] == o_it->id() ) ){
258 object->boundingBox(_bbMin, _bbMax);
276 emit log(
LOGWARN, tr(
"Error for holeMapping_ vector size") );
285 emit log(
LOGWARN, tr(
"Unable to find object for hole (should not happen!!)") );
299 object->setObjectData(HOLEINFO, holeInfo);
316 emit log(
LOGWARN,tr(
"HoleFilling unsupported for poly meshes"));
332 if ( holeInfo == 0 ){
335 o_it->setObjectData(HOLEINFO, holeInfo);
349 o_it->setObjectData(HOLEINFO, holeInfo);
368 bool updated =
false;
405 tool_->tableWidget->clear();
407 tool_->tableWidget->setRowCount ( 0 );
408 tool_->tableWidget->setColumnCount ( 4 );
410 QStringList headerdata;
411 headerdata <<
"Object" <<
"Edges" <<
"Boundary Length" <<
"BB Diagonal";
413 tool_->tableWidget->setHorizontalHeaderLabels(headerdata);
414 tool_->updateGeometry();
429 elements += holeInfo->
holes()->size();
430 tool_->tableWidget->setRowCount ( elements );
433 for (uint i = 0 ; i < holeInfo->
holes()->size() ; ++i ) {
435 QTableWidgetItem*
name =
new QTableWidgetItem( o_it->name() );
437 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
438 tool_->tableWidget->setItem(count,0,name);
440 size_t egde_count = 0;
442 double boundaryLength = 0.0;
444 holeInfo->
getHoleInfo(i, egde_count, bbDiagonal, boundaryLength);
447 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( egde_count ) );
449 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
450 tool_->tableWidget->setItem(count,1,size);
453 QTableWidgetItem* boundaryLengthWidget =
new QTableWidgetItem( QString::number(boundaryLength) );
454 boundaryLengthWidget->setFlags( 0 );
455 boundaryLengthWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
456 tool_->tableWidget->setItem(count,2,boundaryLengthWidget);
458 QTableWidgetItem* bbDiagonalWidget =
new QTableWidgetItem( QString::number(bbDiagonal) );
459 bbDiagonalWidget->setFlags( 0 );
460 bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
461 tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
464 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
477 elements += holeInfo->
holes()->size();
478 tool_->tableWidget->setRowCount ( elements );
481 for (uint i = 0 ; i < holeInfo->
holes()->size() ; ++i ) {
483 QTableWidgetItem*
name =
new QTableWidgetItem( o_it->name() );
485 name->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
486 tool_->tableWidget->setItem(count,0,name);
488 size_t egde_count = 0;
489 double boundaryLength = 0.0;
492 holeInfo->
getHoleInfo(i, egde_count, boundaryLength, bbDiagonal);
495 QTableWidgetItem* size =
new QTableWidgetItem( QString::number( egde_count ) );
497 size->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
498 tool_->tableWidget->setItem(count,1,size);
501 QTableWidgetItem* radius =
new QTableWidgetItem( QString::number(boundaryLength) );
502 radius->setFlags( 0 );
503 radius->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
504 tool_->tableWidget->setItem(count,2,radius);
507 QTableWidgetItem* bbDiagonalWidget =
new QTableWidgetItem( QString::number(bbDiagonal) );
508 bbDiagonalWidget->setFlags( 0 );
509 bbDiagonalWidget->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled);
510 tool_->tableWidget->setItem(count,3,bbDiagonalWidget);
513 holeMapping_.push_back( std::pair<int , int>( o_it->id() , i ) );
521 tool_->tableWidget->resizeColumnToContents ( 1 );
530 emit log(
LOGERR, tr(
"Could not get object from ID.") );
534 emit scriptInfo(
"fillAllHoles( ObjectId )" );
547 object->setObjectData(HOLEINFO, holeInfo);
564 emit log(
LOGERR, tr(
"HoleFilling unsopported for poly meshes.") );
576 emit log(
LOGERR, tr(
"Could not get object from ID.") );
580 emit scriptInfo(
"fillHole( ObjectId , EdgeHandle )" );
593 object->setObjectData(HOLEINFO, holeInfo);
597 TriMesh::EdgeHandle eh(_edgeHandle);
599 if ( !eh.is_valid() || !mesh->is_boundary(eh) ){
600 emit log(
LOGERR, tr(
"Invalid edge handle.") );
618 emit log(
LOGERR, tr(
"HoleFilling unsopported for poly meshes.") );
HoleFillerToolbarWidget * tool_
Widget for Toolbox.
void slotObjectUpdated(int _identifier, const UpdateType &_type)
check for holes if an object has changed
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void fillAllHoles(int _objectID)
fill all holes from a given object
void slotCellDoubleClicked(int _row, int _col)
Slot for filling holes from double-clicked rows.
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
Kernel::Point Point
Coordinate type.
void fillHole(int _index, int _stages=3)
fill hole with given index
void update_menu()
update the entries in the tableWidget
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
Kernel::Scalar Scalar
Scalar type.
QString name()
Return a name for the plugin.
bool dataType(DataType _type) const
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
void detectButton()
detect holes on all objects
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
const QStringList ALL_OBJECTS
Iterable object range.
void pluginsInitialized()
add PickModes after initialization
void slotFillSelection()
Fill all selected holes.
void initializePlugin()
Initialize the toolbox widget.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Type for a MeshObject containing a triangle mesh.
HoleFillerPlugin()
Constructor.
void fillHole(int _objectID, int _edgeHandle)
fill a hole in given object where _edgeHandle is on the boundary
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
Kernel::Normal Normal
Normal type.
Functions for selection on a mesh.
void getHolePostitionInfo(const int _index, typename MeshT::Normal &_holeNormal, typename MeshT::Point &_holeCenter) const
Collect information to fly to a hole.
bool contains(const UpdateType &_type) const
Check if this update contains the given UpdateType.
void fillAllHoles(int _stages=3)
fill all holes
void getHoles()
get all holes and store them internally
std::vector< std::vector< typename MeshT::EdgeHandle > > * holes()
get the holes vector
void flyTo(const ACG::Vec3d &_position, const ACG::Vec3d &_center, double _time)
Fly to point and viewing direction (animated).
void selectHole(int _index)
select a hole with given index
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
#define DATA_TRIANGLE_MESH
Type for a Meshobject containing a poly mesh.
void getSelectedHoles(std::vector< int > &_holeIds, std::vector< int > &_objIds)
get a map from objectID to (selected) holeIDs
void getHoleInfo(const unsigned int _index, size_t &_edges, typename MeshT::Scalar &_diagonal, typename MeshT::Scalar &_boundaryLength) const