mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
ifcviewer: include settings for deflection tolerances
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QFormLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QShowEvent>
|
||||
@@ -66,6 +67,25 @@ void SettingsWindow::setupUi() {
|
||||
"time; dropping them keeps load times sane.");
|
||||
form->addRow("Void Limit", void_limit_spin_);
|
||||
|
||||
deflection_tolerance_spin_ = new QDoubleSpinBox(this);
|
||||
deflection_tolerance_spin_->setRange(0.000001, 1000.0);
|
||||
deflection_tolerance_spin_->setDecimals(6);
|
||||
deflection_tolerance_spin_->setSingleStep(0.001);
|
||||
deflection_tolerance_spin_->setToolTip(
|
||||
"Linear chord error between curved geometry and its triangulation, "
|
||||
"in model length units. Smaller = smoother curves but more "
|
||||
"triangles and slower load.");
|
||||
form->addRow("Deflection Tolerance", deflection_tolerance_spin_);
|
||||
|
||||
angular_tolerance_spin_ = new QDoubleSpinBox(this);
|
||||
angular_tolerance_spin_->setRange(0.000001, 3.141592);
|
||||
angular_tolerance_spin_->setDecimals(6);
|
||||
angular_tolerance_spin_->setSingleStep(0.05);
|
||||
angular_tolerance_spin_->setToolTip(
|
||||
"Maximum angle (radians) between adjacent facet normals on a "
|
||||
"curved surface. Smaller = smoother shading but more triangles.");
|
||||
form->addRow("Angular Tolerance", angular_tolerance_spin_);
|
||||
|
||||
auto* button_box = new QDialogButtonBox(
|
||||
QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
|
||||
@@ -90,6 +110,8 @@ void SettingsWindow::syncFromSettings() {
|
||||
backface_culling_check_->setChecked(AppSettings::instance().backfaceCulling());
|
||||
load_data_source_check_->setChecked(AppSettings::instance().loadDataSource());
|
||||
void_limit_spin_->setValue(AppSettings::instance().voidLimit());
|
||||
deflection_tolerance_spin_->setValue(AppSettings::instance().deflectionTolerance());
|
||||
angular_tolerance_spin_->setValue(AppSettings::instance().angularTolerance());
|
||||
}
|
||||
|
||||
void SettingsWindow::onAccepted() {
|
||||
@@ -98,5 +120,7 @@ void SettingsWindow::onAccepted() {
|
||||
AppSettings::instance().setBackfaceCulling(backface_culling_check_->isChecked());
|
||||
AppSettings::instance().setLoadDataSource(load_data_source_check_->isChecked());
|
||||
AppSettings::instance().setVoidLimit(void_limit_spin_->value());
|
||||
AppSettings::instance().setDeflectionTolerance(deflection_tolerance_spin_->value());
|
||||
AppSettings::instance().setAngularTolerance(angular_tolerance_spin_->value());
|
||||
accept();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <QDialog>
|
||||
|
||||
class QCheckBox;
|
||||
class QDoubleSpinBox;
|
||||
class QLineEdit;
|
||||
class QShowEvent;
|
||||
class QSpinBox;
|
||||
@@ -47,6 +48,8 @@ private:
|
||||
QCheckBox* backface_culling_check_ = nullptr;
|
||||
QCheckBox* load_data_source_check_ = nullptr;
|
||||
QSpinBox* void_limit_spin_ = nullptr;
|
||||
QDoubleSpinBox* deflection_tolerance_spin_ = nullptr;
|
||||
QDoubleSpinBox* angular_tolerance_spin_ = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,10 @@ constexpr const char* kBackfaceCullingKey = "viewport/backface_culling";
|
||||
constexpr const char* kLoadDataSourceKey = "loading/load_data_source";
|
||||
constexpr const char* kVoidLimitKey = "loading/void_limit";
|
||||
constexpr int kVoidLimitDefault = 30;
|
||||
constexpr const char* kDeflectionToleranceKey = "loading/deflection_tolerance";
|
||||
constexpr double kDeflectionToleranceDefault = 0.001;
|
||||
constexpr const char* kAngularToleranceKey = "loading/angular_tolerance";
|
||||
constexpr double kAngularToleranceDefault = 0.5;
|
||||
}
|
||||
|
||||
AppSettings& AppSettings::instance() {
|
||||
@@ -96,6 +100,30 @@ void AppSettings::setVoidLimit(int value) {
|
||||
emit voidLimitChanged(value);
|
||||
}
|
||||
|
||||
double AppSettings::deflectionTolerance() const {
|
||||
return deflection_tolerance_;
|
||||
}
|
||||
|
||||
void AppSettings::setDeflectionTolerance(double value) {
|
||||
if (value <= 0.0) value = kDeflectionToleranceDefault;
|
||||
if (deflection_tolerance_ == value) return;
|
||||
deflection_tolerance_ = value;
|
||||
persist();
|
||||
emit deflectionToleranceChanged(value);
|
||||
}
|
||||
|
||||
double AppSettings::angularTolerance() const {
|
||||
return angular_tolerance_;
|
||||
}
|
||||
|
||||
void AppSettings::setAngularTolerance(double value) {
|
||||
if (value <= 0.0) value = kAngularToleranceDefault;
|
||||
if (angular_tolerance_ == value) return;
|
||||
angular_tolerance_ = value;
|
||||
persist();
|
||||
emit angularToleranceChanged(value);
|
||||
}
|
||||
|
||||
void AppSettings::load() {
|
||||
QSettings settings;
|
||||
geometry_library_ = settings.value(kGeometryLibraryKey, kGeometryLibraryDefault).toString();
|
||||
@@ -104,6 +132,10 @@ void AppSettings::load() {
|
||||
load_data_source_ = settings.value(kLoadDataSourceKey, true).toBool();
|
||||
void_limit_ = settings.value(kVoidLimitKey, kVoidLimitDefault).toInt();
|
||||
if (void_limit_ < 0) void_limit_ = 0;
|
||||
deflection_tolerance_ = settings.value(kDeflectionToleranceKey, kDeflectionToleranceDefault).toDouble();
|
||||
if (deflection_tolerance_ <= 0.0) deflection_tolerance_ = kDeflectionToleranceDefault;
|
||||
angular_tolerance_ = settings.value(kAngularToleranceKey, kAngularToleranceDefault).toDouble();
|
||||
if (angular_tolerance_ <= 0.0) angular_tolerance_ = kAngularToleranceDefault;
|
||||
}
|
||||
|
||||
void AppSettings::persist() {
|
||||
@@ -113,4 +145,6 @@ void AppSettings::persist() {
|
||||
settings.setValue(kBackfaceCullingKey, backface_culling_);
|
||||
settings.setValue(kLoadDataSourceKey, load_data_source_);
|
||||
settings.setValue(kVoidLimitKey, void_limit_);
|
||||
settings.setValue(kDeflectionToleranceKey, deflection_tolerance_);
|
||||
settings.setValue(kAngularToleranceKey, angular_tolerance_);
|
||||
}
|
||||
|
||||
@@ -53,12 +53,25 @@ public:
|
||||
int voidLimit() const;
|
||||
void setVoidLimit(int value);
|
||||
|
||||
// Mesher tolerances passed straight to the IfcOpenShell iterator.
|
||||
// Linear deflection bounds the chord error between a curve and its
|
||||
// triangulation, in model length units; angular deflection bounds the
|
||||
// angle (radians) between adjacent facet normals on a curved surface.
|
||||
// Smaller values mean smoother geometry at the cost of more triangles
|
||||
// and slower iteration.
|
||||
double deflectionTolerance() const;
|
||||
void setDeflectionTolerance(double value);
|
||||
double angularTolerance() const;
|
||||
void setAngularTolerance(double value);
|
||||
|
||||
signals:
|
||||
void geometryLibraryChanged(const QString& value);
|
||||
void showStatsChanged(bool value);
|
||||
void backfaceCullingChanged(bool value);
|
||||
void loadDataSourceChanged(bool value);
|
||||
void voidLimitChanged(int value);
|
||||
void deflectionToleranceChanged(double value);
|
||||
void angularToleranceChanged(double value);
|
||||
|
||||
private:
|
||||
AppSettings();
|
||||
@@ -70,6 +83,8 @@ private:
|
||||
bool backface_culling_ = true;
|
||||
bool load_data_source_ = true;
|
||||
int void_limit_ = 30;
|
||||
double deflection_tolerance_ = 0.001;
|
||||
double angular_tolerance_ = 0.5;
|
||||
};
|
||||
|
||||
#endif // APPSETTINGS_H
|
||||
|
||||
@@ -284,12 +284,17 @@ void GeometryStreamer::run(const std::string& path, int num_threads) {
|
||||
// applied on the GPU per instance.
|
||||
settings.set("use-world-coords", false);
|
||||
settings.set("weld-vertices", false);
|
||||
settings.set("apply-default-materials", true);
|
||||
settings.set("apply-default-materials", false);
|
||||
// Off by default in IfcOpenShell — makes face winding consistent within
|
||||
// each shell, which we need for GL_CULL_FACE and for per-vertex normals
|
||||
// to shade a solid without dark inside-out patches. Costs some iterator
|
||||
// time, but results are cached in the sidecar so it's a one-shot hit.
|
||||
settings.set("reorient-shells", true);
|
||||
settings.set("layerset-first", true);
|
||||
settings.set("mesher-linear-deflection", AppSettings::instance().deflectionTolerance());
|
||||
settings.set("mesher-angular-deflection", AppSettings::instance().angularTolerance());
|
||||
// Wire intersection checks is prohibitively slow on advanced breps. See bug #5999.
|
||||
settings.set("no-wire-intersection-check", true);
|
||||
|
||||
// @todo parallel mapping on RocksDB-backed files still races somewhere
|
||||
// outside the instance cache, producing inconsistent shape counts. Force
|
||||
|
||||
Reference in New Issue
Block a user