Commit 456a26b3 authored by Matthias Möller's avatar Matthias Möller

add mixed and multiple choice decimater

refs #999

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@15342 383ad7c9-94d9-4d36-a494-682f7c89f535
parent c80ac571
......@@ -51,6 +51,7 @@
//== INCLUDES =================================================================
#include <QtGui>
#include <memory>
#include "DecimaterPlugin.hh"
......@@ -58,6 +59,7 @@
#include <ACG/GL/GLState.hh>
#include <QStringList>
#include <ACG/Scenegraph/ManipulatorNode.hh>
#include <ACG/Utils/SmartPointer.hh>
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
......@@ -97,6 +99,8 @@ void DecimaterPlugin::initializePlugin()
// 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)) );
toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"decimater.png");
emit addToolbox( tr("Decimater") , tool_, toolIcon_ );
......@@ -110,6 +114,8 @@ void DecimaterPlugin::pluginsInitialized() {
emit setSlotDescription("decimate(int,QVariantMap)",tr("Decimate a given object"),
QString(tr("objectId,constraints")).split(","),
QString(tr("ID of an object; Object that can has one or more constraint properties (decimation_order,distance,edge_length,normal_deviation,roundness,aspect_ratio,independent_sets,vertices,triangles)")).split(";"));
tool_->decTypeOps->setVisible(false);
}
......@@ -125,6 +131,16 @@ void DecimaterPlugin::updateRoundness(int _value)
tool_->cbRoundness->setChecked (true);
}
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);
}
//-----------------------------------------------------------------------------
......@@ -199,113 +215,155 @@ void DecimaterPlugin::slot_decimate()
ModRoundnessH hModRoundness;
// Create decimater
DecimaterType decimater_object( *mesh );
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));
// Remove old constraints
if(decimater->distance()) {
decimater->removeDistanceConstraint();
decimater_object.remove(hModHausdorff);
decimater_object->remove(hModHausdorff);
}
if(decimater->normalDeviation()) {
decimater->removeNormalDeviationConstraint();
decimater_object.remove(hModNormalDeviation);
decimater_object->remove(hModNormalDeviation);
}
if(decimater->normalFlipping()) {
decimater->removeNormalFlippingConstraint();
decimater_object.remove(hModNormalFlipping);
decimater_object->remove(hModNormalFlipping);
}
if(decimater->roundness()) {
decimater->removeRoundnessConstraint();
decimater_object.remove(hModRoundness);
decimater_object->remove(hModRoundness);
}
if(decimater->aspectRatio()) {
decimater->removeAspectRatioConstraint();
decimater_object.remove(hModAspectRatio);
decimater_object->remove(hModAspectRatio);
}
if(decimater->edgeLength()) {
decimater->removeEdgeLengthConstraint();
decimater_object.remove(hModEdgeLength);
decimater_object->remove(hModEdgeLength);
}
if(decimater->independentSets()) {
decimater->removeIndependentSetsConstraint();
decimater_object.remove(hModIndependent);
decimater_object->remove(hModIndependent);
}
// set priority module: quadric, normal deviation or edge length
if (tool_->rbByDistance->isChecked()) {
decimater->setDecimationOrder(DecimaterInfo::DISTANCE);
decimater_object.add( hModQuadric );
decimater_object.module( hModQuadric ).unset_max_err();
decimater_object->add( hModQuadric );
decimater_object->module( hModQuadric ).unset_max_err();
} else if (tool_->rbByNormalDeviation->isChecked()) {
decimater->setDecimationOrder(DecimaterInfo::NORMALDEV);
decimater_object.add(hModNormalDeviation);
decimater_object.module(hModNormalDeviation).set_binary(false);
std::cout << "add module" << std::endl;
decimater_object->add(hModNormalDeviation);
std::cout << "get module" << std::endl;
decimater_object->module(hModNormalDeviation).set_binary(false);
std::cout << "getted module" << std::endl;
} else if (tool_->rbByEdgeLength->isChecked()) {
decimater->setDecimationOrder(DecimaterInfo::EDGELENGTH);
decimater_object.add(hModEdgeLength);
decimater_object.module(hModEdgeLength).set_binary(false);
decimater_object->add(hModEdgeLength);
decimater_object->module(hModEdgeLength).set_binary(false);
}
// and set new constraints
if ( tool_->cbDistance->isChecked() ) {
if ( decimater_object.add( hModHausdorff ) || tool_->rbConstraintsOnly->isChecked() ) {
if ( decimater_object->add( hModHausdorff ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setDistanceConstraint( tool_->distance->value() );
decimater_object.module( hModHausdorff ).set_tolerance( decimater->distanceValue() );
decimater_object->module( hModHausdorff ).set_tolerance( decimater->distanceValue() );
}
}
if ( tool_->cbNormalDev->isChecked() ) {
if ( decimater_object.add( hModNormalDeviation ) || tool_->rbConstraintsOnly->isChecked() ) {
if ( decimater_object->add( hModNormalDeviation ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setNormalDeviationConstraint( tool_->normalDeviation->value() );
decimater_object.module( hModNormalDeviation ).set_normal_deviation( decimater->normalDeviationValue() );
decimater_object->module( hModNormalDeviation ).set_normal_deviation( decimater->normalDeviationValue() );
}
} else {
if ( decimater_object.add( hModNormalFlipping ) || tool_->rbConstraintsOnly->isChecked() ) {
if ( decimater_object->add( hModNormalFlipping ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setNormalFlippingConstraint();
// decimater_object.module( hModNormalFlipping ).set_max_normal_deviation( decimater->normalDeviationValue() ); ?
}
}
if ( tool_->cbRoundness->isChecked() ) {
if ( decimater_object.add( hModRoundness ) || tool_->rbConstraintsOnly->isChecked() ) {
if ( decimater_object->add( hModRoundness ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setRoundnessConstraint( tool_->roundness->value() );
decimater_object.module( hModRoundness ).set_min_roundness( decimater->roundnessValue(), true );
decimater_object->module( hModRoundness ).set_min_roundness( decimater->roundnessValue(), true );
}
}
if ( tool_->cbAspectRatio->isChecked() ) {
if ( decimater_object.add( hModAspectRatio ) || tool_->rbConstraintsOnly->isChecked() ) {
if ( decimater_object->add( hModAspectRatio ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setAspectRatioConstraint( tool_->aspectRatio->value() );
decimater_object.module( hModAspectRatio ).set_aspect_ratio( decimater->aspectRatioValue() );
decimater_object->module( hModAspectRatio ).set_aspect_ratio( decimater->aspectRatioValue() );
}
}
if ( tool_->cbEdgeLength->isChecked() ) {
if ( decimater_object.add( hModEdgeLength ) || tool_->rbConstraintsOnly->isChecked() ) {
if ( decimater_object->add( hModEdgeLength ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setEdgeLengthConstraint( tool_->edgeLength->value() );
decimater_object.module( hModEdgeLength ).set_edge_length( decimater->edgeLengthValue() );
decimater_object->module( hModEdgeLength ).set_edge_length( decimater->edgeLengthValue() );
}
}
if ( tool_->cbIndependentSets->isChecked() ) {
if ( decimater_object.add( hModIndependent ) || tool_->rbConstraintsOnly->isChecked() ) {
if ( decimater_object->add( hModIndependent ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setIndependentSetsConstraint();
}
}
// Initialize the decimater
if( ! decimater_object.initialize() ){
emit log(LOGWARN, tr("Decimater could not be initialized"));
continue;
}
//decimate
if ( tool_->rbVertices->isChecked() )
decimater_object.decimate_to(tool_->verticesCount->value());
else if (tool_->rbTriangles->isChecked() )
decimater_object.decimate_to_faces(0, tool_->trianglesCount->value());
else // constraints only
decimater_object.decimate_to_faces(0, 1);
if (tool_->rbUseDecimater)
{
// Initialize the decimater
if( ! decimater_object->initialize() ){
emit log(LOGWARN, tr("Decimater could not be initialized"));
continue;
}
//decimate
if(tool_->rbUseDecimater->isChecked())
{
DecimaterType* dec = dynamic_cast<DecimaterType*>(decimater_object.get());
if ( tool_->rbVertices->isChecked() )
dec->decimate_to(tool_->verticesCount->value());
else if (tool_->rbTriangles->isChecked() )
dec->decimate_to_faces(0, tool_->trianglesCount->value());
else // constraints only
dec->decimate_to_faces(0, 1);
}
else if (tool_->rbUseMC)
{
McDecimaterType* dec = dynamic_cast<McDecimaterType*>(decimater_object.get());
dec->set_samples(tool_->randomSamplesCounter->value());
if ( tool_->rbVertices->isChecked() )
dec->decimate_to(tool_->verticesCount->value());
else if (tool_->rbTriangles->isChecked() )
dec->decimate_to_faces(0, tool_->trianglesCount->value());
else // constraints only
dec->decimate_to_faces(0, 1);
}
else if (tool_->rbUseMixed)
{
MixedDecimaterType* dec = dynamic_cast<MixedDecimaterType*>(decimater_object.get());
float mc_factor = 1.0 - (tool_->mixedFactorCounter->value()*0.01);
dec->set_samples(tool_->randomSamplesCounter->value());
if ( tool_->rbVertices->isChecked() )
dec->decimate_to(tool_->verticesCount->value(),mc_factor);
else if (tool_->rbTriangles->isChecked() )
dec->decimate_to_faces(0, tool_->trianglesCount->value(),mc_factor);
else // constraints only
dec->decimate_to_faces(0, 1,mc_factor);
}
}
object->mesh()->garbage_collection();
object->mesh()->update_normals();
......
......@@ -65,6 +65,8 @@
#include "DecimaterToolbarWidget.hh"
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
#include <OpenMesh/Tools/Decimater/McDecimaterT.hh>
#include <OpenMesh/Tools/Decimater/MixedDecimaterT.hh>
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>
#include <OpenMesh/Tools/Decimater/ModNormalFlippingT.hh>
#include <OpenMesh/Tools/Decimater/ModHausdorffT.hh>
......@@ -144,7 +146,10 @@ private :
DecimaterToolbarWidget* tool_;
QIcon* toolIcon_;
typedef OpenMesh::Decimater::DecimaterT< TriMesh > DecimaterType;
typedef OpenMesh::Decimater::BaseDecimaterT< TriMesh > BaseDecimaterType;
typedef OpenMesh::Decimater::DecimaterT< TriMesh > DecimaterType;
typedef OpenMesh::Decimater::McDecimaterT< TriMesh > McDecimaterType;
typedef OpenMesh::Decimater::MixedDecimaterT< TriMesh > MixedDecimaterType;
typedef OpenMesh::Decimater::ModAspectRatioT< TriMesh >::Handle ModAspectRatioH;
typedef OpenMesh::Decimater::ModEdgeLengthT< TriMesh >::Handle ModEdgeLengthH;
......@@ -177,6 +182,9 @@ private slots:
void slotUpdateNumVertices();
void slotUpdateNumTriangles();
void slotMixedCounterValueChanged(double);
void slotMixedSliderValueChanged(int);
//===========================================================================
/** @name Scripting Functions
* @{ */
......
......@@ -7,13 +7,161 @@
<x>0</x>
<y>0</y>
<width>378</width>
<height>580</height>
<height>738</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Decimater</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QRadioButton" name="rbUseDecimater">
<property name="toolTip">
<string>More accurate but slower</string>
</property>
<property name="text">
<string>Incremental</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbUseMC">
<property name="toolTip">
<string>Less accurate but faster</string>
</property>
<property name="text">
<string>Multiple Choice</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbUseMixed">
<property name="toolTip">
<string>Uses Multiple Choise Decimater and Incremental Decimater to get good and fast results.</string>
</property>
<property name="text">
<string>Mixed</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="decTypeOps" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="mcSamplesLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Random Samples</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QSpinBox" name="randomSamplesCounter">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="3">
<widget class="QLabel" name="mixedFactorLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>80%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QDoubleSpinBox" name="mixedFactorCounter">
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>20.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="mixedMCSliderLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Multiple Choice</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="mixedSliderLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Incremental</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="5">
<widget class="QSlider" name="mixedFactorSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>80</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
......@@ -435,34 +583,50 @@ p, li { white-space: pre-wrap; }
<resources/>
<connections>
<connection>
<sender>normalDeviationSlider</sender>
<sender>verticesCount</sender>
<signal>valueChanged(int)</signal>
<receiver>normalDeviation</receiver>
<receiver>verticesCountSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>235</x>
<y>211</y>
<x>359</x>
<y>639</y>
</hint>
<hint type="destinationlabel">
<x>344</x>
<y>212</y>
<x>276</x>
<y>637</y>
</hint>
</hints>
</connection>
<connection>
<sender>normalDeviation</sender>
<sender>verticesCountSlider</sender>
<signal>sliderMoved(int)</signal>
<receiver>verticesCount</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>276</x>
<y>637</y>
</hint>
<hint type="destinationlabel">
<x>359</x>
<y>639</y>
</hint>
</hints>
</connection>
<connection>
<sender>trianglesCount</sender>
<signal>valueChanged(int)</signal>
<receiver>normalDeviationSlider</receiver>
<receiver>trianglesCountSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>344</x>
<y>212</y>
<x>359</x>
<y>609</y>
</hint>
<hint type="destinationlabel">
<x>235</x>
<y>211</y>
<x>276</x>
<y>607</y>
</hint>
</hints>
</connection>
......@@ -473,60 +637,124 @@ p, li { white-space: pre-wrap; }
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>201</x>
<y>365</y>
<x>276</x>
<y>607</y>
</hint>
<hint type="destinationlabel">
<x>295</x>
<y>367</y>
<x>359</x>
<y>609</y>
</hint>
</hints>
</connection>
<connection>
<sender>trianglesCount</sender>
<sender>normalDeviation</sender>
<signal>valueChanged(int)</signal>
<receiver>trianglesCountSlider</receiver>
<receiver>normalDeviationSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>291</x>
<y>362</y>
<x>365</x>
<y>407</y>
</hint>
<hint type="destinationlabel">
<x>230</x>
<y>365</y>
<x>227</x>
<y>407</y>
</hint>
</hints>
</connection>
<connection>
<sender>verticesCountSlider</sender>
<signal>sliderMoved(int)</signal>
<receiver>verticesCount</receiver>
<sender>normalDeviationSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>normalDeviation</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>234</x>
<y>390</y>
<x>227</x>
<y>407</y>
</hint>
<hint type="destinationlabel">
<x>312</x>
<y>399</y>
<x>365</x>
<y>407</y>
</hint>
</hints>
</connection>
<connection>
<sender>verticesCount</sender>
<signal>valueChanged(int)</signal>
<receiver>verticesCountSlider</receiver>
<slot>setValue(int)</slot>
<sender>rbUseMC</sender>
<signal>clicked(bool)</signal>
<receiver>decTypeOps</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>82</x>
<y>69</y>
</hint>
<hint type="destinationlabel">
<x>200</x>
<y>117</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbUseMixed</sender>
<signal>clicked(bool)</signal>
<receiver>decTypeOps</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>103</x>
<y>91</y>
</hint>
<hint type="destinationlabel">
<x>206</x>
<y>121</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbUseMixed</sender>
<signal>clicked(bool)</signal>
<receiver>widget</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>166</x>
<y>99</y>
</hint>
<hint type="destinationlabel">
<x>168</x>
<y>148</y>
</hint>
</hints>
</connection>
<connection>
<sender>rbUseMC</sender>
<signal>clicked(bool)</signal>
<receiver>widget</receiver>
<slot>setHidden(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>128</x>