Commit 9d466f7f authored by Isaak Lim's avatar Isaak Lim

Added the following Mods to the Decimater Plugin:

Aspect Ratio
Edge Length
Independent Sets

Updated DecimaterInfo and the UI accordingly.


git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@12864 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 614060e0
......@@ -44,10 +44,17 @@
DecimaterInfo::DecimaterInfo() :
normalDeviation_(false),
normalFlipping_(false),
distance_(false),
edgeLength_(false),
aspectRatio_(false),
roundness_(false),
independentSets_(false),
decimationOrder_(DISTANCE),
normalDeviation_value_(0),
distance_value_(0),
edgeLength_value_(0),
aspectRatio_value_(0),
roundness_value_(0) {}
......@@ -79,6 +86,22 @@ void DecimaterInfo::setNormalDeviationConstraint( int _value ){
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::setNormalFlippingConstraint(){
normalFlipping_ = true;
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::setIndependentSetsConstraint(){
independentSets_ = true;
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::setRoundnessConstraint( double _value ){
......@@ -89,6 +112,29 @@ void DecimaterInfo::setRoundnessConstraint( double _value ){
//-----------------------------------------------------------------------------------
void DecimaterInfo::setAspectRatioConstraint( double _value ){
aspectRatio_ = true;
aspectRatio_value_ = _value;
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::setEdgeLengthConstraint( double _value ){
edgeLength_ = true;
edgeLength_value_ = _value;
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::setDecimationOrder( DecimationOrder _order ){
decimationOrder_ = _order;
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::removeDistanceConstraint(){
if ( distance_ ) {
......@@ -98,6 +144,17 @@ void DecimaterInfo::removeDistanceConstraint(){
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::removeEdgeLengthConstraint(){
if ( edgeLength_ ) {
edgeLength_ = false;
edgeLength_value_ = 0;
}
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::removeNormalDeviationConstraint(){
......@@ -109,6 +166,37 @@ void DecimaterInfo::removeNormalDeviationConstraint(){
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::removeNormalFlippingConstraint(){
if ( normalFlipping_ ) {
normalFlipping_ = false;
}
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::removeIndependentSetsConstraint(){
if ( independentSets_ ) {
independentSets_ = false;
}
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::removeAspectRatioConstraint(){
if ( aspectRatio_ ) {
aspectRatio_ = false;
aspectRatio_value_ = 0;
}
}
//-----------------------------------------------------------------------------------
void DecimaterInfo::removeRoundnessConstraint(){
......
......@@ -57,31 +57,56 @@ class DecimaterInfo : public PerObjectData
// Copy function
PerObjectData* copyPerObjectData();
enum DecimationOrder { DISTANCE, NORMALDEV, EDGELENGTH };
void setDistanceConstraint( double _value );
void setNormalDeviationConstraint( int _value );
void setNormalFlippingConstraint();
void setRoundnessConstraint( double _value );
void setAspectRatioConstraint( double _value );
void setEdgeLengthConstraint( double _value );
void setIndependentSetsConstraint();
void setDecimationOrder( DecimationOrder _order );
void removeDistanceConstraint();
void removeNormalDeviationConstraint();
void removeNormalFlippingConstraint();
void removeRoundnessConstraint();
void removeAspectRatioConstraint();
void removeEdgeLengthConstraint();
void removeIndependentSetsConstraint();
// Get/Set methods
bool normalDeviation() { return normalDeviation_; }
bool normalFlipping() { return normalFlipping_; }
bool distance() { return distance_; }
bool roundness() { return roundness_; }
bool aspectRatio() { return aspectRatio_; }
bool edgeLength() { return edgeLength_; }
bool independentSets() { return independentSets_; }
int normalDeviationValue() { return normalDeviation_value_; }
double distanceValue() { return distance_value_; }
double edgeLengthValue() { return edgeLength_value_; }
double aspectRatioValue() { return aspectRatio_value_; }
double roundnessValue() { return roundness_value_; }
private :
bool normalDeviation_;
bool normalFlipping_;
bool distance_;
bool edgeLength_;
bool aspectRatio_;
bool roundness_;
bool independentSets_;
DecimationOrder decimationOrder_;
int normalDeviation_value_;
double distance_value_;
double edgeLength_value_;
double aspectRatio_value_;
double roundness_value_;
};
......@@ -76,14 +76,20 @@ void DecimaterPlugin::initializePlugin()
connect(tool_->roundness,SIGNAL(valueChanged(double) ),this,SLOT(updateRoundness(double)) );
connect(tool_->roundnessSlider,SIGNAL(valueChanged(int) ),this,SLOT(updateRoundness(int)) );
connect(tool_->aspectRatio,SIGNAL(valueChanged(double) ),this,SLOT(updateAspectRatio(double)) );
connect(tool_->aspectRatioSlider,SIGNAL(valueChanged(int) ),this,SLOT(updateAspectRatio(int)) );
connect(tool_->distance,SIGNAL(valueChanged(double) ),this,SLOT(updateDistance()) );
connect(tool_->edgeLength,SIGNAL(valueChanged(double) ),this,SLOT(updateEdgeLength()) );
connect(tool_->normalDeviation,SIGNAL(valueChanged(int) ),this,SLOT(updateNormalDev()) );
connect(tool_->normalDeviationSlider,SIGNAL(valueChanged(int) ),this,SLOT(updateNormalDev()) );
connect(tool_->verticesCount,SIGNAL(valueChanged(int) ),this,SLOT(updateVertices()) );
connect(tool_->verticesCountSlider,SIGNAL(valueChanged(int) ),this,SLOT(updateVertices()) );
connect(tool_->trianglesCount,SIGNAL(valueChanged(int) ),this,SLOT(updateTriangles()) );
connect(tool_->trianglesCountSlider,SIGNAL(valueChanged(int) ),this,SLOT(updateTriangles()) );
// Force update if the Toolbox gets visible
connect(tool_, SIGNAL(showing()), this, SLOT( slotUpdateNumVertices() ) );
connect(tool_, SIGNAL(showing()), this, SLOT( slotUpdateNumTriangles() ) );
toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"decimater.png");
emit addToolbox( tr("Decimater") , tool_, toolIcon_ );
......@@ -127,6 +133,31 @@ void DecimaterPlugin::updateRoundness(double _value)
//-----------------------------------------------------------------------------
/** \brief sync between values of aspect ratio slider and spinbox in the toolbox
*
* @param _value new aspect ratio value
*/
void DecimaterPlugin::updateAspectRatio(int _value)
{
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
*/
void DecimaterPlugin::updateAspectRatio(double _value)
{
tool_->aspectRatioSlider->setValue( (int) (_value * 100) );
tool_->cbAspectRatio->setChecked (true);
}
//-----------------------------------------------------------------------------
/** \brief Decimation called by toolbox
*
*/
......@@ -163,8 +194,6 @@ void DecimaterPlugin::slot_decimate()
// Create decimater
DecimaterType decimater_object( *mesh );
decimater_object.add( hModQuadric );
decimater_object.module( hModQuadric ).unset_max_err();
// Remove old constraints
if(decimater->distance()) {
......@@ -173,35 +202,91 @@ void DecimaterPlugin::slot_decimate()
}
if(decimater->normalDeviation()) {
decimater->removeNormalDeviationConstraint();
decimater_object.remove(hModNormalDeviation);
}
if(decimater->normalFlipping()) {
decimater->removeNormalFlippingConstraint();
decimater_object.remove(hModNormalFlipping);
}
if(decimater->roundness()) {
decimater->removeRoundnessConstraint();
decimater_object.remove(hModRoundness);
}
if(decimater->aspectRatio()) {
decimater->removeAspectRatioConstraint();
decimater_object.remove(hModAspectRatio);
}
if(decimater->edgeLength()) {
decimater->removeEdgeLengthConstraint();
decimater_object.remove(hModEdgeLength);
}
if(decimater->independentSets()) {
decimater->removeIndependentSetsConstraint();
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();
} else if (tool_->rbByNormalDeviation->isChecked()) {
decimater->setDecimationOrder(DecimaterInfo::NORMALDEV);
decimater_object.add(hModNormalDeviation);
decimater_object.module(hModNormalDeviation).set_binary(false);
} else if (tool_->rbByEdgeLength->isChecked()) {
decimater->setDecimationOrder(DecimaterInfo::EDGELENGTH);
decimater_object.add(hModEdgeLength);
decimater_object.module(hModEdgeLength).set_binary(false);
}
//and set new constraints
// and set new constraints
if ( tool_->cbDistance->isChecked() ) {
if ( decimater_object.add( hModHausdorff ) ) {
if ( decimater_object.add( hModHausdorff ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setDistanceConstraint( tool_->distance->value() );
decimater_object.module( hModHausdorff ).set_tolerance( decimater->distanceValue() );
}
}
if ( tool_->cbNormalDev->isChecked() ) {
if ( decimater_object.add( hModNormalFlipping ) ) {
if ( decimater_object.add( hModNormalDeviation ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setNormalDeviationConstraint( tool_->normalDeviation->value() );
decimater_object.module( hModNormalFlipping ).set_max_normal_deviation( decimater->normalDeviationValue() );
decimater_object.module( hModNormalDeviation ).set_normal_deviation( decimater->normalDeviationValue() );
}
} else {
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 ) ) {
if ( decimater_object.add( hModRoundness ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setRoundnessConstraint( tool_->roundness->value() );
decimater_object.module( hModRoundness ).set_min_roundness( decimater->roundnessValue(), true );
}
}
if ( tool_->cbAspectRatio->isChecked() ) {
if ( decimater_object.add( hModAspectRatio ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setAspectRatioConstraint( tool_->aspectRatio->value() );
decimater_object.module( hModAspectRatio ).set_aspect_ratio( decimater->aspectRatioValue() );
}
}
if ( tool_->cbEdgeLength->isChecked() ) {
if ( decimater_object.add( hModEdgeLength ) || tool_->rbConstraintsOnly->isChecked() ) {
decimater->setEdgeLengthConstraint( tool_->edgeLength->value() );
decimater_object.module( hModEdgeLength ).set_edge_length( decimater->edgeLengthValue() );
}
}
if ( tool_->cbIndependentSets->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"));
......@@ -209,10 +294,12 @@ void DecimaterPlugin::slot_decimate()
}
//decimate
if ( tool_->cbVertices->isChecked() )
if ( tool_->rbVertices->isChecked() )
decimater_object.decimate_to(tool_->verticesCount->value());
else
decimater_object.decimate();
else if (tool_->rbTriangles->isChecked() )
decimater_object.decimate_to_faces(0, tool_->trianglesCount->value());
else // constraints only
decimater_object.decimate_to_faces(0, 1);
object->mesh()->garbage_collection();
object->mesh()->update_normals();
......@@ -430,17 +517,49 @@ void DecimaterPlugin::slotUpdateNumVertices()
//-----------------------------------------------------------------------------
/** \brief gets and sets the current maximum number of triangles
*
*/
void DecimaterPlugin::slotUpdateNumTriangles() {
// only update if the tool is visible
if (!tool_->isVisible())
return;
uint max = 0;
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++;
}
tool_->trianglesCount->setMinimum(1);
tool_->trianglesCount->setMaximum(max);
tool_->trianglesCountSlider->setMinimum(1);
tool_->trianglesCountSlider->setMaximum(max);
if (tool_->trianglesCount->value() < 2)
tool_->trianglesCount->setValue(max/2);
}
//-----------------------------------------------------------------------------
void DecimaterPlugin::slotObjectSelectionChanged(int /*_identifier*/)
{
slotUpdateNumVertices ();
slotUpdateNumTriangles ();
}
//-----------------------------------------------------------------------------
void DecimaterPlugin::slotObjectUpdated(int /*_identifier*/ , const UpdateType _type )
{
if ( _type.contains(UPDATE_TOPOLOGY) )
if ( _type.contains(UPDATE_TOPOLOGY) ) {
slotUpdateNumVertices ();
slotUpdateNumTriangles ();
}
}
//-----------------------------------------------------------------------------
......@@ -448,7 +567,15 @@ void DecimaterPlugin::slotObjectUpdated(int /*_identifier*/ , const UpdateType _
// activate checkbox if value has changed
void DecimaterPlugin::updateVertices()
{
tool_->cbVertices->setChecked (true);
tool_->rbVertices->setChecked (true);
}
//-----------------------------------------------------------------------------
// activate checkbox if value has changed
void DecimaterPlugin::updateTriangles()
{
tool_->rbTriangles->setChecked (true);
}
//-----------------------------------------------------------------------------
......@@ -461,6 +588,14 @@ void DecimaterPlugin::updateNormalDev()
//-----------------------------------------------------------------------------
// activate checkbox if value has changed
void DecimaterPlugin::updateEdgeLength()
{
tool_->cbEdgeLength->setChecked (true);
}
//-----------------------------------------------------------------------------
// activate checkbox if value has changed
void DecimaterPlugin::updateDistance()
{
......
......@@ -163,14 +163,19 @@ private slots:
/// roundness slider - spinbox sync
void updateRoundness(int _value);
void updateRoundness(double _value);
void updateAspectRatio(int _value);
void updateAspectRatio(double _value);
/// slider / spinbox updates
void updateDistance ();
void updateNormalDev ();
void updateVertices ();
void updateTriangles ();
void updateEdgeLength ();
/// update number of vertices information
void slotUpdateNumVertices();
void slotUpdateNumTriangles();
//===========================================================================
/** @name Scripting Functions
......
......@@ -7,13 +7,46 @@
<x>0</x>
<y>0</y>
<width>364</width>
<height>290</height>
<height>581</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Decimation Order</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="rbByDistance">
<property name="text">
<string>by Distance</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbByNormalDeviation">
<property name="text">
<string>by Normal Deviation</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbByEdgeLength">
<property name="text">
<string>by Edge length</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
......@@ -109,7 +142,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QCheckBox" name="cbRoundness">
<property name="enabled">
<bool>true</bool>
......@@ -125,7 +158,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QSlider" name="roundnessSlider">
<property name="maximum">
<number>100</number>
......@@ -138,7 +171,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="2" column="2">
<item row="3" column="2">
<widget class="QDoubleSpinBox" name="roundness">
<property name="enabled">
<bool>true</bool>
......@@ -157,45 +190,63 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="cbVertices">
<property name="enabled">
<bool>true</bool>
</property>
<item row="4" column="0">
<widget class="QCheckBox" name="cbAspectRatio">
<property name="text">
<string>#Vertices</string>
<string>AspectRatio</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="verticesCountSlider">
<item row="4" column="2">
<widget class="QDoubleSpinBox" name="aspectRatio">
<property name="minimum">
<number>1</number>
<double>1.200000000000000</double>
</property>
<property name="maximum">
<number>100000</number>
<double>15.000000000000000</double>
</property>
<property name="value">
<number>5000</number>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<property name="value">
<double>3.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="verticesCount">
<property name="enabled">
<bool>true</bool>
</property>
<item row="4" column="1">
<widget class="QSlider" name="aspectRatioSlider">
<property name="minimum">
<number>1</number>
<number>120</number>
</property>
<property name="maximum">
<number>99999</number>
<number>1500</number>
</property>
<property name="value">
<number>5000</number>
<number>300</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="cbEdgeLength">
<property name="text">
<string>Edge Length</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QDoubleSpinBox" name="edgeLength">
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="cbIndependentSets">
<property name="text">
<string>Independent Sets</string>
</property>
</widget>
</item>
......@@ -225,6 +276,100 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Stock conditions</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QRadioButton" name="rbTriangles">
<property name="text">
<string>#Triangles</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="trianglesCountSlider">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>5000</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="trianglesCount">
<property name="minimum">
<number>1</number>