Commit 68391422 authored by Matthias Möller's avatar Matthias Möller

add fix-topology function

move some gui elements

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@15427 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 44bed7b2
......@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>456</width>
<height>795</height>
<height>803</height>
</rect>
</property>
<property name="windowTitle">
......@@ -103,6 +103,53 @@ These vertices can usually be removed without destroying the features of the mes
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<string>Snap Boundary:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<widget class="QPushButton" name="snapBoundaryButton">
<property name="toolTip">
<string>Snaps selected boundary vertices together.</string>
</property>
<property name="text">
<string>Snap</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>max. Distance</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="snapBoundarySpinBox">
<property name="decimals">
<number>6</number>
</property>
<property name="minimum">
<double>0.500000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.500000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
......@@ -575,6 +622,20 @@ There is no automatic algorithm to fix these foldovers here. So you will have to
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_13">
<property name="text">
<string>Fix Mesh:</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="fixMeshButton">
<property name="text">
<string>Fix Topology</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
......@@ -592,55 +653,6 @@ There is no automatic algorithm to fix these foldovers here. So you will have to
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Snap Boundary</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<widget class="QPushButton" name="snapBoundaryButton">
<property name="toolTip">
<string>Snaps selected boundary vertices together.</string>
</property>
<property name="text">
<string>Snap</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>max. Distance</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="snapBoundarySpinBox">
<property name="decimals">
<number>6</number>
</property>
<property name="minimum">
<double>0.500000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.500000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
......
......@@ -88,6 +88,7 @@ initializePlugin()
//Face operations
connect(tool_->triangleAspectButton,SIGNAL(clicked()),this,SLOT(slotDetectTriangleAspect()));
connect(tool_->flipOrientation,SIGNAL(clicked()),this,SLOT(slotFlipOrientation()));
connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh()));
//Normal operations
connect(tool_->computeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateNormals()));
......@@ -255,6 +256,15 @@ void MeshRepairPlugin::slotSnapBoundary()
emit updateView();
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::slotFixMesh()
{
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
fixTopology(o_it->id());
emit updateView();
}
//-----------------------------------------------------------------------------
......@@ -348,6 +358,29 @@ void MeshRepairPlugin::snapBoundary(int _objectId, double _eps)
emit scriptInfo("snapBoundary(" + QString::number(_objectId) + ", " + QString::number(_eps) +")");
}
void MeshRepairPlugin::fixTopology(int _objectId)
{
TriMesh* triMesh = 0;
PolyMesh* polyMesh = 0;
PluginFunctions::getMesh(_objectId, triMesh);
PluginFunctions::getMesh(_objectId, polyMesh);
if (triMesh)
fixTopology(triMesh);
else if (polyMesh)
fixTopology(polyMesh);
else
{
emit log(LOGERR, tr("Unsupported Object Type."));
return;
}
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup(_objectId, "fixTopology", UPDATE_ALL);
emit scriptInfo("fixTopology(" + QString::number(_objectId) + ")");
}
void MeshRepairPlugin::removeSelectedVal3Vertices(int _objectId) {
unsigned int count = 0;
......
......@@ -165,6 +165,9 @@ private slots:
/// Button slot
void slotSnapBoundary();
/// Button slot
void slotFixMesh();
//Scripting functions:
public slots:
......@@ -209,6 +212,8 @@ public slots:
void snapBoundary(int _objectId, double _eps);
void fixTopology(int _objectId);
private:
/** \brief select edges based on length
*
......@@ -247,6 +252,12 @@ private:
template<typename MeshT>
static bool sort_less_pair_second(const std::pair<typename MeshT::VertexHandle,double> &lhs,const std::pair<typename MeshT::VertexHandle,double> &rhs);
/** \brief fixes the orientation and non-manifold problems in a mesh.
* @param _mesh target mesh
*
*/
template<typename MeshT>
void fixTopology(MeshT *_mesh);
public slots:
QString version() {
......
......@@ -3,6 +3,8 @@
#include "MeshRepairPlugin.hh"
//-----------------------------------------------------------------------------
template<typename MeshT>
inline unsigned MeshRepairPlugin::n_verticesPerFace()
{
......@@ -10,12 +12,15 @@ inline unsigned MeshRepairPlugin::n_verticesPerFace()
return 4;
}
//-----------------------------------------------------------------------------
template<>
inline unsigned MeshRepairPlugin::n_verticesPerFace<TriMesh>()
{
return 3;
}
//-----------------------------------------------------------------------------
template<typename MeshT>
void MeshRepairPlugin::flipOrientationSelected(MeshT *_mesh)
......@@ -78,12 +83,16 @@ void MeshRepairPlugin::flipOrientationSelected(MeshT *_mesh)
_mesh->update_normals();
}
//-----------------------------------------------------------------------------
template<typename MeshT>
bool MeshRepairPlugin::sort_less_pair_second(const std::pair<typename MeshT::VertexHandle,double> &lhs,const std::pair<typename MeshT::VertexHandle,double> &rhs)
{
return lhs.second < rhs.second;
}
//-----------------------------------------------------------------------------
template<typename MeshT>
void MeshRepairPlugin::snapBoundary(MeshT *_mesh, double _eps)
{
......@@ -217,7 +226,6 @@ void MeshRepairPlugin::snapBoundary(MeshT *_mesh, double _eps)
//try to add new face
std::vector<typename MeshT::VertexHandle> newFace_vertices(f_vertices);
std::replace(newFace_vertices.begin(),newFace_vertices.end(),v_old,v_new);
typename MeshT::FaceHandle faceH = _mesh->add_face(newFace_vertices);
if (!faceH.is_valid())
......@@ -239,3 +247,96 @@ void MeshRepairPlugin::snapBoundary(MeshT *_mesh, double _eps)
_mesh->garbage_collection();
}
//-----------------------------------------------------------------------------
template<typename MeshT>
void MeshRepairPlugin::fixTopology(MeshT *_mesh)
{
OpenMesh::FPropHandleT< size_t > component;
if ( !_mesh->get_property_handle(component,"component") )
_mesh->add_property(component, "component");
for (typename MeshT::VertexIter v_iter = _mesh->vertices_begin(); v_iter != _mesh->vertices_end(); ++v_iter)
{
//unmark all faces
for (typename MeshT::VertexFaceIter vf_iter = _mesh->vf_begin(v_iter); vf_iter; ++vf_iter)
_mesh->property(component,vf_iter.handle()) = 0;
size_t componentCount = 1;
//search and isolate new components
//shared vertices will be doublicated
for (typename MeshT::VertexFaceIter vf_iter = _mesh->vf_begin(v_iter); vf_iter; ++vf_iter)
{
//get the first face in the component
std::vector<typename MeshT::FaceHandle> checkNeighbour;
if(_mesh->property(component,vf_iter.handle()) == 0)
{
_mesh->property(component,vf_iter.handle()) = componentCount;
checkNeighbour.push_back(vf_iter.handle());
}
//if a reference face was found, it exists a new component
//and a new vertex is required (except for the first component)
typename MeshT::VertexHandle v_new;
if (componentCount > 1 && !checkNeighbour.empty())
{
typename MeshT::Point p = _mesh->point(v_iter.handle());
v_new = _mesh->add_vertex(p);
}
//check all adjacent faces of our reference
while(!checkNeighbour.empty())
{
typename MeshT::FaceHandle face = checkNeighbour.back();
checkNeighbour.pop_back();
std::vector<typename MeshT::VertexHandle> f_vertices;
//get all neighbour faces of face
for (typename MeshT::FaceVertexIter fv_iter = _mesh->fv_begin(face); fv_iter; ++fv_iter)
{
f_vertices.push_back(fv_iter.handle());
if (fv_iter.handle() != v_iter)
{
//find the next neighbour face over edge v_iter and fv_iter
typename MeshT::FaceHandle nf;
for (typename MeshT::VertexFaceIter nf_iter = _mesh->vf_begin(v_iter); nf_iter && !nf.is_valid(); ++nf_iter)
{
if (nf_iter.handle() != face)
for (typename MeshT::FaceVertexIter nfv_iter = _mesh->fv_begin(nf_iter); nfv_iter && !nf.is_valid(); ++nfv_iter)
if (nfv_iter.handle() == fv_iter.handle())
nf = nf_iter.handle();
}
//if such a face was found, it is in the same component as the reference face
if (nf.is_valid() && !_mesh->property(component,nf))
{
_mesh->property(component,nf) = componentCount;
checkNeighbour.push_back(nf);
}
}
}
//if one face wasn't found in the component = 1 run, then it is a new component, due split it
if (componentCount > 1 && v_new.is_valid())
{
std::replace(f_vertices.begin(),f_vertices.end(),v_iter.handle(),v_new);
_mesh->delete_face(face,false);
_mesh->add_face(f_vertices);
}
}
//all faces which belongs to v_iter and inside same component found
//the next face will be in a new component
++componentCount;
}
}
_mesh->remove_property(component);
_mesh->garbage_collection();
}
//-----------------------------------------------------------------------------
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