Commit 2d7ee081 authored by Jan Möbius's avatar Jan Möbius

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@19597 383ad7c9-94d9-4d36-a494-682f7c89f535
parents
include (plugin)
openflipper_plugin ( TRANSLATION_LANGUAGES de_DE INSTALLDATA Icons VsiMetadata)
This diff is collapsed.
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef HOLEFILLINGPLUGIN_HH
#define HOLEFILLINGPLUGIN_HH
#include <QObject>
#include <QMenuBar>
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <OpenFlipper/BasePlugin/MouseInterface.hh>
#include <OpenFlipper/BasePlugin/PickingInterface.hh>
#include <OpenFlipper/BasePlugin/ToolboxInterface.hh>
#include <OpenFlipper/BasePlugin/LoggingInterface.hh>
#include <OpenFlipper/BasePlugin/ScriptInterface.hh>
#include <OpenFlipper/BasePlugin/BackupInterface.hh>
#include <OpenFlipper/common/Types.hh>
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include "holefillerToolbar.hh"
class HoleFillerPlugin : public QObject, BaseInterface, MouseInterface, PickingInterface, ToolboxInterface, LoggingInterface, ScriptInterface, BackupInterface
{
Q_OBJECT
Q_INTERFACES(BaseInterface)
Q_INTERFACES(MouseInterface)
Q_INTERFACES(PickingInterface)
Q_INTERFACES(ToolboxInterface)
Q_INTERFACES(LoggingInterface)
Q_INTERFACES(ScriptInterface)
Q_INTERFACES(BackupInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "org.OpenFlipper.Plugins.Plugin-HoleFilling")
#endif
signals:
void updateView();
void updatedObject(int, UpdateType);
void addPickMode( const std::string _mode );
void log(Logtype _type, QString _message);
void log(QString _message);
void createBackup( int _objectid, QString _name, UpdateType _type = UPDATE_ALL);
void scriptInfo( QString _functionName );
void setSlotDescription(QString _slotName , QString _slotDescription,
QStringList _parameters , QStringList _descriptions);
// ToolboxInterface
void addToolbox( QString _name , QWidget* _widget, QIcon* _icon );
private slots:
void slotObjectUpdated(int _identifier);
void slotMouseWheelEvent(QWheelEvent * /*_event*/, const std::string & /*_mode*/){};
void slotMouseEvent( QMouseEvent* /*_event*/ ){};
// BaseInterface
void initializePlugin();
void pluginsInitialized() ;
void detectButton( );
public :
~HoleFillerPlugin() {};
HoleFillerPlugin();
QString name() { return (QString("Hole Filler")); };
QString description( ) { return (QString("Fill Holes or connect meshes")); };
private slots:
void slotItemSelectionChanged();
void slotCellDoubleClicked(int _row , int _col);
void slotFillSelection();
private :
void update_menu();
/// Widget for Toolbox
HoleFillerToolbarWidget* tool_;
/// map from the index in the table to (object-id, hole-id)
std::vector< std::pair< int , int> > holeMapping_;
//Scripting slots
public slots:
void fillAllHoles(int _objectID);
void fillHole(int _objectID, int _edgeHandle);
public slots:
QString version() { return QString("1.3"); };
};
#endif //HOLEFILLINGPLUGIN_HH
This diff is collapsed.
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
#ifndef HOLEFILLER_HH
#define HOLEFILLER_HH
//=============================================================================
#include <vector>
#include <float.h>
#include <cmath>
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include "OpenMeshUtils.hh"
#include <OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.hh>
//=============================================================================
template< class TheMesh >
class HoleFiller
{
public:
typedef TheMesh Mesh;
import_om_abbreviations( typename Mesh );
// A weight is a tuple of area and maximum dihedral angle
//
class Weight {
public:
Weight() : angle_( 180 ), area_( FLT_MAX ) {}
Weight( Scalar _angle, Scalar _area ) : angle_( _angle ), area_( _area ) {}
~Weight() {}
Scalar angle() const { return angle_; }
Scalar area() const { return area_; }
Weight operator+( const Weight & _other ) const {
return Weight( std::max( angle(), _other.angle() ),
area() + _other.area() );
}
bool operator<( const Weight & _rhs ) const {
return ( angle() < _rhs.angle() ||
( angle() == _rhs.angle() && area() < _rhs.area() ) );
}
private:
Scalar angle_;
Scalar area_;
};
// Ctors
HoleFiller( Mesh & _mesh );
~HoleFiller();
// Identify and fill all holes of the mesh.
void fill_all_holes( int _stages = 3 );
// Fill a hole which is identified by one of its boundary edges.
void fill_hole( EH _eh, int _stages = 3 );
// Fair a filling
void fairing( std::vector< FH >& _faceHandles );
// Remove degenerated faces from the filling
void removeDegeneratedFaces( std::vector< FH >& _faceHandles );
private:
// Refine a face
bool refine( FH _fh );
// Relax an edge
bool relax_edge( EH _eh );
// Test whether a point _x lies in the circumsphere of _a,_b,_c.
bool in_circumsphere( const Point & _x,
const Point & _a,
const Point & _b,
const Point & _c ) const;
// Create the triangulation for polygon (_i,...,_j).
bool fill( int _i, int _j );
// Compute the weight of the triangle (_i,_j,_k).
Weight weight( int _i, int _j, int _k );
// Does edge (_u,_v) already exist?
bool exists_edge( VH _u, VH _w );
// Compute the area of the triangle (_a,_b,_c).
Scalar area( VH _a, VH _b, VH _c );
// Compute the dihedral angle (in degrees) between triangle
// (_u,_v,_a) and triangle (_v,_u,_b).
Scalar dihedral_angle( VH _u, VH _v, VH _a, VH _b );
// The mesh, with each vertex we associate a scale factor that is
// needed for remeshing
Mesh & mesh_;
OpenMesh::VPropHandleT< Scalar > scale_;
/*
HOLE
boundary_vertex_
|
V
==*=======*=======*== BOUNDARY
/ \ / \ / \
/ \ / \ / \
\ / \ /
* * <- opposite_vertex_
*/
typedef std::vector< VH > VHVec;
typedef typename std::vector< VH >::iterator VHVecIter;
typedef typename std::vector< VH >::const_iterator CVHVecIter;
typedef std::vector< FH > FHVec;
typedef typename std::vector< FH >::iterator FHVecIter;
typedef typename std::vector< FH >::const_iterator CFHVecIter;
// This vector contains all vertices of the hole (in order)
VHVec boundary_vertex_;
// This vector contains all vertices that are opposite to an edge of the hole
VHVec opposite_vertex_;
// This vector contains all edges of the hole (in order)
std::vector< EH > hole_edge_;
// This vector stores handles to all triangles of the current hole
std::vector< FH > hole_triangle_;
// These are the two central arrays that are needed for the dynamic
// programming approach to hole filling.
// w_[i][j] : stores the minimal weight that can be achieved
// for a triangulation of the polygon
// boundary_vertex_[i],...,boundary_vertex_[j]
// l_[i][j] : stores the third index of the triangle
// <boundary_vertex_[i],boundary_vertex_[l_[i][j]],
// boundary_vertex_[j]>
// that is needed for reconstructing the minimal triangulation
std::vector< std::vector< Weight > > w_;
std::vector< std::vector< int > > l_;
};
//=============================================================================
#ifndef HOLEFILLER_CC
#include "HoleFillerT.cc"
#endif
//=============================================================================
#endif // HOLEFILLER_HH defined
//=============================================================================
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 11127 $ *
* $LastChangedBy: moebius $ *
* $Date: 2011-03-15 16:18:28 +0100 (Di, 15 Mär 2011) $ *
* *
\*===========================================================================*/
#define HOLEINFO_C
#include "HoleInfoT.hh"
#include <MeshTools/MeshSelectionT.hh>
/// Constructor
template< class MeshT >
HoleInfo< MeshT >::HoleInfo(MeshT * _mesh)
: mesh_(_mesh), filler_(0)
{
}
/// Destructor
template< class MeshT >
HoleInfo< MeshT >::~HoleInfo()
{
if (filler_ != 0)
delete filler_;
}
/// get all holes and store them internally
template< class MeshT >
void HoleInfo< MeshT >::getHoles()
{
// Property for the active mesh to mark already visited edges
OpenMesh::EPropHandleT< bool > boundary_search;
// Add a property to the mesh to store original vertex positions
mesh_->add_property( boundary_search, "Boundary search" );
// Initialize Property
typename MeshT::EdgeIter e_it, e_end=mesh_->edges_end();
for (e_it=mesh_->edges_begin(); e_it!=e_end; ++e_it) {
mesh_->property( boundary_search , *e_it ) = false;
}
holes_.clear();
for (e_it=mesh_->edges_begin(); e_it!=e_end; ++e_it) {
// Skip already visited edges
if ( mesh_->property( boundary_search , *e_it ) )
continue;
// Check only boundary edges
if ( !mesh_->is_boundary(*e_it))
continue;
// Get boundary halfedge
typename MeshT::HalfedgeHandle hh = mesh_->halfedge_handle( *e_it, 0 );
if ( ! mesh_->is_boundary( hh ) )
hh = mesh_->opposite_halfedge_handle( hh );
typename MeshT::Point center(0,0,0);
Hole currentHole;
// Collect boundary edges
typename MeshT::HalfedgeHandle ch = hh;
do {
currentHole.push_back( mesh_->edge_handle(ch) );
center += mesh_->point( mesh_->from_vertex_handle(ch) );
mesh_->property( boundary_search , mesh_->edge_handle(ch) ) = true;
//check number of outgoing boundary HEH's at Vertex
int c = 0;
typename MeshT::VertexHandle vh = mesh_->to_vertex_handle(ch);
for ( typename MeshT::VertexOHalfedgeIter voh_it(*mesh_,vh); voh_it.is_valid(); ++voh_it)
if ( mesh_->is_boundary( *voh_it ) )
c++;
if ( c >= 2){
typename MeshT::HalfedgeHandle op = mesh_->opposite_halfedge_handle( ch );
typename MeshT::VertexOHalfedgeIter voh_it(*mesh_,op);
ch = *(++voh_it);
}else
ch = mesh_->next_halfedge_handle( ch );
} while ( ch != hh );
center /= currentHole.size();
bool isHole = true;
int err = 0;
for (unsigned int i=0; i < currentHole.size(); i++){
typename MeshT::HalfedgeHandle hh = mesh_->halfedge_handle( currentHole[i], 0 );
if ( ! mesh_->is_boundary( hh ) )
hh = mesh_->opposite_halfedge_handle( hh );
typename MeshT::VertexHandle vh = mesh_->from_vertex_handle(hh);
typename MeshT::Normal n = mesh_->normal( vh );
typename MeshT::Point p = mesh_->point( vh );
if ( (p - center).norm() < (p + n - center).norm() ){
// isHole = false;
// break;
err++;
}
}
// std::cerr << "Errors " << err << " Size " << hole.count << std::endl;
if (isHole)
holes_.push_back(currentHole);
}
mesh_->remove_property( boundary_search);
}
/// fill hole with given index
template< class MeshT >
void HoleInfo< MeshT >::fillHole(int _index, int _stages)
{
if ( (uint) _index > holes_.size()){
std::cerr << "Cannot fill hole. Index invalid." << std::endl;
return;
}
if (filler_ == 0)
filler_ = new HoleFiller< MeshT >(*mesh_);
filler_->fill_hole( holes_[_index][0], _stages );
mesh_->garbage_collection();
MeshSelection::clearEdgeSelection(mesh_);
mesh_->update_normals();
}
/// fill hole with given edgeHandle on the boundary
template< class MeshT >
void HoleInfo< MeshT >::fillHole(typename MeshT::EdgeHandle _eh, int _stages)
{
if (filler_ == 0)
filler_ = new HoleFiller< MeshT >(*mesh_);
filler_->fill_hole( _eh, _stages );
mesh_->garbage_collection();
MeshSelection::clearEdgeSelection(mesh_);
mesh_->update_normals();
}
/// fill all holes of the mesh
template< class MeshT >
void HoleInfo< MeshT >::fillAllHoles(int _stages)
{
if (filler_ == 0)
filler_ = new HoleFiller< MeshT >(*mesh_);
filler_->fill_all_holes( _stages );
}
/// select a hole with given index
template< class MeshT >
void HoleInfo< MeshT >::selectHole(int _index)
{
if ( (uint) _index > holes_.size()){
std::cerr << "Cannot select hole. Index invalid." << std::endl;
return;
}
for ( uint i = 0 ; i < (holes_[_index]).size() ; ++i ) {
mesh_->status( (holes_[_index])[i] ).set_selected(true);
}
}
/// get the holes vector
template< class MeshT >
std::vector< std::vector< typename MeshT::EdgeHandle > >* HoleInfo< MeshT >::holes()
{
return &holes_;
}
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 11127 $ *
* $LastChangedBy: moebius $ *
* $Date: 2011-03-15 16:18:28 +0100 (Di, 15 Mär 2011) $ *
* *
\*===========================================================================*/
#ifndef HOLEINFO_HH
#define HOLEINFO_HH
#include <OpenFlipper/common/perObjectData.hh>
#include <OpenFlipper/common/Types.hh>
#include "HoleFillerT.hh"
template< class MeshT >
class HoleInfo : public PerObjectData
{
public :
typedef std::vector< typename MeshT::EdgeHandle > Hole;
private :
// the mesh
MeshT* mesh_;
// list of holes
std::vector< Hole > holes_;
// holeFiller
HoleFiller< MeshT >* filler_;
public :
//Konstruktor
HoleInfo(MeshT* _mesh);
//Destruktor
~HoleInfo();
// find all holes in the mesh
void getHoles();
//fill hole with given index
void fillHole(int _index, int _stages = 3 );
//fill hole with given boundary edgeHandle
void fillHole(typename MeshT::EdgeHandle _eh, int _stages = 3 );
//fill all holes
void fillAllHoles( int _stages = 3 );
//select a hole with given index
void selectHole(int _index);
std::vector< std::vector< typename MeshT::EdgeHandle > >* holes();
};
#if defined(INCLUDE_TEMPLATES) && !defined(HOLEINFO_C)
#define HOLEINFO_TEMPLATES
#include "HoleInfoT.cc"
#endif
#endif //HOLEINFO_HH