SmootherPlugin.cc 6.35 KB
Newer Older
Dirk Wilden's avatar
Dirk Wilden committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  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.
//
//  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 Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
Jan Möbius's avatar
Jan Möbius committed
26 27 28
//   $Revision$
//   $Author$
//   $Date$
Dirk Wilden's avatar
Dirk Wilden committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
//
//=============================================================================



#include "SmootherPlugin.hh"


#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

bool SmootherPlugin::initializeToolbox(QWidget*& _widget)
{
44 45
  // Create the Toolbox Widget
  QWidget* toolBox = new QWidget();
Dirk Wilden's avatar
Dirk Wilden committed
46

47
  QPushButton* smoothButton = new QPushButton("&Smooth",toolBox);
Dirk Wilden's avatar
Dirk Wilden committed
48

49 50 51 52
  iterationsSpinbox_ =  new QSpinBox(toolBox) ;
  iterationsSpinbox_->setMinimum(1);
  iterationsSpinbox_->setMaximum(1000);
  iterationsSpinbox_->setSingleStep(1);
Dirk Wilden's avatar
Dirk Wilden committed
53

54
  QLabel* label = new QLabel("Iterations:");
Dirk Wilden's avatar
Dirk Wilden committed
55

56
  QGridLayout* layout = new QGridLayout(toolBox);
Dirk Wilden's avatar
Dirk Wilden committed
57

58 59 60
  layout->addWidget( label             , 0, 0);
  layout->addWidget( smoothButton      , 1, 1);
  layout->addWidget( iterationsSpinbox_, 0, 1);
Dirk Wilden's avatar
Dirk Wilden committed
61

62
  layout->addItem(new QSpacerItem(10,10,QSizePolicy::Expanding,QSizePolicy::Expanding),2,0,1,2);
Dirk Wilden's avatar
Dirk Wilden committed
63

64
  connect( smoothButton, SIGNAL(clicked()), this, SLOT(simpleLaplace()) );
Dirk Wilden's avatar
Dirk Wilden committed
65

66 67
  _widget = toolBox;
  return true;
Dirk Wilden's avatar
Dirk Wilden committed
68 69 70 71 72 73 74
}

/** \brief 
 * 
 */
void SmootherPlugin::simpleLaplace() {

75 76
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS);
	o_it != PluginFunctions::objectsEnd(); ++o_it) {
Dirk Wilden's avatar
Dirk Wilden committed
77 78 79
    
    if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
    
80
      // Get the mesh to work on
Dirk Wilden's avatar
Dirk Wilden committed
81 82 83 84 85 86 87 88 89 90
      TriMesh* mesh = PluginFunctions::triMesh(*o_it);
      
      // Property for the active mesh to store original point positions
      OpenMesh::VPropHandleT< TriMesh::Point > origPositions;
      
      // Add a property to the mesh to store original vertex positions
      mesh->add_property( origPositions, "SmootherPlugin_Original_Positions" );
      
      for ( int i = 0 ; i < iterationsSpinbox_->value() ; ++i ) {
      
91 92 93 94 95
	// Copy original positions to backup ( in vertex property )
	TriMesh::VertexIter v_it, v_end=mesh->vertices_end();
	for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
	  mesh->property( origPositions, v_it ) = mesh->point(v_it);
	}
Dirk Wilden's avatar
Dirk Wilden committed
96
      
97 98
	// Do one smoothing step (For each point of the mesh ... )
	for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
Dirk Wilden's avatar
Dirk Wilden committed
99
      
100
	  TriMesh::Point point = TriMesh::Point(0.0,0.0,0.0);
Dirk Wilden's avatar
Dirk Wilden committed
101
      
102 103
	  // Flag, to skip boundary vertices
	  bool skip = false;
Dirk Wilden's avatar
Dirk Wilden committed
104
      
105 106 107 108 109 110 111
	  // ( .. for each outgoing halfedge .. )
	  TriMesh::VertexOHalfedgeIter voh_it(*mesh,v_it);

	  for ( ; voh_it; ++voh_it ) {

	    // .. add the (original) position of the neighbour ( end of the outgoing halfedge )
	    point += mesh->property( origPositions, mesh->to_vertex_handle(voh_it) );
Dirk Wilden's avatar
Dirk Wilden committed
112
      
113 114 115 116 117 118 119
	    // Check if the current Halfedge is a boundary halfedge
	    // If it is, abort and keep the current vertex position
	    if ( mesh->is_boundary( voh_it.handle() ) ) {
	      skip = true;
	      break;
	    }      
	  }
Dirk Wilden's avatar
Dirk Wilden committed
120
      
121 122
	  // Devide by the valence of the current vertex
	  point /= mesh->valence( v_it );
Dirk Wilden's avatar
Dirk Wilden committed
123
      
124 125 126 127 128
	  if ( ! skip ) {
	    // Set new position for the mesh if its not on the boundary
	    mesh->point(v_it) = point;
	  }
	}
Dirk Wilden's avatar
Dirk Wilden committed
129 130 131 132 133 134 135 136 137 138 139
      
      }// Iterations end
      
      // Remove the property
      mesh->remove_property( origPositions );
      
      mesh->update_normals();
      
      emit updatedObject( o_it->id() );


140
    } else if ( o_it->dataType( DATA_POLY_MESH ) ) {
Dirk Wilden's avatar
Dirk Wilden committed
141

142
      // Get the mesh to work on
Dirk Wilden's avatar
Dirk Wilden committed
143 144 145 146 147 148 149 150 151 152
      PolyMesh* mesh = dynamic_cast< MeshObject< PolyMesh,DATA_POLY_MESH >* > (*o_it)->mesh();

      // Property for the active mesh to store original point positions
      OpenMesh::VPropHandleT< TriMesh::Point > origPositions;

      // Add a property to the mesh to store original vertex positions
      mesh->add_property( origPositions, "SmootherPlugin_Original_Positions" );

      for ( int i = 0 ; i < iterationsSpinbox_->value() ; ++i ) {

153 154 155 156 157
	// Copy original positions to backup ( in Vertex property )
	PolyMesh::VertexIter v_it, v_end=mesh->vertices_end();
	for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
	  mesh->property( origPositions, v_it ) = mesh->point(v_it);
	}
Dirk Wilden's avatar
Dirk Wilden committed
158

159 160
	// Do one smoothing step (For each point of the mesh ... )
	for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
Dirk Wilden's avatar
Dirk Wilden committed
161

162
	  PolyMesh::Point point = PolyMesh::Point(0.0,0.0,0.0);
Dirk Wilden's avatar
Dirk Wilden committed
163

164 165
	  // Flag, to skip boundary vertices
	  bool skip = false;
Dirk Wilden's avatar
Dirk Wilden committed
166

167 168 169 170 171
	  // ( .. for each Outoing halfedge .. )
	  PolyMesh::VertexOHalfedgeIter voh_it(*mesh,v_it);
	  for ( ; voh_it; ++voh_it ) {
	    // .. add the (original) position of the Neighbour ( end of the outgoing halfedge )
	    point += mesh->property( origPositions, mesh->to_vertex_handle(voh_it) );
Dirk Wilden's avatar
Dirk Wilden committed
172

173 174 175 176 177 178
	    // Check if the current Halfedge is a boundary halfedge
	    // If it is, abort and keep the current vertex position
	    if ( mesh->is_boundary( voh_it.handle() ) ) {
	      skip = true;
	      break;
	    }
Dirk Wilden's avatar
Dirk Wilden committed
179

180
	  }
Dirk Wilden's avatar
Dirk Wilden committed
181

182 183
	  // Devide by the valence of the current vertex
	  point /= mesh->valence( v_it );
Dirk Wilden's avatar
Dirk Wilden committed
184

185 186 187 188 189
	  if ( ! skip ) {
	    // Set new position for the mesh if its not on the boundary
	    mesh->point(v_it) = point;
	  }
	}
Dirk Wilden's avatar
Dirk Wilden committed
190 191 192 193 194 195 196 197 198 199 200 201

      }// Iterations end

      // Remove the property
      mesh->remove_property( origPositions );

      mesh->update_normals();

      emit updatedObject( o_it->id() );

    } else {

202 203 204
      emit log(LOGERR, "Data type not supported.");

    } // Switch data type
Dirk Wilden's avatar
Dirk Wilden committed
205 206 207 208 209 210
  }
}


Q_EXPORT_PLUGIN2( smootherplugin , SmootherPlugin );