DecimaterPlugin.cc 38.6 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


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

Jan Möbius's avatar
Jan Möbius committed
64
#define DECIMATER "DecimaterData"
Jan Möbius's avatar
 
Jan Möbius committed
65

Jan Möbius's avatar
Jan Möbius committed
66
//== IMPLEMENTATION ==========================================================
Jan Möbius's avatar
 
Jan Möbius committed
67

68 69
DecimaterPlugin::DecimaterPlugin() :
        tool_(0),
70 71 72
        decimater_objects_(),
        toolIcon_(0),
        runningJobs_(0)
73 74 75 76
{

}

Jan Möbius's avatar
Jan Möbius committed
77 78
void DecimaterPlugin::initializePlugin()
{
79 80 81 82 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

  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
155

Jan Möbius's avatar
 
Jan Möbius committed
156 157
}

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

Jan Möbius's avatar
Jan Möbius committed
163 164
  emit setSlotDescription("decimate(int,QVariantMap)",tr("Decimate a given object"),
                          QString(tr("objectId,constraints")).split(","),
165 166 167 168 169 170 171 172 173 174 175 176
                          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(";"));
177

178 179 180
  if ( OpenFlipper::Options::gui()) {
    tool_->decTypeOps->setVisible(false);
  }
Jan Möbius's avatar
 
Jan Möbius committed
181 182 183 184 185
}


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

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

196 197 198 199 200 201 202 203 204 205
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
206 207 208

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

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

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

221 222 223 224 225

/** \brief sync between values of aspect ratio slider and spinbox in the toolbox
 *
 * @param _value new aspect ratio value
 */
226
void DecimaterPlugin::slotUpdateAspectRatio(int _value)
227 228 229 230 231 232 233 234 235 236 237 238
{
  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
 */
239
void DecimaterPlugin::slotUpdateAspectRatio(double _value)
240 241 242 243 244
{
  tool_->aspectRatioSlider->setValue( (int) (_value * 100) );
  tool_->cbAspectRatio->setChecked (true);
}
//-----------------------------------------------------------------------------
245 246


247
/** \brief Init called by toolbox
Jan Möbius's avatar
 
Jan Möbius committed
248 249
 *
 */
250
void DecimaterPlugin::slot_initialize()
Jan Möbius's avatar
 
Jan Möbius committed
251
{
252

253 254 255
  if ( ! OpenFlipper::Options::gui())
    return;

256 257
  decimater_objects_.clear();

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

261 262 263 264 265 266 267
	  initialize_object(*o_it);

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

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

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

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

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

Jan Möbius's avatar
Jan Möbius committed
278 279
    if (decimater == 0){
      decimater = new DecimaterInfo();
280
      obj->setObjectData(DECIMATER, decimater);
Jan Möbius's avatar
Jan Möbius committed
281
    }
Isaak Lim's avatar
Isaak Lim committed
282

Jan Möbius's avatar
Jan Möbius committed
283 284 285 286 287 288 289 290 291
    // 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
292

Jan Möbius's avatar
Jan Möbius committed
293
    // Create decimater
294 295 296 297 298 299 300 301
    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
302

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

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

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

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

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

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

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

    if ( tool_->cbIndependentSets->isChecked() ) {
Matthias Möller's avatar
Matthias Möller committed
390
      if ( decimater_object->add( decInit->hModIndependent ) || tool_->rbConstraintsOnly->isChecked() ) {
391
        decimater->setIndependentSetsConstraint();
392 393 394
      }
    }

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

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

    decInit->decimater = decimater_object;
403
    decInit->objId = obj->id();
Matthias Möller's avatar
Matthias Möller committed
404 405

    decimater_objects_.push_back(decInit);
406
}
407 408 409 410 411 412 413 414 415 416 417 418 419 420

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);
}

421 422 423 424 425 426
//-----------------------------------------------------------------------------
/** \brief Decimation called by toolbox
 *
 */
void DecimaterPlugin::slot_decimate()
{
Matthias Möller's avatar
Matthias Möller committed
427

428 429 430
  if ( ! OpenFlipper::Options::gui())
    return;

431
  //decimate
432
  runningJobs_ = decimater_objects_.size();
Matthias Möller's avatar
Matthias Möller committed
433
  for (std::vector< ptr::shared_ptr<DecimaterInit> >::iterator decIter = decimater_objects_.begin();
434 435
      decIter != decimater_objects_.end(); ++decIter)
  {
Matthias Möller's avatar
Matthias Möller committed
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
    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() );
    }

460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
    // 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
481

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

484 485
    th->start();
    th->startProcessing();
Isaak Lim's avatar
Isaak Lim committed
486

Jan Möbius's avatar
Jan Möbius committed
487
  }
Jan Möbius's avatar
 
Jan Möbius committed
488

489 490 491 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

}

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
522 523
}

Jan Möbius's avatar
Jan Möbius committed
524 525 526

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

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

Jan Möbius's avatar
Jan Möbius committed
529 530 531 532 533 534 535 536
  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
537

Jan Möbius's avatar
Jan Möbius committed
538 539 540 541
    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
542

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

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

Jan Möbius's avatar
Jan Möbius committed
547 548 549 550
    if (decimater == 0){
      decimater = new DecimaterInfo();
      object->setObjectData(DECIMATER, decimater);
    }
Isaak Lim's avatar
Isaak Lim committed
551

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

Jan Möbius's avatar
Jan Möbius committed
562
    // Create decimater
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    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
582 583 584

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

    // 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);
623 624
          decimater_object->add( hModQuadric );
          decimater_object->module( hModQuadric ).unset_max_err();
625 626 627
          break;
        case 1:
          decimater->setDecimationOrder(DecimaterInfo::NORMALDEV);
628 629
          decimater_object->add(hModNormalDeviation);
          decimater_object->module(hModNormalDeviation).set_binary(false);
630 631 632
          break;
        case 2:
          decimater->setDecimationOrder(DecimaterInfo::EDGELENGTH);
633 634
          decimater_object->add(hModEdgeLength);
          decimater_object->module(hModEdgeLength).set_binary(false);
635 636 637 638 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
          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
672
    }
Jan Möbius's avatar
Jan Möbius committed
673

Jan Möbius's avatar
Jan Möbius committed
674 675
    //distance constraint
    if ( _constraints.contains("distance") ){
Jan Möbius's avatar
 
Jan Möbius committed
676

Jan Möbius's avatar
Jan Möbius committed
677 678 679 680 681
      bool ok;

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

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

Jan Möbius's avatar
Jan Möbius committed
689 690
    //normal deviation constraint
    if ( _constraints.contains("normal_deviation") ){
Jan Möbius's avatar
 
Jan Möbius committed
691

Jan Möbius's avatar
Jan Möbius committed
692
      bool ok;
Jan Möbius's avatar
 
Jan Möbius committed
693

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

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

Jan Möbius's avatar
Jan Möbius committed
709 710 711 712 713 714 715 716
    //roundness constraint
    if ( _constraints.contains("roundness") ){

      bool ok;

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

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

724 725
    //aspect ratio constraint
    if ( _constraints.contains("aspect_ratio") ){
Jan Möbius's avatar
 
Jan Möbius committed
726

727 728 729 730 731
      bool ok;

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

      if (ok) {
732
        if (  decimater_object->add( hModAspectRatio ) || (!verticesCount && !trianglesCount)  ) {
733
            decimater->setAspectRatioConstraint( value );
734
            decimater_object->module( hModAspectRatio ).set_aspect_ratio( decimater->aspectRatioValue() );
735 736 737 738 739 740
        }
      }
    }

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

Jan Möbius's avatar
Jan Möbius committed
742
      bool ok;
Jan Möbius's avatar
 
Jan Möbius committed
743

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

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

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

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

      if (value) {
760
        if (  decimater_object->add( hModIndependent ) || (!verticesCount && !trianglesCount)  ) {
761 762
            decimater->setIndependentSetsConstraint();
        }
Jan Möbius's avatar
Jan Möbius committed
763 764 765 766
      }
    }

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

772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
    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
791
    //decimate
792 793 794 795 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
    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
828 829 830

    object->mesh()->garbage_collection();
    object->mesh()->update_normals();
831 832

    emit updatedObject( baseObjectData->id() , UPDATE_TOPOLOGY);
Jan Möbius's avatar
Jan Möbius committed
833 834 835

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

Jan Möbius's avatar
Jan Möbius committed
837
    // Create QVariantMap parameter string
838 839
    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
840
                    ", " + (_constraints.contains("normal_deviation") ? tr("normal_deviation = %1").arg(_constraints["normal_deviation"].toString()) : "") +
841
                    ", " + (_constraints.contains("edge_length") ? tr("edge_length = %1").arg(_constraints["edge_length"].toString()) : "") +
Jan Möbius's avatar
Jan Möbius committed
842
                    ", " + (_constraints.contains("roundness") ? tr("roundness = %1").arg(_constraints["roundness"].toString()) : "") +
843 844 845
                    ", " + (_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
846
                    ", " + (_constraints.contains("vertices") ? tr("vertices = %1").arg(_constraints["vertices"].toString()) : "") + ")";
Isaak Lim's avatar
Isaak Lim committed
847

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

Jan Möbius's avatar
Jan Möbius committed
850 851 852 853

  } else {
    emit log(LOGERR,tr("Unsupported object type for decimater"));
    return;
Jan Möbius's avatar
 
Jan Möbius committed
854 855 856 857 858 859 860
  }

  emit updateView();
}

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

Jan Möbius's avatar
Jan Möbius committed
861 862 863
void DecimaterPlugin::slotUpdateNumVertices()
{
  // Only update if tool is visible
864
  if ( !OpenFlipper::Options::gui() || !tool_->isVisible() ) {
Jan Möbius's avatar
Jan Möbius committed
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
    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 {
890 891 892
    tool_->verticesCount->blockSignals(true);
    tool_->verticesCountSlider->blockSignals(true);

Jan Möbius's avatar
Jan Möbius committed
893 894 895
    tool_->currentNumVertices->setText (QString::number(max));
    tool_->verticesCount->setMaximum(max);
    tool_->verticesCountSlider->setMaximum(max);
896

Jan Möbius's avatar
Jan Möbius committed
897
    if ( tool_->verticesCount->value() < 2 )
898
    {
Jan Möbius's avatar
Jan Möbius committed
899
      tool_->verticesCount->setValue( max / 2 );
900 901
      tool_->verticesCountSlider->setValue( max / 2);
    }
902 903 904

    tool_->verticesCount->blockSignals(false);
    tool_->verticesCountSlider->blockSignals(false);
Jan Möbius's avatar
Jan Möbius committed
905 906 907 908 909
  }
}

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

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

918
  size_t max = 0;
919 920 921 922 923 924 925 926 927
  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++;
  }

928 929 930
  tool_->trianglesCount->blockSignals(true);
  tool_->trianglesCountSlider->blockSignals(true);

931 932 933 934 935 936
  tool_->trianglesCount->setMinimum(1);
  tool_->trianglesCount->setMaximum(max);
  tool_->trianglesCountSlider->setMinimum(1);
  tool_->trianglesCountSlider->setMaximum(max);

  if (tool_->trianglesCount->value() < 2)
937 938 939 940
  {
    tool_->trianglesCount->setValue (max / 2 );
    tool_->trianglesCountSlider->setValue( max / 2);
  }
941 942 943

  tool_->trianglesCount->blockSignals(false);
  tool_->trianglesCountSlider->blockSignals(false);
944 945 946 947
}

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

Jan Möbius's avatar
Jan Möbius committed
948 949 950
void DecimaterPlugin::slotObjectSelectionChanged(int /*_identifier*/)
{
  slotUpdateNumVertices ();
951
  slotUpdateNumTriangles ();
Jan Möbius's avatar
Jan Möbius committed
952
}
953 954 955 956
//-----------------------------------------------------------------------------

void DecimaterPlugin::objectDeleted(int _id)
{
Matthias Möller's avatar
Matthias Möller committed
957
  slotDisableDecimation();
958
}
Jan Möbius's avatar
Jan Möbius committed
959 960 961

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

962
void DecimaterPlugin::slotAboutToRestore(int _id)
Matthias Möller's avatar
Matthias Möller committed
963 964 965 966 967 968 969
{
  slotDisableDecimation();
}

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

void DecimaterPlugin::slotDisableDecimation()
970
{
971 972 973
  if ( ! OpenFlipper::Options::gui())
    return;

974
  decimater_objects_.clear();
Matthias Möller's avatar
Matthias Möller committed
975
  tool_->pbDecimate->setEnabled(false);
976 977 978 979
}

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

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

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

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

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

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

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

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

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

1014
// activate checkbox if value has changed
1015
void DecimaterPlugin::slotUpdateEdgeLength()
1016 1017 1018 1019 1020 1021
{
  tool_->cbEdgeLength->setChecked (true);
}

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

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