Commit e79c16a9 authored by Jan Möbius's avatar Jan Möbius

Started cleanup and more documentation

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@15716 383ad7c9-94d9-4d36-a494-682f7c89f535
parent b420c28e
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 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: 15713 $ *
* $LastChangedBy: moebius $ *
* $Date: 2012-10-25 12:58:58 +0200 (Do, 25 Okt 2012) $ *
* *
\*===========================================================================*/
#include "MeshRepairPlugin.hh"
#include "MeshFixingT.hh"
//-----------------------------------------------------------------------------
void MeshRepairPlugin::fixNonManifoldVertices(int _objectId)
{
TriMesh* triMesh = 0;
PolyMesh* polyMesh = 0;
PluginFunctions::getMesh(_objectId, triMesh);
PluginFunctions::getMesh(_objectId, polyMesh);
if (triMesh)
fixNonManifoldVertices(triMesh);
else if (polyMesh)
fixNonManifoldVertices(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::fixMesh(int _objectId, double _epsilon) {
// get the target mesh
TriMesh* triMesh = 0;
PluginFunctions::getMesh(_objectId,triMesh);
if (triMesh) {
MeshFixing<TriMesh> fixer(*triMesh,_epsilon);
if ( !fixer.fix() )
emit log(LOGERR, "Fixmesh encountered Problems! Object: " + QString::number(_objectId) + ".");
// Recompute normals
triMesh->update_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup(_objectId, "Fixed mesh", UPDATE_ALL);
emit scriptInfo( "fixMesh(" + QString::number(_objectId) + ", " + QString::number(_epsilon) + ")" );
} else
emit log( LOGERR,tr("Unsupported Object Type for mesh fixing!") );
}
//-----------------------------------------------------------------------------
......@@ -295,7 +295,7 @@ int MeshFixing<MeshT>::neighbor(unsigned int _f, unsigned int _v0, unsigned int
return neighborFace;
}
/**
/** Tries to ensure that all faces in one component have the same orientation.
*
*/
template<class MeshT>
......@@ -304,7 +304,6 @@ void MeshFixing<MeshT>::fix_orientation()
// We need faces to work on!
if (faces_.empty()) return;
int fh = 0;
std::vector<int> todo;
......
......@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>432</width>
<height>852</height>
<height>830</height>
</rect>
</property>
<property name="windowTitle">
......@@ -588,20 +588,6 @@ 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="fixTopologyButton">
<property name="text">
<string>Fix Topology</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
......@@ -693,13 +679,26 @@ There is no automatic algorithm to fix these foldovers here. So you will have to
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>General</string>
<string>General Operations</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QPushButton" name="fixNonManifoldVerticesButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Remove non-manifold vertices by duplicating them&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Fix non-manifold vertices</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QPushButton" name="fixMeshButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This button will try to fix triangle meshes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Degenerated faces will be removed and all vertices which are closer than the given distance will be collapsed. Non-manifold configurations at vertices will be removed and all faces of each component will be updated to have the same orientation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Fix Triangle Mesh</string>
</property>
......
This diff is collapsed.
......@@ -169,9 +169,14 @@ private slots:
void slotSnapBoundary();
/// Button slot
void slotFixTopology();
void slotFixNonManifoldVertices();
//===========================================================================
/** @name Scripting functions
* @{ */
//===========================================================================
//Scripting functions:
public slots:
/// Remove all selected valence 3 vertices
......@@ -189,23 +194,12 @@ public slots:
/// Detect triangle with aspect of _aspect and select candidates
void detectTriangleAspect(int _objectId, float _aspect);
/// Recomputes the face normals of an object
void updateFaceNormals(int _objectId);
/// Recomputes the halfedge normals of an object
void updateHalfedgeNormals(int _objectId);
/// Recomputes the vertex normals of an object
void updateVertexNormals(int _objectId);
/// Recomputes the face and vertex normals of an object
void updateNormals(int _objectId);
/// Flips the normals of all faces by changing the vertex order
void flipOrientation(int _objectId);
/// Fix a mesh
void fixMesh(int _objectId, double _epsilon);
/// Selects all edges of an object which are shorter than the given length
void selectEdgesShorterThan(int _objectId,double _length);
......@@ -218,7 +212,52 @@ public slots:
void snapBoundary(int _objectId, double _eps);
void fixTopology(int _objectId);
// ==================================================
// Normal recomputations
// ==================================================
/// Recomputes the face normals of an object
void updateFaceNormals(int _objectId);
/// Recomputes the halfedge normals of an object
void updateHalfedgeNormals(int _objectId);
/// Recomputes the vertex normals of an object
void updateVertexNormals(int _objectId);
/// Recomputes the face and vertex normals of an object
void updateNormals(int _objectId);
// ==================================================
// General
// ==================================================
/** \brief remove non-manifold vertices by duplicating them
*
* @param _objectId Id of the mesh to fix
*/
void fixNonManifoldVertices(int _objectId);
/** \brief Fix a mesh
*
* Degenerated faces will be removed and all vertices which are closer than the given distance
* will be collapsed. Non-manifold configurations at vertices will be removed and all faces of
* each component will be updated to have the same orientation.
*
* @param _objectId Id of the object to fix
* @param _epsilon Snapping distance
*/
void fixMesh(int _objectId, double _epsilon);
/** @} */
private:
/** \brief select edges based on length
......@@ -258,12 +297,20 @@ 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
/** \brief Removes non-manifold vertices by duplicating them
*
* @param _mesh target mesh
*/
template<typename MeshT>
void fixTopology(MeshT *_mesh);
void fixNonManifoldVertices(MeshT *_mesh);
// Checked from here
public slots:
QString version() {
......
......@@ -243,6 +243,7 @@ void MeshRepairPlugin::snapBoundary(MeshT *_mesh, double _eps)
}
}
vertexDistMap.erase(v_oldIter);
//todo: delete vertex before proceed. Now, they will be deleted at the end resulting worse snap
}
_mesh->delete_isolated_vertices();
......@@ -252,8 +253,9 @@ void MeshRepairPlugin::snapBoundary(MeshT *_mesh, double _eps)
}
//-----------------------------------------------------------------------------
template<typename MeshT>
void MeshRepairPlugin::fixTopology(MeshT *_mesh)
void MeshRepairPlugin::fixNonManifoldVertices(MeshT *_mesh)
{
OpenMesh::FPropHandleT< size_t > component;
if ( !_mesh->get_property_handle(component,"component") )
......@@ -269,7 +271,7 @@ void MeshRepairPlugin::fixTopology(MeshT *_mesh)
//search and isolate new components
//shared vertices will be doublicated
//shared vertices will be duplicated
for (typename MeshT::VertexFaceIter vf_iter = _mesh->vf_begin(v_iter); vf_iter; ++vf_iter)
{
//get the first face in the component
......@@ -280,8 +282,8 @@ void MeshRepairPlugin::fixTopology(MeshT *_mesh)
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)
// if a reference face was found, a new component exists
// and a new vertex is required (except for the first component)
typename MeshT::VertexHandle v_new;
if (componentCount > 1 && !checkNeighbour.empty())
{
......@@ -289,20 +291,20 @@ void MeshRepairPlugin::fixTopology(MeshT *_mesh)
v_new = _mesh->add_vertex(p);
}
//check all adjacent faces of our reference
// 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
// get all neighbor 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
//find the next neighbor 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)
{
......@@ -321,7 +323,7 @@ void MeshRepairPlugin::fixTopology(MeshT *_mesh)
}
}
//if one face wasn't found in the component = 1 run, then it is a new component, due split it
//if one face wasn't found in the component = 1 run, then it is a new component, due to split
if (componentCount > 1 && v_new.is_valid())
{
std::replace(f_vertices.begin(),f_vertices.end(),v_iter.handle(),v_new);
......@@ -332,8 +334,8 @@ void MeshRepairPlugin::fixTopology(MeshT *_mesh)
}
}
//all faces which belongs to v_iter and inside same component found
//the next face will be in a new component
// all faces which belong to v_iter and inside same component found
// the next face will be in a new component
++componentCount;
}
}
......
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 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: 15713 $ *
* $LastChangedBy: moebius $ *
* $Date: 2012-10-25 12:58:58 +0200 (Do, 25 Okt 2012) $ *
* *
\*===========================================================================*/
#include "MeshRepairPlugin.hh"
//-----------------------------------------------------------------------------
void MeshRepairPlugin::updateFaceNormals(int _objectId) {
BaseObjectData* object = 0;
PluginFunctions::getObject(_objectId,object);
if ( object == 0) {
emit log(LOGERR,tr("updateFaceNormals: Unable to get object %1. ").arg(_objectId) );
return;
}
if ( object->dataType(DATA_TRIANGLE_MESH) ) {
TriMesh* mesh = PluginFunctions::triMesh(object);
mesh->update_face_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Updated Face Normals", UPDATE_ALL);
emit scriptInfo( "updateFaceNormals(" + QString::number(_objectId) + ")" );
} else if ( object->dataType(DATA_POLY_MESH) ) {
PolyMesh* mesh = PluginFunctions::polyMesh(object);
mesh->update_face_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Updated Face Normals", UPDATE_ALL);
emit scriptInfo( "updateFaceNormals(" + QString::number(_objectId) + ")" );
} else
emit log(LOGERR,tr("updateFaceNormals: MeshRepair only works on triangle and poly meshes!") );
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::updateHalfedgeNormals(int _objectId) {
BaseObjectData* object = 0;
PluginFunctions::getObject(_objectId,object);
if ( object == 0) {
emit log(LOGERR,tr("updateFaceNormals: Unable to get object %1. ").arg(_objectId) );
return;
}
if ( object->dataType(DATA_TRIANGLE_MESH) ) {
TriMesh* mesh = PluginFunctions::triMesh(object);
mesh->request_halfedge_normals();
mesh->update_halfedge_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Updated Face Normals", UPDATE_ALL);
emit scriptInfo( "updateFaceNormals(" + QString::number(_objectId) + ")" );
} else if ( object->dataType(DATA_POLY_MESH) ) {
PolyMesh* mesh = PluginFunctions::polyMesh(object);
mesh->request_halfedge_normals();
mesh->update_halfedge_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Updated Face Normals", UPDATE_ALL);
emit scriptInfo( "updateFaceNormals(" + QString::number(_objectId) + ")" );
} else
emit log(LOGERR,tr("updateFaceNormals: MeshRepair only works on triangle and poly meshes!") );
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::updateVertexNormals(int _objectId){
BaseObjectData* object = 0;
PluginFunctions::getObject(_objectId,object);
if ( object == 0) {
emit log(LOGERR,tr("updateVertexNormals: Unable to get object %1. ").arg(_objectId) );
return;
}
if ( object->dataType(DATA_TRIANGLE_MESH) ) {
TriMesh* mesh = PluginFunctions::triMesh(object);
mesh->update_vertex_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Updated Vertex Normals", UPDATE_ALL);
emit scriptInfo( "updateVertexNormals(" + QString::number(_objectId) + ")" );
} else if ( object->dataType(DATA_POLY_MESH) ) {
PolyMesh* mesh = PluginFunctions::polyMesh(object);
mesh->update_vertex_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Updated Vertex Normals", UPDATE_ALL);
emit scriptInfo( "updateVertexNormals(" + QString::number(_objectId) + ")" );
} else
emit log(LOGERR,tr("updateVertexNormals: MeshRepair only works on triangle and poly meshes!") );
}
//-----------------------------------------------------------------------------
void MeshRepairPlugin::updateNormals(int _objectId) {
BaseObjectData* object = 0;
PluginFunctions::getObject(_objectId,object);
if ( object == 0) {
emit log(LOGERR,tr("updateNormals: Unable to get object %1. ").arg(_objectId) );
return;
}
if ( object->dataType(DATA_TRIANGLE_MESH) ) {
TriMesh* mesh = PluginFunctions::triMesh(object);
mesh->update_normals();
emit scriptInfo( "updateNormals(" + QString::number(_objectId) + ")" );
} else if ( object->dataType(DATA_POLY_MESH) ) {
PolyMesh* mesh = PluginFunctions::polyMesh(object);
mesh->update_normals();
emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup( _objectId, "Updated All Normals", UPDATE_ALL);
emit scriptInfo( "updateNormals(" + QString::number(_objectId) + ")" );
} else
emit log(LOGERR,tr("updateNormals: MeshRepair only works on triangle and poly meshes!") );
}
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