DecimaterPlugin.cc 38.8 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1 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 43
*                                                                            *
\*===========================================================================*/

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


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


Jan Möbius's avatar
Jan Möbius committed
58
//== INCLUDES =================================================================
Jan Möbius's avatar
 
Jan Möbius committed
59

60
#include "DecimaterPlugin.hh"
Matthias Möller's avatar
Matthias Möller committed
61

62
#if QT_VERSION >= 0x050000
Matthias Möller's avatar
Matthias Möller committed
63 64 65 66
#else
  #include <QtGui>
#endif

Jan Möbius's avatar
 
Jan Möbius committed
67

Jan Möbius's avatar
Jan Möbius committed
68
#define DECIMATER "DecimaterData"
Jan Möbius's avatar
 
Jan Möbius committed
69

Jan Möbius's avatar
Jan Möbius committed
70
//== IMPLEMENTATION ==========================================================
Jan Möbius's avatar
 
Jan Möbius committed
71

72 73
DecimaterPlugin::DecimaterPlugin() :
        tool_(0),
74 75 76
        decimater_objects_(),
        toolIcon_(0),
        runningJobs_(0)
77 78 79 80
{

}

Jan Möbius's avatar
Jan Möbius committed
81 82
void DecimaterPlugin::initializePlugin()
{
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158

  if ( OpenFlipper::Options::gui()) {
    tool_ = new DecimaterToolbarWidget();
    QSize size(100, 100);
    tool_->resize(size);

    // connect signals->slots
    connect(tool_->pbDecimate,SIGNAL(clicked() ),this,SLOT(slot_decimate()));
    connect(tool_->pbInitialize,SIGNAL(clicked() ), this, SLOT(slot_initialize()));

    connect(tool_->roundness,SIGNAL(valueChanged(double) ),this,SLOT(slotUpdateRoundness(double)) );
    connect(tool_->roundnessSlider,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateRoundness(int)) );
    connect(tool_->aspectRatio,SIGNAL(valueChanged(double) ),this,SLOT(slotUpdateAspectRatio(double)) );
    connect(tool_->aspectRatioSlider,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateAspectRatio(int)) );
    connect(tool_->distance,SIGNAL(valueChanged(double) ),this,SLOT(slotUpdateDistance()) );
    connect(tool_->edgeLength,SIGNAL(valueChanged(double) ),this,SLOT(slotUpdateEdgeLength()) );
    connect(tool_->normalDeviation,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateNormalDev()) );
    connect(tool_->normalDeviationSlider,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateNormalDev()) );
    connect(tool_->verticesCount,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateVertices()) );
    connect(tool_->verticesCountSlider,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateVertices()) );
    connect(tool_->trianglesCount,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateTriangles()) );
    connect(tool_->trianglesCountSlider,SIGNAL(valueChanged(int) ),this,SLOT(slotUpdateTriangles()) );

    // Force update if the Toolbox gets visible
    connect(tool_, SIGNAL(showing()), this, SLOT( slotUpdateNumVertices() ) );
    connect(tool_, SIGNAL(showing()), this, SLOT( slotUpdateNumTriangles() ) );
    connect(tool_->mixedFactorCounter, SIGNAL(valueChanged(double)), this, SLOT(slotMixedCounterValueChanged(double)) );
    connect(tool_->mixedFactorSlider, SIGNAL(valueChanged(int)), this, SLOT(slotMixedSliderValueChanged(int)) );
    connect(tool_->cbDistance, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->cbNormalDev, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->cbEdgeLength, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->cbIndependentSets, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->cbRoundness, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->cbAspectRatio, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbByDistance, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbByEdgeLength, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbByNormalDeviation, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbConstraintsOnly, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbTriangles, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbUseDecimater, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbUseMC, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbUseMixed, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));
    connect(tool_->rbVertices, SIGNAL(toggled(bool)), this, SLOT(slotDisableDecimation()));

    toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"decimater.png");
    emit addToolbox( tr("Decimater") , tool_, toolIcon_ );

    WhatsThisGenerator generator("Decimater");

    tool_->pbDecimate->setWhatsThis(tool_->pbDecimate->whatsThis()+generator.generateLink("quick_tutorial"));
    tool_->pbInitialize->setWhatsThis(tool_->pbInitialize->whatsThis()+generator.generateLink("quick_tutorial"));
    tool_->rbUseDecimater->setWhatsThis(tool_->rbUseDecimater->whatsThis()+generator.generateLink("incremental"));
    tool_->rbUseMC->setWhatsThis(tool_->rbUseMC->whatsThis()+generator.generateLink("multiple_choice"));
    tool_->rbUseMixed->setWhatsThis(tool_->rbUseMixed->whatsThis()+generator.generateLink("mixed"));
    tool_->cbDistance->setWhatsThis(tool_->cbDistance->whatsThis()+generator.generateLink());
    tool_->cbNormalDev->setWhatsThis(tool_->cbNormalDev->whatsThis()+generator.generateLink());
    tool_->cbEdgeLength->setWhatsThis(tool_->cbEdgeLength->whatsThis()+generator.generateLink());
    tool_->cbIndependentSets->setWhatsThis(tool_->cbIndependentSets->whatsThis()+generator.generateLink());
    tool_->cbRoundness->setWhatsThis(tool_->cbRoundness->whatsThis()+generator.generateLink());
    tool_->cbAspectRatio->setWhatsThis(tool_->cbAspectRatio->whatsThis()+generator.generateLink());
    tool_->rbByDistance->setWhatsThis(tool_->rbByDistance->whatsThis()+generator.generateLink());
    tool_->rbByEdgeLength->setWhatsThis(tool_->rbByEdgeLength->whatsThis()+generator.generateLink());
    tool_->rbByNormalDeviation->setWhatsThis(tool_->rbByNormalDeviation->whatsThis()+generator.generateLink());
    tool_->rbConstraintsOnly->setWhatsThis(tool_->rbConstraintsOnly->whatsThis()+generator.generateLink());
    tool_->rbTriangles->setWhatsThis(tool_->rbTriangles->whatsThis()+generator.generateLink());
    tool_->rbVertices->setWhatsThis(tool_->rbVertices->whatsThis()+generator.generateLink());


    tool_->randomSamplesCounter->setWhatsThis(tool_->randomSamplesCounter->whatsThis()+generator.generateLink("multiple_choice"));
    tool_->mixedFactorCounter->setWhatsThis(tool_->mixedFactorCounter->whatsThis()+generator.generateLink("mixed"));
    tool_->roundness->setWhatsThis(tool_->roundness->whatsThis()+generator.generateLink());
    tool_->aspectRatio->setWhatsThis(tool_->aspectRatio->whatsThis()+generator.generateLink());
    tool_->distance->setWhatsThis(tool_->distance->whatsThis()+generator.generateLink());
    tool_->edgeLength->setWhatsThis(tool_->edgeLength->whatsThis()+generator.generateLink());
    tool_->normalDeviation->setWhatsThis(tool_->normalDeviation->whatsThis()+generator.generateLink());
  }
Matthias Möller's avatar
doc  
Matthias Möller committed
159

Jan Möbius's avatar
 
Jan Möbius committed
160 161
}

Jan Möbius's avatar
Jan Möbius committed
162
/** \brief Initialization of the plugin when it is loaded by the core
Isaak Lim's avatar
Isaak Lim committed
163
 *
Jan Möbius's avatar
 
Jan Möbius committed
164
 */
Jan Möbius's avatar
Jan Möbius committed
165
void DecimaterPlugin::pluginsInitialized() {
Jan Möbius's avatar
 
Jan Möbius committed
166

Jan Möbius's avatar
Jan Möbius committed
167 168
  emit setSlotDescription("decimate(int,QVariantMap)",tr("Decimate a given object"),
                          QString(tr("objectId,constraints")).split(","),
169 170 171 172 173 174 175 176 177 178 179 180
                          QString(tr("ID of an object; Object that can has one or more constraint properties ("
                              "decimater_type [0 (Incremental), 1 (MC), 2 (Mixed)], "
                              "random_samples [For MC/Mixed], "
                              "incremental_percentage [For Mixed], "
                              "decimation_order [0 (by distance), 1 (by normal deviation), 2 (by edge length)], "
                              "distance, "
                              "edge_length, "
                              "normal_deviation, "
                              "roundness, "
                              "aspect_ratio,independent_sets, "
                              "vertices, "
                              "triangles)")).split(";"));
181

182 183 184
  if ( OpenFlipper::Options::gui()) {
    tool_->decTypeOps->setVisible(false);
  }
Jan Möbius's avatar
 
Jan Möbius committed
185 186 187 188 189
}


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

Jan Möbius's avatar
Jan Möbius committed
190
/** \brief sync between values of roundness slider and spinbox in the toolbox
Jan Möbius's avatar
 
Jan Möbius committed
191
 *
Jan Möbius's avatar
Jan Möbius committed
192
 * @param _value new roundness value
Jan Möbius's avatar
 
Jan Möbius committed
193
 */
194
void DecimaterPlugin::slotUpdateRoundness(int _value)
Jan Möbius's avatar
Jan Möbius committed
195 196 197
{
  tool_->roundness->setValue( (double) _value / 100.0 );
  tool_->cbRoundness->setChecked (true);
Jan Möbius's avatar
 
Jan Möbius committed
198 199
}

200 201 202 203 204 205 206 207 208 209
void DecimaterPlugin::slotMixedCounterValueChanged(double _value)
{
  tool_->mixedFactorLabel->setText(QString::number(100-_value)+QString("%"));
  tool_->mixedFactorSlider->setValue(100-_value);
}
void DecimaterPlugin::slotMixedSliderValueChanged(int _value)
{
  tool_->mixedFactorLabel->setText(QString::number(_value)+QString("%"));
  tool_->mixedFactorCounter->setValue(100.0-_value);
}
Jan Möbius's avatar
 
Jan Möbius committed
210 211 212

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

Jan Möbius's avatar
Jan Möbius committed
213
/** \brief sync between values of roundness slider and spinbox in the toolbox
Jan Möbius's avatar
 
Jan Möbius committed
214
 *
Jan Möbius's avatar
Jan Möbius committed
215
 * @param _value new roundness value
Jan Möbius's avatar
 
Jan Möbius committed
216
 */
217
void DecimaterPlugin::slotUpdateRoundness(double _value)
Jan Möbius's avatar
Jan Möbius committed
218 219 220
{
  tool_->roundnessSlider->setValue( (int) (_value * 100) );
  tool_->cbRoundness->setChecked (true);
Jan Möbius's avatar
 
Jan Möbius committed
221 222 223 224
}

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

225 226 227 228 229

/** \brief sync between values of aspect ratio slider and spinbox in the toolbox
 *
 * @param _value new aspect ratio value
 */
230
void DecimaterPlugin::slotUpdateAspectRatio(int _value)
231 232 233 234 235 236 237 238 239 240 241 242
{
  tool_->aspectRatio->setValue( (double) _value / 100.0 );
  tool_->cbAspectRatio->setChecked (true);
}


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

/** \brief sync between values of aspect ratio slider and spinbox in the toolbox
 *
 * @param _value new aspect ratio value
 */
243
void DecimaterPlugin::slotUpdateAspectRatio(double _value)
244 245 246 247 248
{
  tool_->aspectRatioSlider->setValue( (int) (_value * 100) );
  tool_->cbAspectRatio->setChecked (true);
}
//-----------------------------------------------------------------------------
249 250


251
/** \brief Init called by toolbox
Jan Möbius's avatar
 
Jan Möbius committed
252 253
 *
 */
254
void DecimaterPlugin::slot_initialize()
Jan Möbius's avatar
 
Jan Möbius committed
255
{
256

257 258 259
  if ( ! OpenFlipper::Options::gui())
    return;

260 261
  decimater_objects_.clear();

Jan Möbius's avatar
Jan Möbius committed
262
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DATA_TRIANGLE_MESH) ;
263
      o_it != PluginFunctions::objectsEnd(); ++o_it)  {
Jan Möbius's avatar
 
Jan Möbius committed
264

265 266 267 268 269 270 271
	  initialize_object(*o_it);

  }
  tool_->pbDecimate->setEnabled(true);
}

void DecimaterPlugin::initialize_object(BaseObjectData *obj) {
Jan Möbius's avatar
Jan Möbius committed
272
    //initialize
273
    TriMeshObject* object = PluginFunctions::triMeshObject(obj);
Jan Möbius's avatar
 
Jan Möbius committed
274

Jan Möbius's avatar
Jan Möbius committed
275 276
    if ( object == 0 )
      emit log(LOGWARN , tr("Unable to get object"));
Jan Möbius's avatar
 
Jan Möbius committed
277

278
    DecimaterInfo* decimater = dynamic_cast< DecimaterInfo* > ( obj->objectData(DECIMATER) );
Jan Möbius's avatar
 
Jan Möbius committed
279

280
    TriMesh* mesh = PluginFunctions::triMesh(obj);
Isaak Lim's avatar
Isaak Lim committed
281

Jan Möbius's avatar
Jan Möbius committed
282 283
    if (decimater == 0){
      decimater = new DecimaterInfo();
284
      obj->setObjectData(DECIMATER, decimater);
Jan Möbius's avatar
Jan Möbius committed
285
    }
Isaak Lim's avatar
Isaak Lim committed
286

Jan Möbius's avatar
Jan Möbius committed
287 288 289 290 291 292 293 294 295
    // constraint handles for decimation
    ModAspectRatioH     hModAspectRatio;
    ModEdgeLengthH      hModEdgeLength;
    ModHausdorffH       hModHausdorff;
    ModIndependentH     hModIndependent;
    ModNormalDeviationH hModNormalDeviation;
    ModNormalFlippingH  hModNormalFlipping;
    ModQuadricH         hModQuadric;
    ModRoundnessH       hModRoundness;
Isaak Lim's avatar
Isaak Lim committed
296

Jan Möbius's avatar
Jan Möbius committed
297
    // Create decimater
298 299 300 301 302 303 304 305
    ptr::shared_ptr<BaseDecimaterType> decimater_object;
    if (tool_->rbUseDecimater->isChecked())
      decimater_object = ptr::shared_ptr<DecimaterType>(new DecimaterType(*mesh));
    else if(tool_->rbUseMC->isChecked())
      decimater_object = ptr::shared_ptr<McDecimaterType>(new McDecimaterType(*mesh));
    else if(tool_->rbUseMixed->isChecked())
      decimater_object = ptr::shared_ptr<MixedDecimaterType>(new MixedDecimaterType(*mesh));

Isaak Lim's avatar
Isaak Lim committed
306

Jan Möbius's avatar
Jan Möbius committed
307 308
    // Remove old constraints
    if(decimater->distance()) {
309 310
      decimater->removeDistanceConstraint();
      decimater_object->remove(hModHausdorff);
Jan Möbius's avatar
Jan Möbius committed
311 312
    }
    if(decimater->normalDeviation()) {
313 314
      decimater->removeNormalDeviationConstraint();
      decimater_object->remove(hModNormalDeviation);
315 316
    }
    if(decimater->normalFlipping()) {
317 318
      decimater->removeNormalFlippingConstraint();
      decimater_object->remove(hModNormalFlipping);
Jan Möbius's avatar
Jan Möbius committed
319 320
    }
    if(decimater->roundness()) {
321 322
      decimater->removeRoundnessConstraint();
      decimater_object->remove(hModRoundness);
Jan Möbius's avatar
Jan Möbius committed
323
    }
324 325
    if(decimater->aspectRatio()) {
      decimater->removeAspectRatioConstraint();
326
      decimater_object->remove(hModAspectRatio);
327 328 329
    }
    if(decimater->edgeLength()) {
      decimater->removeEdgeLengthConstraint();
330
      decimater_object->remove(hModEdgeLength);
331 332 333
    }
    if(decimater->independentSets()) {
      decimater->removeIndependentSetsConstraint();
334
      decimater_object->remove(hModIndependent);
335 336 337 338 339
    }

    // set priority module: quadric, normal deviation or edge length
    if (tool_->rbByDistance->isChecked()) {
      decimater->setDecimationOrder(DecimaterInfo::DISTANCE);
340 341
      decimater_object->add( hModQuadric );
      decimater_object->module( hModQuadric ).unset_max_err();
342 343
    } else if (tool_->rbByNormalDeviation->isChecked()) {
      decimater->setDecimationOrder(DecimaterInfo::NORMALDEV);
344 345
      decimater_object->add(hModNormalDeviation);
      decimater_object->module(hModNormalDeviation).set_binary(false);
346 347
    } else if (tool_->rbByEdgeLength->isChecked()) {
      decimater->setDecimationOrder(DecimaterInfo::EDGELENGTH);
348 349
      decimater_object->add(hModEdgeLength);
      decimater_object->module(hModEdgeLength).set_binary(false);
350
    }
Jan Möbius's avatar
 
Jan Möbius committed
351

352
    // and set new constraints
Matthias Möller's avatar
Matthias Möller committed
353
    ptr::shared_ptr<DecimaterInit> decInit (new DecimaterInit);
Jan Möbius's avatar
Jan Möbius committed
354
    if ( tool_->cbDistance->isChecked() ) {
Matthias Möller's avatar
Matthias Möller committed
355
      if (  decimater_object->add( decInit->hModHausdorff ) || tool_->rbConstraintsOnly->isChecked() ) {
356
        decimater->setDistanceConstraint( tool_->distance->value() );
Matthias Möller's avatar
Matthias Möller committed
357
        decimater_object->module( decInit->hModHausdorff ).set_tolerance( decimater->distanceValue() );
Jan Möbius's avatar
Jan Möbius committed
358 359
      }
    }
Jan Möbius's avatar
 
Jan Möbius committed
360

Jan Möbius's avatar
Jan Möbius committed
361
    if ( tool_->cbNormalDev->isChecked() ) {
Matthias Möller's avatar
Matthias Möller committed
362
      if (  decimater_object->add( decInit->hModNormalDeviation ) || tool_->rbConstraintsOnly->isChecked() ) {
363
        decimater->setNormalDeviationConstraint( tool_->normalDeviation->value() );
Matthias Möller's avatar
Matthias Möller committed
364
        decimater_object->module( decInit->hModNormalDeviation ).set_normal_deviation( decimater->normalDeviationValue() );
365 366
      }
    } else {
Matthias Möller's avatar
Matthias Möller committed
367
      if ( decimater_object->add( decInit->hModNormalFlipping ) || tool_->rbConstraintsOnly->isChecked() ) {
368
        decimater->setNormalFlippingConstraint();
Jan Möbius's avatar
Jan Möbius committed
369 370
      }
    }
Jan Möbius's avatar
 
Jan Möbius committed
371

Isaak Lim's avatar
Isaak Lim committed
372
    if ( tool_->cbRoundness->isChecked() ) {
Matthias Möller's avatar
Matthias Möller committed
373
      if (  decimater_object->add( decInit->hModRoundness ) || tool_->rbConstraintsOnly->isChecked() ) {
374
        decimater->setRoundnessConstraint( tool_->roundness->value() );
Matthias Möller's avatar
Matthias Möller committed
375
        decimater_object->module( decInit->hModRoundness ).set_min_roundness( decimater->roundnessValue(), true );
Jan Möbius's avatar
Jan Möbius committed
376 377
      }
    }
Jan Möbius's avatar
 
Jan Möbius committed
378

379
    if ( tool_->cbAspectRatio->isChecked() ) {
Matthias Möller's avatar
Matthias Möller committed
380
      if ( decimater_object->add( decInit->hModAspectRatio ) || tool_->rbConstraintsOnly->isChecked() ) {
381
        decimater->setAspectRatioConstraint( tool_->aspectRatio->value() );
Matthias Möller's avatar
Matthias Möller committed
382
        decimater_object->module( decInit->hModAspectRatio ).set_aspect_ratio( decimater->aspectRatioValue() );
383 384 385 386
      }
    }

    if ( tool_->cbEdgeLength->isChecked() ) {
Matthias Möller's avatar
Matthias Möller committed
387
      if ( decimater_object->add( decInit->hModEdgeLength ) || tool_->rbConstraintsOnly->isChecked() ) {
388
        decimater->setEdgeLengthConstraint( tool_->edgeLength->value() );
Matthias Möller's avatar
Matthias Möller committed
389
        decimater_object->module( decInit->hModEdgeLength ).set_edge_length( decimater->edgeLengthValue() );
390 391 392 393
      }
    }

    if ( tool_->cbIndependentSets->isChecked() ) {
Matthias Möller's avatar
Matthias Möller committed
394
      if ( decimater_object->add( decInit->hModIndependent ) || tool_->rbConstraintsOnly->isChecked() ) {
395
        decimater->setIndependentSetsConstraint();
396 397 398
      }
    }

Jan Möbius's avatar
 
Jan Möbius committed
399

400 401 402
    // Initialize the decimater
    if( ! decimater_object->initialize() ){
      emit log(LOGWARN, tr("Decimater could not be initialized"));
403
      return;
404
    }
Matthias Möller's avatar
Matthias Möller committed
405 406

    decInit->decimater = decimater_object;
407
    decInit->objId = obj->id();
Matthias Möller's avatar
Matthias Möller committed
408 409

    decimater_objects_.push_back(decInit);
410
}
411 412 413 414 415 416 417 418 419 420 421 422 423 424

void DecimaterPlugin::slot_initialize_object(int obj_id, bool clear) {
	if (clear)
		decimater_objects_.clear();

	BaseObjectData *obj = 0;
	PluginFunctions::getObject(obj_id, obj);
	if (!obj) return;

	initialize_object(obj);

	tool_->pbDecimate->setEnabled(true);
}

425 426 427 428 429 430
//-----------------------------------------------------------------------------
/** \brief Decimation called by toolbox
 *
 */
void DecimaterPlugin::slot_decimate()
{
Matthias Möller's avatar
Matthias Möller committed
431

432 433 434
  if ( ! OpenFlipper::Options::gui())
    return;

435
  //decimate
436
  runningJobs_ = decimater_objects_.size();
Matthias Möller's avatar
Matthias Möller committed
437
  for (std::vector< ptr::shared_ptr<DecimaterInit> >::iterator decIter = decimater_objects_.begin();
438 439
      decIter != decimater_objects_.end(); ++decIter)
  {
Matthias Möller's avatar
Matthias Möller committed
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
    ptr::shared_ptr<DecimaterInit> decInit = *decIter;
    ptr::shared_ptr<BaseDecimaterType> decimater = decInit->decimater;

    // set values for constraints
    if ( tool_->cbDistance->isChecked() ) {
        decimater->module( decInit->hModHausdorff ).set_tolerance( tool_->distance->value() );
    }

    if ( tool_->cbNormalDev->isChecked() ) {
      decimater->module( decInit->hModNormalDeviation ).set_normal_deviation( tool_->normalDeviation->value() );
    }

    if ( tool_->cbRoundness->isChecked() ) {
      decimater->module( decInit->hModRoundness ).set_min_roundness( tool_->roundness->value(), true );
    }

    if ( tool_->cbAspectRatio->isChecked() ) {
      decimater->module( decInit->hModAspectRatio ).set_aspect_ratio( tool_->aspectRatio->value() );
    }

    if ( tool_->cbEdgeLength->isChecked() ) {
      decimater->module( decInit->hModEdgeLength ).set_edge_length( tool_->edgeLength->value() );
    }

464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
    // fill data for the decimate thread
    DecimateThread::Params params;
    params.dec = (tool_->rbUseDecimater->isChecked()) ? dynamic_cast<DecimaterType*>(decimater.get()) : NULL;
    params.mcDec = (tool_->rbUseMC->isChecked())   ? dynamic_cast<McDecimaterType*>(decimater.get()) : NULL;
    params.mixedDec = (tool_->rbUseMixed->isChecked())   ? dynamic_cast<MixedDecimaterType*>(decimater.get()) : NULL;

    params.facesCount = (tool_->rbTriangles->isChecked()) ? tool_->trianglesCount->value() : -1;
    params.verticesCount = (tool_->rbVertices->isChecked() ) ? tool_->verticesCount->value() : -1;
    params.samples = tool_->randomSamplesCounter->value();
    params.mc_factor = 1.0 - (tool_->mixedFactorCounter->value()*0.01);

    // create and start decimate thread
    QString jobId = QString("Decimate_Object_%1").arg(decInit->objId);
    DecimateThread* th = new DecimateThread(params, jobId, decInit->objId);
    connect(th, SIGNAL(finished(QString)), this,SIGNAL(finishJob(QString)));
    connect(th, SIGNAL(finished(QString)), this, SLOT(slot_decimate_finished(QString)));
    connect(th, SIGNAL(state(QString, int)), this, SIGNAL(setJobState(QString, int)));
    connect(this, SIGNAL(jobCanceled(QString)), th, SLOT(slotCancel(QString)));

    tool_->pbDecimate->setEnabled(false);
    tool_->pbInitialize->setEnabled(false);
Jan Möbius's avatar
Jan Möbius committed
485

486
    emit startJob(jobId , QString("Decimate Object with Id %1").arg(decInit->objId) , 0, 100, false);
487

488 489
    th->start();
    th->startProcessing();
Isaak Lim's avatar
Isaak Lim committed
490

Jan Möbius's avatar
Jan Möbius committed
491
  }
Jan Möbius's avatar
 
Jan Möbius committed
492

493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525

}

void DecimaterPlugin::canceledJob (QString _job )
{
  emit jobCanceled(_job);
}

void DecimaterPlugin::slot_decimate_finished(QString _jobId)
{
  //This function is executed by the main thread! but the sender is the finished thread
  DecimateThread* thread = dynamic_cast<DecimateThread*>(sender());

  if (!thread)
    return;
  if (!thread->baseDecimater())
    return;

  //update mesh
  thread->baseDecimater()->mesh().garbage_collection();
  thread->baseDecimater()->mesh().update_normals();

  emit updatedObject( thread->objectId() , UPDATE_TOPOLOGY );
  emit createBackup( thread->objectId(), "Decimation");

  //cleanup when all threads are done
  --runningJobs_;//running in main thread, so no race condition
  if (runningJobs_ == 0)
  {
    tool_->pbDecimate->setEnabled(true);
    tool_->pbInitialize->setEnabled(true);
    emit updateView();
  }
Jan Möbius's avatar
 
Jan Möbius committed
526 527
}

Jan Möbius's avatar
Jan Möbius committed
528 529 530

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

Jan Möbius's avatar
Jan Möbius committed
531
void DecimaterPlugin::decimate(int _objID, QVariantMap _constraints) {
Jan Möbius's avatar
 
Jan Möbius committed
532

Jan Möbius's avatar
Jan Möbius committed
533 534 535 536 537 538 539 540
  BaseObjectData* baseObjectData;
  if ( ! PluginFunctions::getObject(_objID,baseObjectData) ) {
    emit log(LOGERR,tr("Unable to get Object"));
    return;
  }

  if ( baseObjectData->dataType() == DATA_TRIANGLE_MESH ) {
    TriMeshObject* object = PluginFunctions::triMeshObject(baseObjectData);
Jan Möbius's avatar
 
Jan Möbius committed
541

Jan Möbius's avatar
Jan Möbius committed
542 543 544 545
    if ( object == 0 ) {
      emit log(LOGWARN , tr("Unable to get object ( Only Triangle Meshes supported)"));
      return;
    }
Jan Möbius's avatar
 
Jan Möbius committed
546

Jan Möbius's avatar
Jan Möbius committed
547
    DecimaterInfo* decimater = dynamic_cast< DecimaterInfo* > ( object->objectData(DECIMATER) );
Jan Möbius's avatar
 
Jan Möbius committed
548

Jan Möbius's avatar
Jan Möbius committed
549
    TriMesh* mesh = PluginFunctions::triMesh(baseObjectData);
Isaak Lim's avatar
Isaak Lim committed
550

Jan Möbius's avatar
Jan Möbius committed
551 552 553 554
    if (decimater == 0){
      decimater = new DecimaterInfo();
      object->setObjectData(DECIMATER, decimater);
    }
Isaak Lim's avatar
Isaak Lim committed
555

Jan Möbius's avatar
 
Jan Möbius committed
556
    // constraint handles for decimation
Jan Möbius's avatar
Jan Möbius committed
557 558 559 560
    ModAspectRatioH     hModAspectRatio;
    ModEdgeLengthH      hModEdgeLength;
    ModHausdorffH       hModHausdorff;
    ModIndependentH     hModIndependent;
Jan Möbius's avatar
 
Jan Möbius committed
561
    ModNormalDeviationH hModNormalDeviation;
Jan Möbius's avatar
Jan Möbius committed
562 563 564
    ModNormalFlippingH  hModNormalFlipping;
    ModQuadricH         hModQuadric;
    ModRoundnessH       hModRoundness;
Isaak Lim's avatar
Isaak Lim committed
565

Jan Möbius's avatar
Jan Möbius committed
566
    // Create decimater
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
    ptr::shared_ptr<BaseDecimaterType> decimater_object;
    if (_constraints.contains("decimater_type"))
    {
      bool ok;
      int value = _constraints["decimater_type"].toInt(&ok);
      if (ok)
      {
        if (value == 0)
          decimater_object = ptr::shared_ptr<DecimaterType>(new DecimaterType(*mesh));
        else if (value == 1)
          decimater_object = ptr::shared_ptr<McDecimaterType>(new McDecimaterType(*mesh));
        else if (value == 2)
          decimater_object = ptr::shared_ptr<MixedDecimaterType>(new MixedDecimaterType(*mesh));
      }

    }

    if (!decimater_object)
      decimater_object = ptr::shared_ptr<DecimaterType>(new DecimaterType(*mesh));
Jan Möbius's avatar
Jan Möbius committed
586 587 588

    // Remove old constraints
    if(decimater->distance()) {
589
      decimater->removeDistanceConstraint();
590
      decimater_object->remove(hModHausdorff);
Jan Möbius's avatar
Jan Möbius committed
591 592
    }
    if(decimater->normalDeviation()) {
593
      decimater->removeNormalDeviationConstraint();
594
      decimater_object->remove(hModNormalDeviation);
595 596 597
    }
    if(decimater->normalFlipping()) {
      decimater->removeNormalFlippingConstraint();
598
      decimater_object->remove(hModNormalFlipping);
Jan Möbius's avatar
Jan Möbius committed
599 600
    }
    if(decimater->roundness()) {
601
      decimater->removeRoundnessConstraint();
602
      decimater_object->remove(hModRoundness);
603 604 605
    }
    if(decimater->aspectRatio()) {
      decimater->removeAspectRatioConstraint();
606
      decimater_object->remove(hModAspectRatio);
607 608 609
    }
    if(decimater->edgeLength()) {
      decimater->removeEdgeLengthConstraint();
610
      decimater_object->remove(hModEdgeLength);
611 612 613
    }
    if(decimater->independentSets()) {
      decimater->removeIndependentSetsConstraint();
614
      decimater_object->remove(hModIndependent);
615 616 617 618 619 620 621 622 623 624 625 626
    }

    // set priority module: quadric, normal deviation or edge length
    if ( _constraints.contains("decimation_order") ){
      bool ok;

      int value = _constraints["decimation_order"].toInt(&ok);

      if (ok) {
        switch (value) {
        case 0:
          decimater->setDecimationOrder(DecimaterInfo::DISTANCE);
627 628
          decimater_object->add( hModQuadric );
          decimater_object->module( hModQuadric ).unset_max_err();
629 630 631
          break;
        case 1:
          decimater->setDecimationOrder(DecimaterInfo::NORMALDEV);
632 633
          decimater_object->add(hModNormalDeviation);
          decimater_object->module(hModNormalDeviation).set_binary(false);
634 635 636
          break;
        case 2:
          decimater->setDecimationOrder(DecimaterInfo::EDGELENGTH);
637 638
          decimater_object->add(hModEdgeLength);
          decimater_object->module(hModEdgeLength).set_binary(false);
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
          break;
        default:
          emit log(LOGERR,tr("Invalid Decimation Order"));
          return;
        }
      }
    } else {
      emit log(LOGERR,tr("No Decimation Order set"));
      return;
    }

    // stock options (triangle and vertices count) constraint
    bool verticesCount = false;
    bool trianglesCount = false;
    int vertices = 0;
    int triangles = 0;

    if ( _constraints.contains("vertices") ){

      bool ok;

      int value = _constraints["vertices"].toInt(&ok);

      if (ok){
        verticesCount = true;
        vertices = value;
      }
    } else if ( _constraints.contains("triangles") ){

      bool ok;

      int value = _constraints["triangles"].toInt(&ok);

      if (ok){
        trianglesCount = true;
        triangles = value;
      }
Jan Möbius's avatar
Jan Möbius committed
676
    }
Jan Möbius's avatar
Jan Möbius committed
677

Jan Möbius's avatar
Jan Möbius committed
678 679
    //distance constraint
    if ( _constraints.contains("distance") ){
Jan Möbius's avatar
 
Jan Möbius committed
680

Jan Möbius's avatar
Jan Möbius committed
681 682 683 684 685
      bool ok;

      double value = _constraints["distance"].toDouble(&ok);

      if (ok) {
686
        if (  decimater_object->add( hModHausdorff ) || (!verticesCount && !trianglesCount)  ) {
Jan Möbius's avatar
Jan Möbius committed
687
            decimater->setDistanceConstraint( value );
688
            decimater_object->module( hModHausdorff ).set_tolerance( decimater->distanceValue() );
Jan Möbius's avatar
Jan Möbius committed
689 690
        }
      }
Jan Möbius's avatar
 
Jan Möbius committed
691 692
    }

Jan Möbius's avatar
Jan Möbius committed
693 694
    //normal deviation constraint
    if ( _constraints.contains("normal_deviation") ){
Jan Möbius's avatar
 
Jan Möbius committed
695

Jan Möbius's avatar
Jan Möbius committed
696
      bool ok;
Jan Möbius's avatar
 
Jan Möbius committed
697

Jan Möbius's avatar
Jan Möbius committed
698
      int value = _constraints["normal_deviation"].toInt(&ok);
Jan Möbius's avatar
 
Jan Möbius committed
699

Jan Möbius's avatar
Jan Möbius committed
700
      if (ok) {
701
        if (  decimater_object->add( hModNormalDeviation ) || (!verticesCount && !trianglesCount)  ) {
Jan Möbius's avatar
Jan Möbius committed
702
            decimater->setNormalDeviationConstraint( value );
703
            decimater_object->module( hModNormalDeviation ).set_normal_deviation( decimater->normalDeviationValue() );
Jan Möbius's avatar
Jan Möbius committed
704 705
        }
      }
706
    } else { // flipping constraint
707
      if (  decimater_object->add( hModNormalFlipping ) || (!verticesCount && !trianglesCount)  ) {
708
        decimater->setNormalFlippingConstraint();
709
        // decimater_object->module( hModNormalFlipping ).set_max_normal_deviation( decimater->normalDeviationValue() ); ?
710
      }
Jan Möbius's avatar
 
Jan Möbius committed
711 712
    }

Jan Möbius's avatar
Jan Möbius committed
713 714 715 716 717 718 719 720
    //roundness constraint
    if ( _constraints.contains("roundness") ){

      bool ok;

      double value = _constraints["roundness"].toDouble(&ok);

      if (ok) {
721
        if (  decimater_object->add( hModRoundness ) || (!verticesCount && !trianglesCount)  ) {
Jan Möbius's avatar
Jan Möbius committed
722
            decimater->setRoundnessConstraint( value );
723
            decimater_object->module( hModRoundness ).set_min_roundness( decimater->roundnessValue(), true );
Jan Möbius's avatar
Jan Möbius committed
724
        }
Jan Möbius's avatar
 
Jan Möbius committed
725 726 727
      }
    }

728 729
    //aspect ratio constraint
    if ( _constraints.contains("aspect_ratio") ){
Jan Möbius's avatar
 
Jan Möbius committed
730

731 732 733 734 735
      bool ok;

      double value = _constraints["aspect_ratio"].toDouble(&ok);

      if (ok) {
736
        if (  decimater_object->add( hModAspectRatio ) || (!verticesCount && !trianglesCount)  ) {
737
            decimater->setAspectRatioConstraint( value );
738
            decimater_object->module( hModAspectRatio ).set_aspect_ratio( decimater->aspectRatioValue() );
739 740 741 742 743 744
        }
      }
    }

    //edge length constraint
    if ( _constraints.contains("edge_length") ){
Jan Möbius's avatar
 
Jan Möbius committed
745

Jan Möbius's avatar
Jan Möbius committed
746
      bool ok;
Jan Möbius's avatar
 
Jan Möbius committed
747

748
      double value = _constraints["edge_length"].toDouble(&ok);
Jan Möbius's avatar
 
Jan Möbius committed
749

750
      if (ok) {
751
        if (  decimater_object->add( hModEdgeLength ) || (!verticesCount && !trianglesCount)  ) {
752
            decimater->setEdgeLengthConstraint( value );
753
            decimater_object->module( hModEdgeLength ).set_edge_length( decimater->edgeLengthValue() );
754 755 756 757 758 759 760 761 762 763
        }
      }
    }

    //independent sets constraint
    if ( _constraints.contains("independent_sets") ){

      bool value = _constraints["independent_sets"].toBool();

      if (value) {
764
        if (  decimater_object->add( hModIndependent ) || (!verticesCount && !trianglesCount)  ) {
765 766
            decimater->setIndependentSetsConstraint();
        }
Jan Möbius's avatar
Jan Möbius committed
767 768 769 770
      }
    }

    //init the decimater
771
    if( ! decimater_object->initialize() ){
Jan Möbius's avatar
Jan Möbius committed
772 773 774 775
      emit log(LOGWARN, tr("Decimater could not be initialized"));
      return;
    }

776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
    float mc_factor = 0.5;
    size_t randomSamples = 8;

    if (_constraints.contains("random_samples"))
    {
      bool ok;
      unsigned value =_constraints["random_samples"].toUInt(&ok);
      if (ok)
        randomSamples = value;
    }

    if (_constraints.contains("incremental_percentage"))
    {
      bool ok;
      unsigned value =_constraints["incremental_percentage"].toUInt(&ok);
      if (ok)
        mc_factor = 1.f - (value*0.01f);
    }

Jan Möbius's avatar
Jan Möbius committed
795
    //decimate
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
    DecimaterType* dec = dynamic_cast<DecimaterType*>(decimater_object.get());
    McDecimaterType* mcDec = dynamic_cast<McDecimaterType*>(decimater_object.get());
    MixedDecimaterType* mixedDec = dynamic_cast<MixedDecimaterType*>(decimater_object.get());

    if(dec && !mixedDec)
    {
      if ( verticesCount )
        dec->decimate_to(vertices);
      else if (trianglesCount )
        dec->decimate_to_faces(0, triangles);
      else // constraints only
        dec->decimate_to_faces(0, 1);
    }
    else if (mcDec && !mixedDec)
    {
      mcDec->set_samples(randomSamples);
      if ( verticesCount )
        mcDec->decimate_to(vertices);
      else if (trianglesCount)
        mcDec->decimate_to_faces(0, triangles);
      else // constraints only
        mcDec->decimate_to_faces(0, 1);
    }
    else if (mixedDec)
    {
      mixedDec->set_samples(randomSamples);
      if ( verticesCount )
        mixedDec->decimate_to(vertices,mc_factor);
      else if (trianglesCount)
        mixedDec->decimate_to_faces(0, triangles,mc_factor);
      else // constraints only
        mixedDec->decimate_to_faces(0, 1,mc_factor);
    }else
    {
      emit log(LOGERR,tr("Could not find Decimater Type"));
    }
Jan Möbius's avatar
Jan Möbius committed
832 833 834 835 836 837 838

    object->mesh()->garbage_collection();
    object->mesh()->update_normals();
    object->update();

    // Create backup
    emit createBackup(_objID, "Decimation");
Isaak Lim's avatar
Isaak Lim committed
839

Jan Möbius's avatar
Jan Möbius committed
840
    // Create QVariantMap parameter string
841 842
    QString param = "("  + (_constraints.contains("decimation_order") ? tr("decimation_order =  %1").arg(_constraints["decimation_order"].toString()) : "") +
                    ", " + (_constraints.contains("distance") ? tr("distance = %1").arg(_constraints["distance"].toString()) : "") +
Jan Möbius's avatar
Jan Möbius committed
843
                    ", " + (_constraints.contains("normal_deviation") ? tr("normal_deviation = %1").arg(_constraints["normal_deviation"].toString()) : "") +
844
                    ", " + (_constraints.contains("edge_length") ? tr("edge_length = %1").arg(_constraints["edge_length"].toString()) : "") +
Jan Möbius's avatar
Jan Möbius committed
845
                    ", " + (_constraints.contains("roundness") ? tr("roundness = %1").arg(_constraints["roundness"].toString()) : "") +
846 847 848
                    ", " + (_constraints.contains("aspect_ratio") ? tr("aspect_ratio = %1").arg(_constraints["aspect_ratio"].toString()) : "") +
                    ", " + (_constraints.contains("independent_sets") ? tr("independent_sets = %1").arg(_constraints["independent_sets"].toString()) : "") +
                    ", " + (_constraints.contains("triangles") ? tr("triangles = %1").arg(_constraints["triangles"].toString()) : "") +
Jan Möbius's avatar
Jan Möbius committed
849
                    ", " + (_constraints.contains("vertices") ? tr("vertices = %1").arg(_constraints["vertices"].toString()) : "") + ")";
Isaak Lim's avatar
Isaak Lim committed
850

Jan Möbius's avatar
Jan Möbius committed
851
    emit scriptInfo( "decimate(" + QString::number(_objID) + ", " + param + ")" );
Isaak Lim's avatar
Isaak Lim committed
852

Jan Möbius's avatar
Jan Möbius committed
853 854 855 856 857
    emit updatedObject( baseObjectData->id() , UPDATE_TOPOLOGY);

  } else {
    emit log(LOGERR,tr("Unsupported object type for decimater"));
    return;
Jan Möbius's avatar
 
Jan Möbius committed
858 859 860 861 862 863 864
  }

  emit updateView();
}

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

Jan Möbius's avatar
Jan Möbius committed
865 866 867
void DecimaterPlugin::slotUpdateNumVertices()
{
  // Only update if tool is visible
868
  if ( !OpenFlipper::Options::gui() || !tool_->isVisible() ) {
Jan Möbius's avatar
Jan Möbius committed
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
    return;
  }

  int max = 0;
  int div = 0;

  bool ok;
  emit functionExists( "infomeshobject" , "vertexCount(int)", ok  ) ;
  if (!ok)
  {
    tool_->currentNumVertices->setText ("<not available>");
    return;
  }

  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType(DATA_TRIANGLE_MESH)) ;
                                        o_it != PluginFunctions::objectsEnd(); ++o_it)  {


    max = std::max( RPC::callFunctionValue<int>   ("infomeshobject" , "vertexCount",o_it->id()) , max );
    div++;
  }

  if (div <= 0)
    tool_->currentNumVertices->setText ("<not available>");
  else {
894 895 896
    tool_->verticesCount->blockSignals(true);
    tool_->verticesCountSlider->blockSignals(true);

Jan Möbius's avatar
Jan Möbius committed
897 898 899
    tool_->currentNumVertices->setText (QString::number(max));
    tool_->verticesCount->setMaximum(max);
    tool_->verticesCountSlider->setMaximum(max);
900

Jan Möbius's avatar
Jan Möbius committed
901
    if ( tool_->verticesCount->value() < 2 )
902
    {
Jan Möbius's avatar
Jan Möbius committed
903
      tool_->verticesCount->setValue( max / 2 );
904 905
      tool_->verticesCountSlider->setValue( max / 2);
    }
906 907 908

    tool_->verticesCount->blockSignals(false);
    tool_->verticesCountSlider->blockSignals(false);
Jan Möbius's avatar
Jan Möbius committed
909 910 911 912 913
  }
}

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

914 915 916 917 918
/** \brief gets and sets the current maximum number of triangles
 *
 */
void DecimaterPlugin::slotUpdateNumTriangles() {
  // only update if the tool is visible
919
  if (!OpenFlipper::Options::gui() || !tool_->isVisible())
920 921
    return;

922
  size_t max = 0;
923 924 925 926 927 928 929 930 931
  int meshN = 0;

  for (PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS, DataType(DATA_TRIANGLE_MESH));
                                       o_it != PluginFunctions::objectsEnd(); ++o_it) {
    TriMesh* mesh = PluginFunctions::triMesh(o_it->id());
    max = std::max(mesh->n_faces(), max);
    meshN++;
  }

932 933 934
  tool_->trianglesCount->blockSignals(true);
  tool_->trianglesCountSlider->blockSignals(true);

935 936 937 938 939 940
  tool_->trianglesCount->setMinimum(1);
  tool_->trianglesCount->setMaximum(max);
  tool_->trianglesCountSlider->setMinimum(1);
  tool_->trianglesCountSlider->setMaximum(max);

  if (tool_->trianglesCount->value() < 2)
941 942 943 944
  {
    tool_->trianglesCount->setValue (max / 2 );
    tool_->trianglesCountSlider->setValue( max / 2);
  }
945 946 947

  tool_->trianglesCount->blockSignals(false);
  tool_->trianglesCountSlider->blockSignals(false);
948 949 950 951
}

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

Jan Möbius's avatar
Jan Möbius committed
952 953 954
void DecimaterPlugin::slotObjectSelectionChanged(int /*_identifier*/)
{
  slotUpdateNumVertices ();
955
  slotUpdateNumTriangles ();
Jan Möbius's avatar
Jan Möbius committed
956
}
957 958 959 960
//-----------------------------------------------------------------------------

void DecimaterPlugin::objectDeleted(int _id)
{
Matthias Möller's avatar
Matthias Möller committed
961
  slotDisableDecimation();
962
}
Jan Möbius's avatar
Jan Möbius committed
963 964 965

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

966
void DecimaterPlugin::slotAboutToRestore(int _id)
Matthias Möller's avatar
Matthias Möller committed
967 968 969 970 971 972 973
{
  slotDisableDecimation();
}

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

void DecimaterPlugin::slotDisableDecimation()
974
{
975 976 977
  if ( ! OpenFlipper::Options::gui())
    return;

978
  decimater_objects_.clear();
Matthias Möller's avatar
Matthias Möller committed
979
  tool_->pbDecimate->setEnabled(false);
980 981 982 983
}

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

984
void DecimaterPlugin::slotObjectUpdated(int /*_identifier*/ , const UpdateType& _type )
Jan Möbius's avatar
Jan Möbius committed
985
{
986
  if ( _type.contains(UPDATE_TOPOLOGY) ) {
Jan Möbius's avatar
Jan Möbius committed
987
    slotUpdateNumVertices ();
988 989
    slotUpdateNumTriangles ();
  }
Jan Möbius's avatar
Jan Möbius committed
990 991 992 993 994
}

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

// activate checkbox if value has changed
995
void DecimaterPlugin::slotUpdateVertices()
Jan Möbius's avatar
Jan Möbius committed
996
{
997 998 999 1000 1001 1002
  tool_->rbVertices->setChecked (true);
}

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

// activate checkbox if value has changed
1003
void DecimaterPlugin::slotUpdateTriangles()
1004 1005
{
  tool_->rbTriangles->setChecked (true);
Jan Möbius's avatar
Jan Möbius committed
1006 1007 1008 1009 1010
}

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

// activate checkbox if value has changed
1011
void DecimaterPlugin::slotUpdateNormalDev()
Jan Möbius's avatar
Jan Möbius committed
1012 1013 1014 1015 1016 1017
{
  tool_->cbNormalDev->setChecked (true);
}

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

1018
// activate checkbox if value has changed
1019
void DecimaterPlugin::slotUpdateEdgeLength()
1020 1021 1022 1023 1024 1025
{
  tool_->cbEdgeLength->setChecked (true);
}

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

Jan Möbius's avatar
Jan Möbius committed
1026
// activate checkbox if value has changed
1027
void DecimaterPlugin::slotUpdateDistance()
Jan Möbius's avatar
Jan Möbius committed
1028 1029 1030 1031
{
  tool_->cbDistance->setChecked (true);
}

Matthias Möller's avatar
Matthias Möller committed
1032 1033 1034
#if QT_VERSION < 0x050000
  Q_EXPORT_PLUGIN2(DecimaterPlugin , DecimaterPlugin );
#endif