Commit 9773936a authored by Marlin Frickenschmidt's avatar Marlin Frickenschmidt
Browse files

Made many of the functions of Mesh Repair scriptable. Also made a few minor bugfixes.

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@10786 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 1894ef17
......@@ -65,15 +65,15 @@ initializePlugin()
// Vertex Selection/Removal
connect(tool_->valenceThreeButton, SIGNAL(clicked()), this, SLOT(slotDetectFlatTriangle()) );
connect(tool_->valenceThreeButton, SIGNAL(clicked()), this, SLOT(slotDetectFlatTriangles()) );
connect(tool_->repairRemoveVButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedVal3Vertices()) );
// Edge Selection/Repairing
connect(tool_->detectEShorterButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesShorter()) );
connect(tool_->detectELargerButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesLarger()) );
connect(tool_->detectELargerButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesLonger()) );
connect(tool_->repairCollapseEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedEdges()) );
connect(tool_->detectCapAngle, SIGNAL(clicked()), this, SLOT(slotDetectCaps()) );
connect(tool_->repairFlipEButton, SIGNAL(clicked()), this, SLOT(slotRemoveCaps()) );
connect(tool_->detectCapAngle, SIGNAL(clicked()), this, SLOT(slotDetectSkinnyTriangleByAngle()) );
connect(tool_->repairFlipEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSkinnyTriangleByAngle()) );
connect(tool_->detectFoldoverButton, SIGNAL(clicked()), this, SLOT(slotDetectFoldover()) );
//Face operations
......@@ -90,14 +90,56 @@ initializePlugin()
//-----------------------------------------------------------------------------
/** \brief Initialization of the plugin when it is loaded by the core
*
*/
void MeshRepairPlugin::pluginsInitialized() {
emit setSlotDescription("decimate(int,QVariantMap)",tr("Decimate a given object"),
QString(tr("objectId,constraints")).split(","),
QString(tr("ID of an object; Object that can has one or more constraint properties (distance,normal_deviation,roundness,vertices)")).split(";"));
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotDetectEdgesShorter(){
double length = tool_->edgeSpin->value();
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
selectEdgesShorterThan(o_it->id(),length);
emit updateView();
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotDetectEdgesLonger(){
double length = tool_->edgeSpin->value();
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
selectEdgesLongerThan(o_it->id(),length);
emit updateView();
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::selectEdgesShorterThan(int _objectId,double _length) {
selectionEdgeLength(_objectId,_length,false);
emit scriptInfo( "selectEdgesShorterThan(" + QString::number(_objectId) + ", " + QString::number(_length) + ")" );
}
void MeshRepairPlugin::selectEdgesLargerThan(int _objectId,double _length) {
//-----------------------------------------------------------------------------
void MeshRepairPlugin::selectEdgesLongerThan(int _objectId,double _length) {
selectionEdgeLength(_objectId,_length,true);
emit scriptInfo( "selectEdgesLongerThan(" + QString::number(_objectId) + ", " + QString::number(_length) + ")" );
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::selectionEdgeLength(int _objectId, double _length, bool _larger) {
QString backupstring = tr("Selected Edges ");
......@@ -130,7 +172,6 @@ void MeshRepairPlugin::selectionEdgeLength(int _objectId, double _length, bool _
if ( (p1 - p2).norm() < _length)
triMesh->status(e_it).set_selected(true);
}
}
emit updatedObject(_objectId,UPDATE_SELECTION);
......@@ -176,62 +217,67 @@ void MeshRepairPlugin::selectionEdgeLength(int _objectId, double _length, bool _
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotDetectFlatTriangle() {
void MeshRepairPlugin::slotDetectFlatTriangles() {
double angle = tool_->valenceThreeSpinbox->value();
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it) {
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
detectFlatTriangles(o_it->id(), angle);
}
if (o_it->dataType() != DATA_TRIANGLE_MESH) {
emit log("Cannot detect flat triangles on non-trimesh " + QString::number(o_it->id()) + ".");
continue;
}
//-----------------------------------------------------------------------------
float angle = tool_->valenceThreeSpinbox->value();
unsigned int count(0);
void MeshRepairPlugin::detectFlatTriangles(int _objectId, double _angle) {
// get the target mesh
TriMesh* mesh = 0;
PluginFunctions::getMesh(o_it->id(),mesh);
unsigned int count(0);
if ( mesh ) {
// get the target mesh
TriMesh* mesh = 0;
PluginFunctions::getMesh(_objectId,mesh);
// Clear current triangle selection
MeshSelection::clearVertexSelection(mesh);
if ( mesh ) {
TriMesh::VertexIter v_it, v_end(mesh->vertices_end());
TriMesh::VVIter vv_it;
TriMesh::VFIter vf_it;
TriMesh::FaceHandle fh;
std::vector<TriMesh::VertexHandle> vh(3);
unsigned int i;
TriMesh::Scalar cosangle(cos(angle/180.0*M_PI));
// Clear current triangle selection
MeshSelection::clearVertexSelection(mesh);
for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it)
TriMesh::VertexIter v_it, v_end(mesh->vertices_end());
TriMesh::VVIter vv_it;
TriMesh::VFIter vf_it;
TriMesh::FaceHandle fh;
std::vector<TriMesh::VertexHandle> vh(3);
unsigned int i;
TriMesh::Scalar cosangle(cos(_angle/180.0*M_PI));
for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it)
{
if (!mesh->status(v_it).deleted() && !mesh->is_boundary(v_it) && mesh->valence(v_it) == 3)
{
if (!mesh->status(v_it).deleted() && !mesh->is_boundary(v_it) && mesh->valence(v_it) == 3)
vf_it = mesh->vf_iter(v_it);
const TriMesh::Normal& n0 = mesh->normal(vf_it);
const TriMesh::Normal& n1 = mesh->normal(++vf_it);
const TriMesh::Normal& n2 = mesh->normal(++vf_it);
if ( (n0|n1) > cosangle &&
(n0|n2) > cosangle &&
(n1|n2) > cosangle )
{
vf_it = mesh->vf_iter(v_it);
const TriMesh::Normal& n0 = mesh->normal(vf_it);
const TriMesh::Normal& n1 = mesh->normal(++vf_it);
const TriMesh::Normal& n2 = mesh->normal(++vf_it);
if ( (n0|n1) > cosangle &&
(n0|n2) > cosangle &&
(n1|n2) > cosangle )
{
mesh->status(v_it).set_selected(true);
++count;
}
mesh->status(v_it).set_selected(true);
++count;
}
}
}
if (count > 0) {
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Select vertices with face angle difference smaller than " + QString::number(angle));
}
emit log ("Selected " + QString::number(count) + " vertices on object " + QString::number(o_it->id()) + " with face angle difference smaller than " + QString::number(angle) + ".");
}
else {
emit log(LOGERR, "Cannot detect flat triangles on non-trimesh " + QString::number(_objectId) + ".");
}
if (count > 0) {
emit updatedObject(_objectId, UPDATE_SELECTION);
emit createBackup(_objectId, "Select vertices with face angle difference smaller than " + QString::number(_angle));
}
emit log ("Selected " + QString::number(count) + " vertices on object " + QString::number(_objectId) + " with face angle difference smaller than " + QString::number(_angle) + ".");
emit scriptInfo( "detectFlatTriangles(" + QString::number(_objectId) + ", " + QString::number(_angle) + ")" );
emit updateView();
}
......@@ -288,28 +334,6 @@ void MeshRepairPlugin::slotRemoveSelectedVal3Vertices() {
emit updateView();
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotDetectEdgesLarger(){
double length = tool_->edgeSpin->value();
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
selectEdgesLargerThan(o_it->id(),length);
emit updateView();
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotDetectEdgesShorter(){
double length = tool_->edgeSpin->value();
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
selectEdgesShorterThan(o_it->id(),length);
emit updateView();
}
//-----------------------------------------------------------------------------
......@@ -356,6 +380,7 @@ void MeshRepairPlugin::removeSelectedEdges(int _objectId){
emit updatedObject(_objectId,UPDATE_ALL);
emit createBackup( _objectId, "Removed selected Edges");
emit scriptInfo( "removeSelectedEdges(" + QString::number(_objectId) + ")" );
return;
}
......@@ -395,16 +420,18 @@ flipOrientation(int _objectId)
for (f_it = triMesh->faces_begin(); f_it != f_end ; ++f_it) {
// Collect vertex handles
TriMesh::FaceVertexIter fv_it = triMesh->fv_iter(f_it);
handles.push_back( fv_it.handle() );
++fv_it;
handles.push_back( fv_it.handle() );
++fv_it;
handles.push_back( fv_it.handle() );
// delete the corresponding face
triMesh->delete_face(f_it, false);
if (triMesh->status(f_it).selected()) {
// Collect vertex handles
TriMesh::FaceVertexIter fv_it = triMesh->fv_iter(f_it);
handles.push_back( fv_it.handle() );
++fv_it;
handles.push_back( fv_it.handle() );
++fv_it;
handles.push_back( fv_it.handle() );
// delete the corresponding face
triMesh->delete_face(f_it, false);
}
}
// clean the mesh
......@@ -418,6 +445,7 @@ flipOrientation(int _objectId)
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Flipped Normals");
emit scriptInfo( "flipOrientation(" + QString::number(_objectId) + ")" );
return;
}
......@@ -475,6 +503,7 @@ flipOrientation(int _objectId)
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Flipped Normals");
emit scriptInfo( "flipOrientation(" + QString::number(_objectId) + ")" );
return;
}
......@@ -495,7 +524,7 @@ void MeshRepairPlugin::slotFlipOrientation(){
//-----------------------------------------------------------------------------
void MeshRepairPlugin::detectCaps(int _objectId, double _angle, bool _remove)
void MeshRepairPlugin::detectSkinnyTriangleByAngle(int _objectId, double _angle, bool _remove)
{
// get the target mesh
TriMesh* triMesh = 0;
......@@ -545,14 +574,14 @@ void MeshRepairPlugin::detectCaps(int _objectId, double _angle, bool _remove)
if ( _remove ) {
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, tr("removed cap edges with angle > %1 .").arg(angle) );
emit createBackup( _objectId, tr("Removed cap edges with angle > %1 .").arg(angle) );
} else {
emit updatedObject(_objectId, UPDATE_SELECTION);
emit createBackup( _objectId, tr("Selected cap edges with angle > %1 .").arg(angle) );
}
emit scriptInfo( "detectSkinnyTriangleByAngle(" + QString::number(_objectId) + "," + QString::number(_angle) + "," + _remove + ")" );
return;
}
emit log( LOGERR,tr("Unsupported Object Type for Cap detection!") );
......@@ -560,23 +589,25 @@ void MeshRepairPlugin::detectCaps(int _objectId, double _angle, bool _remove)
}
void MeshRepairPlugin::slotDetectCaps()
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotDetectSkinnyTriangleByAngle()
{
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
detectCaps( o_it->id(), tool_->capAngleSpinbox->value(), false );
detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), false );
emit updateView();
}
void MeshRepairPlugin::slotRemoveCaps()
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotRemoveSkinnyTriangleByAngle()
{
//rewrite!!!
//rewrite!!!
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
detectCaps( o_it->id(), tool_->capAngleSpinbox->value(), true );
detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), true );
emit updateView();
}
//-----------------------------------------------------------------------------
......
......@@ -50,19 +50,23 @@
#include <OpenFlipper/BasePlugin/LoggingInterface.hh>
#include <OpenFlipper/BasePlugin/ToolboxInterface.hh>
#include <OpenFlipper/BasePlugin/BackupInterface.hh>
#include <OpenFlipper/BasePlugin/ScriptInterface.hh>
#include <OpenFlipper/BasePlugin/RPCInterface.hh>
#include <OpenFlipper/common/Types.hh>
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include "MeshRepairToolbar.hh"
class MeshRepairPlugin : public QObject, BaseInterface , ToolboxInterface, BackupInterface, LoggingInterface
class MeshRepairPlugin : public QObject, BaseInterface , ToolboxInterface, BackupInterface, LoggingInterface, ScriptInterface, RPCInterface
{
Q_OBJECT
Q_INTERFACES(BaseInterface)
Q_INTERFACES(ToolboxInterface)
Q_INTERFACES(BackupInterface)
Q_INTERFACES(LoggingInterface)
Q_INTERFACES(ScriptInterface)
Q_INTERFACES(RPCInterface)
signals:
......@@ -70,7 +74,10 @@ signals:
// Base Interface
void updatedObject(int _identifier, const UpdateType _type);
void setSlotDescription(QString _slotName, QString _slotDescription,
QStringList _parameters, QStringList _descriptions);
// Logging interface
void log(Logtype _type, QString _message);
void log(QString _message);
......@@ -80,9 +87,17 @@ signals:
// Backup Interface
void createBackup( int _objectid, QString _name);
// RPC Interface
void pluginExists( QString _pluginName , bool& _exists ) ;
void functionExists( QString _pluginName , QString _functionName , bool& _exists );
// ScriptInterface
void scriptInfo( QString _functionName );
private slots:
void initializePlugin();
void pluginsInitialized();
void slotActiveObjectChanged() {};
public :
......@@ -105,13 +120,13 @@ private :
private slots:
/// Button slot
void slotDetectFlatTriangle();
void slotDetectFlatTriangles();
/// Button slot
void slotRemoveSelectedVal3Vertices();
/// Button Slot
void slotDetectEdgesLarger();
void slotDetectEdgesLonger();
/// Button Slot
void slotDetectEdgesShorter();
......@@ -123,10 +138,10 @@ private slots:
void slotFlipOrientation();
/// Button slot
void slotDetectCaps();
void slotDetectSkinnyTriangleByAngle();
/// Button slot
void slotRemoveCaps();
void slotRemoveSkinnyTriangleByAngle();
/// Button slot
void slotDetectFoldover();
......@@ -141,7 +156,7 @@ public slots:
void selectEdgesShorterThan(int _objectId,double _length);
/// Selects all edges of an oobject which are larger than the given length
void selectEdgesLargerThan(int _objectId,double _length);
void selectEdgesLongerThan(int _objectId,double _length);
/// Removes all selected edges
void removeSelectedEdges(int _objectId);
......@@ -150,7 +165,10 @@ public slots:
void flipOrientation(int _objectId);
/// Detect/Remove edges where neighbouring faces form angle > _angle degrees
void detectCaps(int _objectId, double _angle, bool _remove);
void detectSkinnyTriangleByAngle(int _objectId, double _angle, bool _remove);
/// Detect valence 3 triangles that lie in the plane of their adjacent triangles
void detectFlatTriangles(int _objectId, double _angle);
private:
/** \brief select edges based on length
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment