diff --git a/GeneralMeshFixing.cc b/GeneralMeshFixing.cc new file mode 100644 index 0000000000000000000000000000000000000000..3611d99b5c091b7d3b2826045f93784f30591a2b --- /dev/null +++ b/GeneralMeshFixing.cc @@ -0,0 +1,103 @@ + +/*===========================================================================*\ + * * + * 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 . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $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 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!") ); + +} + +//----------------------------------------------------------------------------- diff --git a/MeshFixingT.cc b/MeshFixingT.cc index 7db4bdd4502534d41e4336e95cb3490a866071d3..3c51af5c1d0cb375f352b0029284d0d2bfd590c1 100644 --- a/MeshFixingT.cc +++ b/MeshFixingT.cc @@ -295,7 +295,7 @@ int MeshFixing::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 @@ -304,7 +304,6 @@ void MeshFixing::fix_orientation() // We need faces to work on! if (faces_.empty()) return; - int fh = 0; std::vector todo; diff --git a/MeshRepairControls.ui b/MeshRepairControls.ui index e616791dbaf8078951239b0b72c7c3ce7671c41d..e232a303fb68b9254de4e70b04b6e91c812b98b6 100644 --- a/MeshRepairControls.ui +++ b/MeshRepairControls.ui @@ -7,7 +7,7 @@ 0 0 432 - 852 + 830 @@ -588,20 +588,6 @@ There is no automatic algorithm to fix these foldovers here. So you will have to - - - - Fix Mesh: - - - - - - - Fix Topology - - - @@ -693,13 +679,26 @@ There is no automatic algorithm to fix these foldovers here. So you will have to - General + General Operations + + + + <html><head/><body><p>Remove non-manifold vertices by duplicating them</p></body></html> + + + Fix non-manifold vertices + + + + + <html><head/><body><p>This button will try to fix triangle meshes. </p><p><br/></p><p>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.</p></body></html> + Fix Triangle Mesh diff --git a/MeshRepairPlugin.cc b/MeshRepairPlugin.cc index b38fad323161b74ca6a311269b985a69112d39d0..0aa8819d09bbc80597e371c4a9f372e22d7423d3 100644 --- a/MeshRepairPlugin.cc +++ b/MeshRepairPlugin.cc @@ -52,7 +52,6 @@ #include #include #include -#include "MeshFixingT.hh" //----------------------------------------------------------------------------- @@ -89,16 +88,26 @@ initializePlugin() //Face operations connect(tool_->triangleAspectButton,SIGNAL(clicked()),this,SLOT(slotDetectTriangleAspect())); connect(tool_->flipOrientation,SIGNAL(clicked()),this,SLOT(slotFlipOrientation())); - connect(tool_->fixTopologyButton,SIGNAL(clicked()),this,SLOT(slotFixTopology())); + + + + // General Operations + connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh())); + + + //================== //Normal operations + //================== connect(tool_->computeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateNormals())); connect(tool_->computeVertexNormals,SIGNAL(clicked()),this,SLOT(slotUpdateVertexNormals())); connect(tool_->computeFaceNormals,SIGNAL(clicked()),this,SLOT(slotUpdateFaceNormals())); connect(tool_->computeHalfedgeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateHalfedgeNormals())); - // General Operations - connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh())); + //================== + // General + //================== + connect(tool_->fixNonManifoldVerticesButton,SIGNAL(clicked()),this,SLOT(slotFixNonManifoldVertices())); toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"meshrepair-toolbox.png"); tool_->repairCollapseEButton->setIcon(*toolIcon_); @@ -274,10 +283,10 @@ void MeshRepairPlugin::slotSnapBoundary() //----------------------------------------------------------------------------- -void MeshRepairPlugin::slotFixTopology() +void MeshRepairPlugin::slotFixNonManifoldVertices() { 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()); + fixNonManifoldVertices(o_it->id()); emit updateView(); } @@ -289,29 +298,15 @@ void MeshRepairPlugin::slotFixTopology() */ void MeshRepairPlugin::pluginsInitialized() { - emit setSlotDescription("updateFaceNormals(int)",tr("Recompute Face normals"), - QStringList(tr("objectId")), - QStringList(tr("ID of an object"))); + // TODO: Check and update - emit setSlotDescription("updateHalfedgeNormals(int)",tr("Recompute Halfedge normals"), - QStringList(tr("objectId")), - QStringList(tr("ID of an object"))); - emit setSlotDescription("updateVertexNormals(int)",tr("Recompute Vertex normals"), - QStringList(tr("objectId")), - QStringList(tr("ID of an object"))); - - emit setSlotDescription("updateNormals(int)",tr("Recompute Face and Vertex normals"), - QStringList(tr("objectId")), - QStringList(tr("ID of an object"))); emit setSlotDescription("flipOrientation(int)",tr("Flips the normals of all faces by changing the vertex order in each face"), QStringList(tr("objectId")), QStringList(tr("ID of an object"))); - emit setSlotDescription("fixMesh(int,double)",tr("Fixes a mesh."), - QString(tr("objectId,distance")).split(","), - QString(tr("ID of an object;Vertices with distance lower than epsilon will be treated as one")).split(";")); + emit setSlotDescription("removeSelectedEdges(int)",tr("Remove the selected edges"), QStringList(tr("objectId")), @@ -344,10 +339,48 @@ void MeshRepairPlugin::pluginsInitialized() { emit setSlotDescription("detectSkinnyTriangleByAngle(int,double,bool)",tr("Select or remove skinny triangles. Whether a triangle is skinny is determined by a minimum angle threshold."), QString(tr("objectId,angle,remove")).split(","), QString(tr("ID of an object;Minimum angle threshold")).split(";")); + emit setSlotDescription("snapBoundary(int,double)",tr("Snaps selected and boundary vertices if the distance is less than the given max. distance."), QString(tr("objectId,epsilon")).split(","), QString(tr("ID of an object;Max Distance")).split(";")); + + + + + // =============================== + // Normal Fixing + // =============================== + + emit setSlotDescription("updateFaceNormals(int)",tr("Recompute Face normals"), + QStringList(tr("objectId")), + QStringList(tr("ID of an object"))); + + emit setSlotDescription("updateHalfedgeNormals(int)",tr("Recompute Halfedge normals"), + QStringList(tr("objectId")), + QStringList(tr("ID of an object"))); + + emit setSlotDescription("updateVertexNormals(int)",tr("Recompute Vertex normals"), + QStringList(tr("objectId")), + QStringList(tr("ID of an object"))); + + emit setSlotDescription("updateNormals(int)",tr("Recompute Face and Vertex normals"), + QStringList(tr("objectId")), + QStringList(tr("ID of an object"))); + + + // =============================== + // General Mesh fixing + // =============================== + + emit setSlotDescription("(int)",tr("Fixes non manifold vertices."), + QString(tr("objectId")).split(","), + QString(tr("ID of an object;Non manifold vertices are splitted.")).split(";")); + + emit setSlotDescription("fixMesh(int,double)",tr("Fixes a mesh."), + QString(tr("objectId,distance")).split(","), + QString(tr("ID of an object;Vertices with distance lower than epsilon will be treated as one.")).split(";")); + } @@ -379,27 +412,7 @@ void MeshRepairPlugin::snapBoundary(int _objectId, double _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) { @@ -630,119 +643,8 @@ void MeshRepairPlugin::detectFoldover(int _objectId, float _angle) { + " with angle greater than " + QString::number(_angle) + "."); } -//----------------------------------------------------------------------------- - -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!") ); -} - //----------------------------------------------------------------------------- void @@ -960,32 +862,6 @@ void MeshRepairPlugin::detectFlatValence3Vertices(int _objectId, double _angle) } -void -MeshRepairPlugin::fixMesh(int _objectId, double _epsilon) { - // get the target mesh - TriMesh* triMesh = 0; - - PluginFunctions::getMesh(_objectId,triMesh); - - if (triMesh) { - MeshFixing 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!") ); - -} - -//----------------------------------------------------------------------------- Q_EXPORT_PLUGIN2( meshrepairplugin , MeshRepairPlugin ); diff --git a/MeshRepairPlugin.hh b/MeshRepairPlugin.hh index 5be8c178e09a903624a51dc65853d02d9a8e32fd..31145f533844d102b0684da00859cdd8e76b15e3 100644 --- a/MeshRepairPlugin.hh +++ b/MeshRepairPlugin.hh @@ -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 static bool sort_less_pair_second(const std::pair &lhs,const std::pair &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 - void fixTopology(MeshT *_mesh); + void fixNonManifoldVertices(MeshT *_mesh); + + // Checked from here public slots: QString version() { diff --git a/MeshRepairPluginT.cc b/MeshRepairPluginT.cc index d94ede3ffb136b024aab5f0fe704c948858c7c7f..bb8b34d7de21a165ba77393d20f96384905d7372 100644 --- a/MeshRepairPluginT.cc +++ b/MeshRepairPluginT.cc @@ -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 -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 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; } } diff --git a/NormalFixing.cc b/NormalFixing.cc new file mode 100644 index 0000000000000000000000000000000000000000..e5b7cf33e30ca850c142a49e1b1c6faa21e70ed4 --- /dev/null +++ b/NormalFixing.cc @@ -0,0 +1,164 @@ + +/*===========================================================================*\ + * * + * 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 . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $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!") ); +} + +