SmootherPlugin.cc 13.4 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40 41 42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43 44 45 46 47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
\*===========================================================================*/
Jan Möbius's avatar
Jan Möbius committed
49

Jan Möbius's avatar
 
Jan Möbius committed
50 51 52 53 54 55 56 57 58
//=============================================================================
//
//  CLASS SmootherPlugin - IMPLEMENTATION
//
//=============================================================================


//== INCLUDES =================================================================

Matthias Möller's avatar
Matthias Möller committed
59

Jan Möbius's avatar
 
Jan Möbius committed
60 61 62 63
#include "SmootherPlugin.hh"

#include "SmootherObject.hh"

64
#if QT_VERSION >= 0x050000
65 66 67 68
#else
#include <QtGui>
#endif

Jan Möbius's avatar
 
Jan Möbius committed
69 70 71 72
#define SMOOTHER "SmootherData"

//== IMPLEMENTATION ==========================================================

Jan Möbius's avatar
Jan Möbius committed
73 74 75 76 77 78 79
SmootherPlugin::SmootherPlugin() :
        tool_(0),
        toolIcon_(0)
{
}

//-----------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
80

Jan Möbius's avatar
Jan Möbius committed
81
void
Jan Möbius's avatar
 
Jan Möbius committed
82
SmootherPlugin::
Jan Möbius's avatar
Jan Möbius committed
83
initializePlugin()
Jan Möbius's avatar
 
Jan Möbius committed
84
{
Jan Möbius's avatar
Jan Möbius committed
85 86 87 88
  if ( OpenFlipper::Options::gui() ) {
    tool_ = new SmootherToolbarWidget();
    QSize size(100, 100);
    tool_->resize(size);
Jan Möbius's avatar
 
Jan Möbius committed
89

Jan Möbius's avatar
Jan Möbius committed
90 91
    // connect signals->slots
    connect(tool_->pB_smooth,SIGNAL(clicked() ),this,SLOT(slot_smooth()));
Jan Möbius's avatar
 
Jan Möbius committed
92

Jan Möbius's avatar
Jan Möbius committed
93 94 95
    toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"smoother2.png");
    emit addToolbox( tr("Smoother") , tool_, toolIcon_ );
  }
Jan Möbius's avatar
 
Jan Möbius committed
96 97 98 99
}

//-----------------------------------------------------------------------------

Dirk Wilden's avatar
Dirk Wilden committed
100
/** \brief Set the scripting slot descriptions
101
 *
Dirk Wilden's avatar
Dirk Wilden committed
102 103 104 105
 */
void
SmootherPlugin::pluginsInitialized(){

106 107 108 109
  emit setSlotDescription("smooth(int,int,QString,QString,double,bool)", "Smooth an object",
                           QString("object_id,iterations,direction,continuity,maxDistance,respectFeatures").split(","),
                           QString("id of an object, number of smoothing iterations, Smoothing direction. (tangential;normal;tangential+normal), Continuity. (C1 or C2), max distance the smoothed mesh is allowed to differ from the original,Keep features intact").split(","));

Dirk Wilden's avatar
Dirk Wilden committed
110 111 112 113 114 115 116 117 118 119 120 121 122
  emit setSlotDescription("smooth(int,int,QString,QString,double)", "Smooth an object",
                          QString("object_id,iterations,direction,continuity,maxDistance").split(","),
                          QString("id of an object, number of smoothing iterations, Smoothing direction. (tangential;normal;tangential+normal), Continuity. (C1 or C2), max distance the smoothed mesh is allowed to differ from the original").split(","));

  emit setSlotDescription("smooth(int,int,QString,QString)", "Smooth an object",
                          QString("object_id,iterations,direction,continuity").split(","),
                          QString("id of an object, number of smoothing iterations, Smoothing direction. (tangential;normal;tangential+normal), Continuity. (C1 or C2)").split(","));

}


//-----------------------------------------------------------------------------

123 124
/** \brief Smooth all target objects
 *
Dirk Wilden's avatar
Dirk Wilden committed
125 126 127
 * Parameters for the smoothing are retrieved from the toolbox
 *
 */
Jan Möbius's avatar
 
Jan Möbius committed
128 129 130 131
void
SmootherPlugin::
slot_smooth()
{
Dirk Wilden's avatar
Dirk Wilden committed
132 133
  bool found = false;
  
Jan Möbius's avatar
 
Jan Möbius committed
134 135 136
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DATA_TRIANGLE_MESH) ;
        o_it != PluginFunctions::objectsEnd(); ++o_it)  {

137 138
    QString jobDescription = "Smoothed (";
  
Jan Möbius's avatar
 
Jan Möbius committed
139 140 141 142 143 144 145
    TriMeshObject* object = PluginFunctions::triMeshObject(*o_it);

    if ( object == 0 ) {
      emit log(LOGWARN , "Unable to get object ( Only Triangle Meshes supported)");
      continue;
    }

Dirk Wilden's avatar
Dirk Wilden committed
146 147
    found = true;

Jan Möbius's avatar
 
Jan Möbius committed
148 149
    SmootherObject* data = dynamic_cast< SmootherObject* > ( o_it->objectData(SMOOTHER) );

150 151 152
    // Get triangle mesh
    TriMesh* mesh = PluginFunctions::triMesh(*o_it);
    
Jan Möbius's avatar
Jan Möbius committed
153 154 155 156 157
    if ( mesh == NULL ) {
      emit log(LOGERR, "Unable to get mesh from object( Only Triangle Meshes supported)");
      return;
    }

Jan Möbius's avatar
 
Jan Möbius committed
158
    if (data == 0){
159
      data = new SmootherObject();
Jan Möbius's avatar
 
Jan Möbius committed
160 161
      o_it->setObjectData(SMOOTHER, data);
    }
162 163 164
    
    // Create smoother
    SmootherType smoother(*mesh);
Jan Möbius's avatar
 
Jan Möbius committed
165 166

    OpenMesh::Smoother::SmootherT< TriMesh >::Component component = OpenMesh::Smoother::SmootherT< TriMesh >::Tangential_and_Normal;
167
    if( tool_->rbTangential_and_Normal->isChecked() ) {
Jan Möbius's avatar
 
Jan Möbius committed
168
      component = OpenMesh::Smoother::SmootherT< TriMesh >::Tangential_and_Normal;
169 170
      jobDescription += "tangential and normal,";
    } else if( tool_->rbNormal->isChecked() ) {
Jan Möbius's avatar
 
Jan Möbius committed
171
      component = OpenMesh::Smoother::SmootherT< TriMesh >::Normal;
172 173
      jobDescription += "normal,";
    } else if( tool_->rbTangential->isChecked() ) {
Jan Möbius's avatar
 
Jan Möbius committed
174
      component = OpenMesh::Smoother::SmootherT< TriMesh >::Tangential;
175 176
      jobDescription += "tangential,";
    }
Jan Möbius's avatar
 
Jan Möbius committed
177

178 179 180
    // Set perObjectData
    data->component(component);

Jan Möbius's avatar
 
Jan Möbius committed
181
    OpenMesh::Smoother::SmootherT< TriMesh >::Continuity continuity = OpenMesh::Smoother::SmootherT< TriMesh >::C0;
182
    if( tool_->rB_c0->isChecked() ) {
Jan Möbius's avatar
 
Jan Möbius committed
183
      continuity = OpenMesh::Smoother::SmootherT< TriMesh >::C0;
184 185
      jobDescription += "C0";
    } else if( tool_->rB_c1->isChecked() ) {
Jan Möbius's avatar
 
Jan Möbius committed
186
      continuity = OpenMesh::Smoother::SmootherT< TriMesh >::C1;
187 188
      jobDescription += "C1";
    }
189 190 191
    
    // Set perObjectData
    data->continuity(continuity);
Jan Möbius's avatar
 
Jan Möbius committed
192 193 194 195 196 197 198 199 200

    // Read maximum distance Error from lineEdit
    if ( tool_->cbDistance->isChecked() ) {
      QString value;
      value = tool_->distance->text();
      bool ok = false;

      double absoluteError = value.toDouble(&ok);

201 202 203 204
      if ( ok ) {
        data->distance(absoluteError);
        smoother.set_absolute_local_error( absoluteError );
      } else {
Jan Möbius's avatar
 
Jan Möbius committed
205
        emit log(LOGWARN , "Unable to read distance error from LineEdit");
206
      }
207 208
      
      jobDescription += ",max_error: " + QString::number(absoluteError);
Jan Möbius's avatar
 
Jan Möbius committed
209
    }
210
    
211 212 213 214 215
    // Set perObjectData
    data->features(tool_->respectFeatures->isChecked());
    data->iterations(tool_->sB_iter->value());
    
    // Initialize smoother
David Bommes's avatar
David Bommes committed
216 217 218 219 220 221 222

    if(tool_->cbReinitialize->isChecked() || !data->initialized())
    {
         smoother.initialize(component,continuity );
         data->initialized(true);
    }

223
    smoother.skip_features(data->features());
Jan Möbius's avatar
 
Jan Möbius committed
224

225
    smoother.smooth( data->iterations() );
226 227
    
    jobDescription +=  ") " + QString::number(tool_->sB_iter->value()) + " iterations";
Jan Möbius's avatar
 
Jan Möbius committed
228

Jan Möbius's avatar
Jan Möbius committed
229
    mesh->update_normals();
Jan Möbius's avatar
 
Jan Möbius committed
230

231
    emit updatedObject( o_it->id(), UPDATE_GEOMETRY );
Dirk Wilden's avatar
Dirk Wilden committed
232
    emit createBackup(o_it->id(), "Smoothing", UPDATE_GEOMETRY );
Jan Möbius's avatar
 
Jan Möbius committed
233 234
  }

Dirk Wilden's avatar
Dirk Wilden committed
235 236 237
  if ( !found )
    emit log(LOGERR , tr("Unable to smooth. No triangle mesh selected as target!") );

Jan Möbius's avatar
 
Jan Möbius committed
238 239
}

Dirk Wilden's avatar
Dirk Wilden committed
240 241 242

//-----------------------------------------------------------------------------

243
void SmootherPlugin::smooth(int _objectId , int _iterations , QString _direction , QString _continuity, double _maxDistance, bool _respectFeatures ) {
Dirk Wilden's avatar
Dirk Wilden committed
244

Jan Möbius's avatar
Jan Möbius committed
245 246 247 248 249 250 251 252 253
  BaseObjectData* baseObjectData;
  if ( ! PluginFunctions::getObject(_objectId,baseObjectData) ) {
    emit log(LOGERR,"Unable to get Object");
    return;
  }

  if ( baseObjectData->dataType() == DATA_TRIANGLE_MESH ) {
    TriMeshObject* object = PluginFunctions::triMeshObject(baseObjectData);

254 255
    QString jobDescription = "Smoothed (";
    
Jan Möbius's avatar
Jan Möbius committed
256 257 258 259 260 261 262
    if ( object == 0 ) {
      emit log(LOGWARN , "Unable to get object ( Only Triangle Meshes supported)");
      return;
    }

    SmootherObject* data = dynamic_cast< SmootherObject* > ( object->objectData(SMOOTHER) );

263 264 265
    // Get triangle mesh
    TriMesh* mesh = PluginFunctions::triMesh(object);
    
Jan Möbius's avatar
Jan Möbius committed
266 267 268 269 270
    if ( mesh == NULL ) {
      emit log(LOGERR, "Unable to get mesh from object( Only Triangle Meshes supported)");
      return;
    }

Jan Möbius's avatar
Jan Möbius committed
271
    if (data == 0){
272
      data = new SmootherObject();
Jan Möbius's avatar
Jan Möbius committed
273 274
      object->setObjectData(SMOOTHER, data);
    }
275 276
    
    SmootherType smoother(*mesh);
Jan Möbius's avatar
Jan Möbius committed
277 278 279 280 281

    OpenMesh::Smoother::SmootherT< TriMesh >::Component component = OpenMesh::Smoother::SmootherT< TriMesh >::Tangential_and_Normal;
    bool tangential = _direction.contains("tangential");
    bool normal     = _direction.contains("normal");

282
    if ( tangential && normal ) {
Jan Möbius's avatar
Jan Möbius committed
283
      component = OpenMesh::Smoother::SmootherT< TriMesh >::Tangential_and_Normal;
284 285
      jobDescription += "tangential and normal,";
    } else if ( tangential ) {
Jan Möbius's avatar
Jan Möbius committed
286
      component = OpenMesh::Smoother::SmootherT< TriMesh >::Tangential;
287 288
      jobDescription += "normal,";
    } else {
Jan Möbius's avatar
Jan Möbius committed
289
      component = OpenMesh::Smoother::SmootherT< TriMesh >::Normal;
290 291 292
      jobDescription += "tangential,";
    }
    
293 294
    // Set perObjectData
    data->component(component);
Jan Möbius's avatar
Jan Möbius committed
295 296 297 298 299 300 301

    OpenMesh::Smoother::SmootherT< TriMesh >::Continuity continuity = OpenMesh::Smoother::SmootherT< TriMesh >::C0;
    bool c0 = _continuity.contains("C0");
    bool c1 = _continuity.contains("C1");

    if ( c0 && c1 )
      std::cerr << "Continuity C0 + C1 ? Using C1" << std::endl;
302
    if( c1 ) {
Jan Möbius's avatar
Jan Möbius committed
303
      continuity = OpenMesh::Smoother::SmootherT< TriMesh >::C1;
304 305
      jobDescription += "C1";
    } else if( c0 ) {
Jan Möbius's avatar
Jan Möbius committed
306
      continuity = OpenMesh::Smoother::SmootherT< TriMesh >::C0;
307 308
      jobDescription += "C0";
    }
309 310 311
    
    // Set perObjectData
    data->continuity(continuity);
Jan Möbius's avatar
Jan Möbius committed
312

313
    if ( _maxDistance > 0.0) {
314 315 316
      // Set perObjectData
      data->distance(_maxDistance);
      smoother.set_absolute_local_error( _maxDistance );
317
      jobDescription += ",max_error: " + QString::number(_maxDistance);
318 319 320 321 322
    } else {
      // Set perObjectData
      data->distance( FLT_MAX );
      smoother.set_absolute_local_error( FLT_MAX );
    }
Dirk Wilden's avatar
Dirk Wilden committed
323

324 325 326 327
    // Keep features?
    data->features(_respectFeatures);
    smoother.skip_features(_respectFeatures);

328
    smoother.initialize(component,continuity);
Jan Möbius's avatar
Jan Möbius committed
329

330
    smoother.smooth( _iterations );
Jan Möbius's avatar
Jan Möbius committed
331

332 333
    jobDescription +=  ") " + QString::number(_iterations) + " iterations";
    
Jan Möbius's avatar
Jan Möbius committed
334
    mesh->update_normals();
Jan Möbius's avatar
Jan Möbius committed
335

336
    emit updatedObject( object->id(), UPDATE_GEOMETRY );
Jan Möbius's avatar
Jan Möbius committed
337

338
    // Create backup
Dirk Wilden's avatar
Dirk Wilden committed
339
    emit createBackup(object->id(),"Smoothing", UPDATE_GEOMETRY );
340 341 342
    
    emit scriptInfo(tr("smooth(%1, %2, %3, %4, %5)").arg(QString::number(_objectId), QString::number(_iterations),
                                                    _direction, _continuity, QString::number(_maxDistance)));
Jan Möbius's avatar
Jan Möbius committed
343 344 345 346 347 348 349 350

  } else {
    emit log(LOGERR,"Unsupported object type for smoother");
    return;
  }

}

Jan Möbius's avatar
 
Jan Möbius committed
351 352
//-----------------------------------------------------------------------------

Matthias Möller's avatar
Matthias Möller committed
353 354 355
#if QT_VERSION < 0x050000
  Q_EXPORT_PLUGIN2( SmootherPlugin , SmootherPlugin );
#endif
Jan Möbius's avatar
 
Jan Möbius committed
356