Mesh quality settings

This commit is contained in:
Jakub Melka
2019-09-28 18:26:31 +02:00
parent 9941438e99
commit b09f9eff21
17 changed files with 335 additions and 68 deletions

View File

@ -255,6 +255,9 @@ void PDFViewerMainWindow::onViewerSettingsChanged()
{
m_pdfWidget->updateRenderer(m_settings->getRendererEngine(), m_settings->isMultisampleAntialiasingEnabled() ? m_settings->getRendererSamples() : -1);
m_pdfWidget->getDrawWidgetProxy()->setFeatures(m_settings->getFeatures());
m_pdfWidget->getDrawWidgetProxy()->setPreferredMeshResolutionRatio(m_settings->getPreferredMeshResolutionRatio());
m_pdfWidget->getDrawWidgetProxy()->setMinimalMeshResolutionRatio(m_settings->getMinimalMeshResolutionRatio());
m_pdfWidget->getDrawWidgetProxy()->setColorTolerance(m_settings->getColorTolerance());
updateRenderingOptionActions();
}

View File

@ -11,12 +11,17 @@ void PDFViewerSettings::setSettings(const PDFViewerSettings::Settings& settings)
void PDFViewerSettings::readSettings(QSettings& settings)
{
Settings defaultSettings;
settings.beginGroup("ViewerSettings");
m_settings.m_directory = settings.value("defaultDirectory", QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString();
m_settings.m_features = static_cast<pdf::PDFRenderer::Features>(settings.value("rendererFeatures", static_cast<int>(pdf::PDFRenderer::getDefaultFeatures())).toInt());
m_settings.m_rendererEngine = static_cast<pdf::RendererEngine>(settings.value("renderingEngine", static_cast<int>(pdf::RendererEngine::OpenGL)).toInt());
m_settings.m_multisampleAntialiasing = settings.value("msaa", true).toBool();
m_settings.m_rendererSamples = settings.value("rendererSamples", 16).toInt();
m_settings.m_multisampleAntialiasing = settings.value("msaa", defaultSettings.m_multisampleAntialiasing).toBool();
m_settings.m_rendererSamples = settings.value("rendererSamples", defaultSettings.m_rendererSamples).toInt();
m_settings.m_preferredMeshResolutionRatio = settings.value("preferredMeshResolutionRatio", defaultSettings.m_preferredMeshResolutionRatio).toDouble();
m_settings.m_minimalMeshResolutionRatio = settings.value("minimalMeshResolutionRatio", defaultSettings.m_minimalMeshResolutionRatio).toDouble();
m_settings.m_colorTolerance = settings.value("colorTolerance", defaultSettings.m_colorTolerance).toDouble();
settings.endGroup();
emit settingsChanged();
@ -30,6 +35,9 @@ void PDFViewerSettings::writeSettings(QSettings& settings)
settings.setValue("renderingEngine", static_cast<int>(m_settings.m_rendererEngine));
settings.setValue("msaa", m_settings.m_multisampleAntialiasing);
settings.setValue("rendererSamples", m_settings.m_rendererSamples);
settings.setValue("preferredMeshResolutionRatio", m_settings.m_preferredMeshResolutionRatio);
settings.setValue("minimalMeshResolutionRatio", m_settings.m_minimalMeshResolutionRatio);
settings.setValue("colorTolerance", m_settings.m_colorTolerance);
settings.endGroup();
}
@ -89,4 +97,31 @@ void PDFViewerSettings::setRendererSamples(int rendererSamples)
}
}
void PDFViewerSettings::setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio)
{
if (m_settings.m_preferredMeshResolutionRatio != preferredMeshResolutionRatio)
{
m_settings.m_preferredMeshResolutionRatio = preferredMeshResolutionRatio;
emit settingsChanged();
}
}
void PDFViewerSettings::setMinimalMeshResolutionRatio(pdf::PDFReal minimalMeshResolutionRatio)
{
if (m_settings.m_minimalMeshResolutionRatio != minimalMeshResolutionRatio)
{
m_settings.m_minimalMeshResolutionRatio = minimalMeshResolutionRatio;
emit settingsChanged();
}
}
void PDFViewerSettings::setColorTolerance(pdf::PDFReal colorTolerance)
{
if (m_settings.m_colorTolerance != colorTolerance)
{
m_settings.m_colorTolerance = colorTolerance;
emit settingsChanged();
}
}
} // namespace pdfviewer

View File

@ -25,7 +25,10 @@ public:
m_features(pdf::PDFRenderer::getDefaultFeatures()),
m_rendererEngine(pdf::RendererEngine::OpenGL),
m_multisampleAntialiasing(true),
m_rendererSamples(16)
m_rendererSamples(16),
m_preferredMeshResolutionRatio(0.02),
m_minimalMeshResolutionRatio(0.005),
m_colorTolerance(0.01)
{
}
@ -35,6 +38,9 @@ public:
pdf::RendererEngine m_rendererEngine;
bool m_multisampleAntialiasing;
int m_rendererSamples;
pdf::PDFReal m_preferredMeshResolutionRatio;
pdf::PDFReal m_minimalMeshResolutionRatio;
pdf::PDFReal m_colorTolerance;
};
const Settings& getSettings() const { return m_settings; }
@ -57,6 +63,15 @@ public:
bool isMultisampleAntialiasingEnabled() const { return m_settings.m_multisampleAntialiasing; }
pdf::PDFReal getPreferredMeshResolutionRatio() const { return m_settings.m_preferredMeshResolutionRatio; }
void setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio);
pdf::PDFReal getMinimalMeshResolutionRatio() const { return m_settings.m_minimalMeshResolutionRatio; }
void setMinimalMeshResolutionRatio(pdf::PDFReal minimalMeshResolutionRatio);
pdf::PDFReal getColorTolerance() const { return m_settings.m_colorTolerance; }
void setColorTolerance(pdf::PDFReal colorTolerance);
signals:
void settingsChanged();

View File

@ -4,6 +4,7 @@
#include "pdfglobal.h"
#include "pdfutils.h"
#include <QMessageBox>
#include <QListWidgetItem>
namespace pdfviewer
@ -42,6 +43,10 @@ PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settin
{
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFViewerSettingsDialog::saveData);
}
for (QDoubleSpinBox* spinBox : { ui->preferredMeshResolutionEdit, ui->minimalMeshResolutionEdit, ui->colorToleranceEdit })
{
connect(spinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &PDFViewerSettingsDialog::saveData);
}
ui->optionsPagesWidget->setCurrentRow(0);
adjustSize();
@ -82,6 +87,7 @@ void PDFViewerSettingsDialog::loadData()
pdf::PDFTemporaryValueChange guard(&m_isLoadingData, true);
ui->renderingEngineComboBox->setCurrentIndex(ui->renderingEngineComboBox->findData(static_cast<int>(m_settings.m_rendererEngine)));
// Engine
if (m_settings.m_rendererEngine == pdf::RendererEngine::OpenGL)
{
ui->multisampleAntialiasingCheckBox->setEnabled(true);
@ -106,11 +112,17 @@ void PDFViewerSettingsDialog::loadData()
ui->multisampleAntialiasingSamplesCountComboBox->setCurrentIndex(-1);
}
// Rendering
ui->antialiasingCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::Antialiasing));
ui->textAntialiasingCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::TextAntialiasing));
ui->smoothPicturesCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::SmoothImages));
ui->ignoreOptionalContentCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::IgnoreOptionalContent));
ui->clipToCropBoxCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::ClipToCropBox));
// Shading
ui->preferredMeshResolutionEdit->setValue(m_settings.m_preferredMeshResolutionRatio);
ui->minimalMeshResolutionEdit->setValue(m_settings.m_minimalMeshResolutionRatio);
ui->colorToleranceEdit->setValue(m_settings.m_colorTolerance);
}
void PDFViewerSettingsDialog::saveData()
@ -154,6 +166,18 @@ void PDFViewerSettingsDialog::saveData()
{
m_settings.m_features.setFlag(pdf::PDFRenderer::ClipToCropBox, ui->clipToCropBoxCheckBox->isChecked());
}
else if (sender == ui->preferredMeshResolutionEdit)
{
m_settings.m_preferredMeshResolutionRatio = ui->preferredMeshResolutionEdit->value();
}
else if (sender == ui->minimalMeshResolutionEdit)
{
m_settings.m_minimalMeshResolutionRatio = ui->minimalMeshResolutionEdit->value();
}
else if (sender == ui->colorToleranceEdit)
{
m_settings.m_colorTolerance = ui->colorToleranceEdit->value();
}
loadData();
}

View File

@ -255,6 +255,113 @@
<property name="title">
<string>Shading Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="preferredMeshResolutionLabel">
<property name="text">
<string>Preferred mesh resolution ratio</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="colorToleranceLabel">
<property name="text">
<string>Color tolerance</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="minimalMeshResolutionLabel">
<property name="text">
<string>Minimal mesh resolution ratio</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="preferredMeshResolutionEdit">
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="minimalMeshResolutionEdit">
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="colorToleranceEdit">
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="shadingInfoLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Shading is meshed according the mesh quality criteria. It involves &lt;span style=&quot; font-weight:600;&quot;&gt;color tolerance&lt;/span&gt; and shape tolerance. If color of vertices of triangle in the mesh is too different (it differs more than color tolerance) then mesh is refined and triangle is subdivided. Some shadings are defined by patterns (such as &lt;span style=&quot; font-style:italic;&quot;&gt;Coons patch shading &lt;/span&gt;or &lt;span style=&quot; font-style:italic;&quot;&gt;Tensor product patch shading&lt;/span&gt;), which is also considered in meshing.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Preferred mesh resolution ratio&lt;/span&gt; should be set to optimal balance between performance of mesh generation and quality of the mesh. Optimal triangle size will be computed in the following way: total meshing area (typically a page) will be multiplied with this ratio and that will determine the triangle size. So, if we have A4 page (210 mm x 297mm), and ratio is set to 0,01, then we will get optimal triangle size as 297 * 0.01 = ~3mm.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Minimal mesh resolution ratio&lt;/span&gt; is ratio, which will determine triangle minimal size. At this bound, no triangles are subdivided, even if color is different or shape is not good. This should be set to a value, at which user barely can recognize patterns on the screen (for example, the size of triangle should be &amp;lt; 1mm). But it also affect performance, because too much triangles can be generated.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Color tolerance&lt;/span&gt; is threshold, at which is two colors recognized as different. The comparation is done component-wise, so if at least one of color components is greater than this parameter, then colors are treated as different.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="shadingVerticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>91</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>