SmootherPlugin.cc 6.89 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
//  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$
//
//=============================================================================




35

Jan Möbius's avatar
 
Jan Möbius committed
36
37
38
39
40
41
#include <QtGui>
 #include <QSpacerItem>

#include "SmootherPlugin.hh"

#include <iostream>
42
#include <ACG/GL/GLState.hh>
Jan Möbius's avatar
 
Jan Möbius committed
43
44
45
46
47
48

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

 bool SmootherPlugin::initializeToolbox(QWidget*& _widget)
{
   // Create the Toolbox Widget
49
   tool_ = new QWidget();
Jan Möbius's avatar
 
Jan Möbius committed
50
51
   _widget = tool_;
   QSize size(300, 300);
52
53
54
55
   tool_->resize(size);
   MeshDialogLayout_ = new QGridLayout( tool_);


Jan Möbius's avatar
 
Jan Möbius committed
56
   smoothButton_ = new QPushButton("&Smooth",tool_);
57

Jan Möbius's avatar
 
Jan Möbius committed
58
59
60
61
   iterationsSpinbox_ =  new QSpinBox(tool_) ;
   iterationsSpinbox_->setMinimum(1);
   iterationsSpinbox_->setMaximum(1000);
   iterationsSpinbox_->setSingleStep(1);
62

Jan Möbius's avatar
 
Jan Möbius committed
63
64
   smootherTypeBox_ = new QComboBox();
   smootherTypeBox_->addItem("Simple Laplace");
65

Jan Möbius's avatar
 
Jan Möbius committed
66
67
68
69
   MeshDialogLayout_->addWidget( smootherTypeBox_,0 , 0 , 1 , 2 , Qt::AlignTop );
   MeshDialogLayout_->addWidget( smoothButton_     , 1, 0 , Qt::AlignTop );
   MeshDialogLayout_->addWidget( iterationsSpinbox_, 1, 1 , Qt::AlignTop );
   MeshDialogLayout_->addItem(new QSpacerItem(10,10,QSizePolicy::Expanding,QSizePolicy::Expanding),2,0,1,2);
70

Jan Möbius's avatar
 
Jan Möbius committed
71
   connect(smoothButton_,SIGNAL(clicked()),this,SLOT(slotSmooth()));
72

Jan Möbius's avatar
 
Jan Möbius committed
73
74
75
76
   return true;
}

void SmootherPlugin::simpleLaplace() {
77
78
79


   for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DATA_TRIANGLE_MESH) ;
Jan Möbius's avatar
   
Jan Möbius committed
80
                                         o_it != PluginFunctions::objectsEnd(); ++o_it)  {
Jan Möbius's avatar
 
Jan Möbius committed
81
82
       // Get the mesh to work on
      TriMesh* mesh = PluginFunctions::triMesh(*o_it);
83

Jan Möbius's avatar
 
Jan Möbius committed
84
85
      // Add a property to the mesh to store original vertex positions
      mesh->add_property( orig_pos_, "SmootherPlugin_Original_Positions" );
86

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

Jan Möbius's avatar
 
Jan Möbius committed
89
90
91
92
93
         // 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(  orig_pos_ , v_it ) = mesh->point(v_it);
         }
94

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

Jan Möbius's avatar
 
Jan Möbius committed
98
            TriMesh::Point point = TriMesh::Point(0.0,0.0,0.0);
99

Jan Möbius's avatar
 
Jan Möbius committed
100
101
            // Flag, to skip boundary vertices
            bool skip = false;
102

Jan Möbius's avatar
 
Jan Möbius committed
103
104
105
106
107
            // ( .. for each Outoing 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( orig_pos_ , mesh->to_vertex_handle(voh_it) );
108

Jan Möbius's avatar
 
Jan Möbius committed
109
110
111
112
               // 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;
113
                  break;
Jan Möbius's avatar
 
Jan Möbius committed
114
               }
115

Jan Möbius's avatar
 
Jan Möbius committed
116
            }
117

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

Jan Möbius's avatar
 
Jan Möbius committed
121
122
123
124
125
            if ( ! skip ) {
               // Set new position for the mesh if its not on the boundary
               mesh->point(v_it) = point;
            }
         }
126

Jan Möbius's avatar
 
Jan Möbius committed
127
      }// Iterations end
128

Jan Möbius's avatar
 
Jan Möbius committed
129
130
      // Remove the property
      mesh->remove_property( orig_pos_);
131

Jan Möbius's avatar
 
Jan Möbius committed
132
      mesh->update_normals();
133

Jan Möbius's avatar
   
Jan Möbius committed
134
      emit updatedObject( o_it->id() );
Jan Möbius's avatar
 
Jan Möbius committed
135
   }
136
137

     for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DATA_POLY_MESH) ;
Jan Möbius's avatar
   
Jan Möbius committed
138
                                         o_it != PluginFunctions::objectsEnd(); ++o_it)  {
Jan Möbius's avatar
 
Jan Möbius committed
139
140
       // Get the mesh to work on
      PolyMesh* mesh = dynamic_cast< MeshObject< PolyMesh,DATA_POLY_MESH >* > (*o_it)->mesh();
141

Jan Möbius's avatar
 
Jan Möbius committed
142
143
      // Add a property to the mesh to store original vertex positions
      mesh->add_property( orig_pos_, "SmootherPlugin_Original_Positions" );
144

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

Jan Möbius's avatar
 
Jan Möbius committed
147
148
149
150
151
         // 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(  orig_pos_ , v_it ) = mesh->point(v_it);
         }
152

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

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

Jan Möbius's avatar
 
Jan Möbius committed
158
159
            // Flag, to skip boundary vertices
            bool skip = false;
160

Jan Möbius's avatar
 
Jan Möbius committed
161
162
163
164
165
            // ( .. 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( orig_pos_ , mesh->to_vertex_handle(voh_it) );
166

Jan Möbius's avatar
 
Jan Möbius committed
167
168
169
170
               // 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;
171
                  break;
Jan Möbius's avatar
 
Jan Möbius committed
172
               }
173

Jan Möbius's avatar
 
Jan Möbius committed
174
            }
175

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

Jan Möbius's avatar
 
Jan Möbius committed
179
180
181
182
183
            if ( ! skip ) {
               // Set new position for the mesh if its not on the boundary
               mesh->point(v_it) = point;
            }
         }
184

Jan Möbius's avatar
 
Jan Möbius committed
185
      }// Iterations end
186

Jan Möbius's avatar
 
Jan Möbius committed
187
188
      // Remove the property
      mesh->remove_property( orig_pos_);
189

Jan Möbius's avatar
 
Jan Möbius committed
190
      mesh->update_normals();
191

Jan Möbius's avatar
   
Jan Möbius committed
192
      emit updatedObject( o_it->id() );
Jan Möbius's avatar
 
Jan Möbius committed
193
   }
194

Jan Möbius's avatar
 
Jan Möbius committed
195
196
197
198
199
}

 void SmootherPlugin::slotSmooth()
{
  switch (smootherTypeBox_->currentIndex() ) {
200
    case 0 :
Jan Möbius's avatar
 
Jan Möbius committed
201
202
       simpleLaplace();
       break;
203
     default :
Jan Möbius's avatar
 
Jan Möbius committed
204
205
206
207
208
209
210
        std::cerr << "Smoother : Smoother type error" << std::endl;
  }
}


Q_EXPORT_PLUGIN2( smootherplugin , SmootherPlugin );