SmootherPlugin.cc 6.88 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//=============================================================================
//
//                               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.
15
//
Jan Möbius's avatar
 
Jan Möbius committed
16
17
18
19
//  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.
20
//
Jan Möbius's avatar
 
Jan Möbius committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision$
//   $Author$
//   $Date$
//
//=============================================================================



#include "SmootherPlugin.hh"

Dirk Wilden's avatar
   
Dirk Wilden committed
36
37
38

#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
Jan Möbius's avatar
 
Jan Möbius committed
39
40
41

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

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

Dirk Wilden's avatar
   
Dirk Wilden committed
48
   QGridLayout* layout = new QGridLayout(toolBox);
49

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

Dirk Wilden's avatar
   
Dirk Wilden committed
52
   iterationsSpinbox_ =  new QSpinBox(toolBox) ;
Jan Möbius's avatar
 
Jan Möbius committed
53
54
55
   iterationsSpinbox_->setMinimum(1);
   iterationsSpinbox_->setMaximum(1000);
   iterationsSpinbox_->setSingleStep(1);
56

Dirk Wilden's avatar
   
Dirk Wilden committed
57
58
59
60
61
   QLabel* label = new QLabel("Iterations:");

   layout->addWidget( label             , 0, 0);
   layout->addWidget( smoothButton      , 1, 1);
   layout->addWidget( iterationsSpinbox_, 0, 1);
62

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

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

Jan Möbius's avatar
 
Jan Möbius committed
67
68
69
   return true;
}

Dirk Wilden's avatar
   
Dirk Wilden committed
70
71
72
/** \brief 
 * 
 */
Jan Möbius's avatar
 
Jan Möbius committed
73
void SmootherPlugin::simpleLaplace() {
74
75


Dirk Wilden's avatar
   
Dirk Wilden committed
76
77
78
79
80
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it) {
    
    if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
    
        // Get the mesh to work on
Jan Möbius's avatar
 
Jan Möbius committed
81
      TriMesh* mesh = PluginFunctions::triMesh(*o_it);
Dirk Wilden's avatar
   
Dirk Wilden committed
82
83
84
85
      
      // Property for the active mesh to store original point positions
      OpenMesh::VPropHandleT< TriMesh::Point > origPositions;
      
Jan Möbius's avatar
 
Jan Möbius committed
86
      // Add a property to the mesh to store original vertex positions
Dirk Wilden's avatar
   
Dirk Wilden committed
87
88
      mesh->add_property( origPositions, "SmootherPlugin_Original_Positions" );
      
Jan Möbius's avatar
 
Jan Möbius committed
89
      for ( int i = 0 ; i < iterationsSpinbox_->value() ; ++i ) {
Dirk Wilden's avatar
   
Dirk Wilden committed
90
91
92
93
94
95
96
97
98
99
      
          // 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);
          }
      
          // Do one smoothing step (For each point of the mesh ... )
          for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
      
Jan Möbius's avatar
 
Jan Möbius committed
100
            TriMesh::Point point = TriMesh::Point(0.0,0.0,0.0);
Dirk Wilden's avatar
   
Dirk Wilden committed
101
      
Jan Möbius's avatar
 
Jan Möbius committed
102
103
            // Flag, to skip boundary vertices
            bool skip = false;
Dirk Wilden's avatar
   
Dirk Wilden committed
104
      
Jan Möbius's avatar
 
Jan Möbius committed
105
106
107
            // ( .. for each Outoing halfedge .. )
            TriMesh::VertexOHalfedgeIter voh_it(*mesh,v_it);
            for ( ; voh_it; ++voh_it ) {
Dirk Wilden's avatar
   
Dirk Wilden committed
108
109
110
111
112
113
                // .. add the (original) position of the Neighbour ( end of the outgoing halfedge )
                point += mesh->property( origPositions, mesh->to_vertex_handle(voh_it) );
      
                // 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() ) ) {
Jan Möbius's avatar
 
Jan Möbius committed
114
                  skip = true;
115
                  break;
Dirk Wilden's avatar
   
Dirk Wilden committed
116
117
                }
      
Jan Möbius's avatar
 
Jan Möbius committed
118
            }
Dirk Wilden's avatar
   
Dirk Wilden committed
119
      
Jan Möbius's avatar
 
Jan Möbius committed
120
121
            // Devide by the valence of the current vertex
            point /= mesh->valence( v_it );
Dirk Wilden's avatar
   
Dirk Wilden committed
122
      
Jan Möbius's avatar
 
Jan Möbius committed
123
            if ( ! skip ) {
Dirk Wilden's avatar
   
Dirk Wilden committed
124
125
                // Set new position for the mesh if its not on the boundary
                mesh->point(v_it) = point;
Jan Möbius's avatar
 
Jan Möbius committed
126
            }
Dirk Wilden's avatar
   
Dirk Wilden committed
127
128
          }
      
Jan Möbius's avatar
 
Jan Möbius committed
129
      }// Iterations end
Dirk Wilden's avatar
   
Dirk Wilden committed
130
      
Jan Möbius's avatar
 
Jan Möbius committed
131
      // Remove the property
Dirk Wilden's avatar
   
Dirk Wilden committed
132
133
      mesh->remove_property( origPositions );
      
Jan Möbius's avatar
 
Jan Möbius committed
134
      mesh->update_normals();
Dirk Wilden's avatar
   
Dirk Wilden committed
135
      
Jan Möbius's avatar
   
Jan Möbius committed
136
      emit updatedObject( o_it->id() );
137

Dirk Wilden's avatar
   
Dirk Wilden committed
138
139
140

   } else if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {

Jan Möbius's avatar
 
Jan Möbius committed
141
142
       // Get the mesh to work on
      PolyMesh* mesh = dynamic_cast< MeshObject< PolyMesh,DATA_POLY_MESH >* > (*o_it)->mesh();
143

Dirk Wilden's avatar
   
Dirk Wilden committed
144
145
146
      // Property for the active mesh to store original point positions
      OpenMesh::VPropHandleT< TriMesh::Point > origPositions;

Jan Möbius's avatar
 
Jan Möbius committed
147
      // Add a property to the mesh to store original vertex positions
Dirk Wilden's avatar
   
Dirk Wilden committed
148
      mesh->add_property( origPositions, "SmootherPlugin_Original_Positions" );
149

Jan Möbius's avatar
 
Jan Möbius committed
150
      for ( int i = 0 ; i < iterationsSpinbox_->value() ; ++i ) {
151

Jan Möbius's avatar
 
Jan Möbius committed
152
153
154
         // 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) {
Dirk Wilden's avatar
   
Dirk Wilden committed
155
            mesh->property( origPositions, v_it ) = mesh->point(v_it);
Jan Möbius's avatar
 
Jan Möbius committed
156
         }
157

Jan Möbius's avatar
 
Jan Möbius committed
158
159
         // Do one smoothing step (For each point of the mesh ... )
         for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
160

Jan Möbius's avatar
 
Jan Möbius committed
161
            PolyMesh::Point point = PolyMesh::Point(0.0,0.0,0.0);
162

Jan Möbius's avatar
 
Jan Möbius committed
163
164
            // Flag, to skip boundary vertices
            bool skip = false;
165

Jan Möbius's avatar
 
Jan Möbius committed
166
167
168
169
            // ( .. 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 )
Dirk Wilden's avatar
   
Dirk Wilden committed
170
               point += mesh->property( origPositions, mesh->to_vertex_handle(voh_it) );
171

Jan Möbius's avatar
 
Jan Möbius committed
172
173
174
175
               // 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;
176
                  break;
Jan Möbius's avatar
 
Jan Möbius committed
177
               }
178

Jan Möbius's avatar
 
Jan Möbius committed
179
            }
180

Jan Möbius's avatar
 
Jan Möbius committed
181
182
            // Devide by the valence of the current vertex
            point /= mesh->valence( v_it );
183

Jan Möbius's avatar
 
Jan Möbius committed
184
185
186
187
188
            if ( ! skip ) {
               // Set new position for the mesh if its not on the boundary
               mesh->point(v_it) = point;
            }
         }
189

Jan Möbius's avatar
 
Jan Möbius committed
190
      }// Iterations end
191

Jan Möbius's avatar
 
Jan Möbius committed
192
      // Remove the property
Dirk Wilden's avatar
   
Dirk Wilden committed
193
      mesh->remove_property( origPositions );
194

Jan Möbius's avatar
 
Jan Möbius committed
195
      mesh->update_normals();
196

Jan Möbius's avatar
   
Jan Möbius committed
197
      emit updatedObject( o_it->id() );
198

Dirk Wilden's avatar
   
Dirk Wilden committed
199
    } else {
Jan Möbius's avatar
 
Jan Möbius committed
200

Dirk Wilden's avatar
   
Dirk Wilden committed
201
202
      emit log(LOGERR, "DataType not supported.");
    }
Jan Möbius's avatar
 
Jan Möbius committed
203
204
205
206
207
208
  }
}


Q_EXPORT_PLUGIN2( smootherplugin , SmootherPlugin );