Interface mockup 12

This commit is contained in:
Dion Moult
2026-05-07 17:10:04 +10:00
parent ad62dd6d91
commit bae1eddda9
14 changed files with 399 additions and 128 deletions
+11 -12
View File
@@ -23,28 +23,27 @@
#include "Widget.h"
#include "../../ElementRegistry.h"
#include "../../SessionState.h"
#include "../../../ifcviewer/AppSettings.h"
#include "../../../ifcviewer/ViewportWindow.h"
namespace ifcinterface::panels::properties {
PropertiesPanelView::PropertiesPanelView(PropertiesPanelWidget* widget,
ViewportWindow* viewport,
ifcinterface::ElementRegistry* registry,
ifcinterface::SessionState* session_state,
QObject* parent)
: QObject(parent), widget_(widget), registry_(registry)
: QObject(parent), widget_(widget), session_state_(session_state)
{
connect(viewport, &ViewportWindow::objectPicked, this, [this](uint32_t object_id) {
connect(session_state_, &ifcinterface::SessionState::selectionChanged, this, [this](uint32_t object_id) {
refresh(object_id);
});
connect(session_state_, &ifcinterface::SessionState::projectReset, this, [this]() {
refresh(0);
});
refresh(0);
}
void PropertiesPanelView::clearSelection() {
refresh(0);
}
void PropertiesPanelView::refresh(uint32_t object_id) {
auto* registry = session_state_->elementRegistry();
PropertiesPanelState state;
state.entity = {"IfcWall", "SOLIDWALL"};
state.attributes = {
@@ -84,13 +83,13 @@ void PropertiesPanelView::refresh(uint32_t object_id) {
{"Paint Coverage", "42.78 m2"}}},
};
if (!registry_) {
if (!registry) {
widget_->render(state);
return;
}
if (!AppSettings::instance().loadDataSource()) {
auto info = registry_->findBasicElementInfo(object_id);
auto info = registry->findBasicElementInfo(object_id);
if (info && !info->type.isEmpty()) {
state.entity.entity_class = info->type;
if (!state.property_sets.isEmpty() && !state.property_sets[1].rows.isEmpty()) {
@@ -111,7 +110,7 @@ void PropertiesPanelView::refresh(uint32_t object_id) {
return;
}
auto entity = registry_->findEntity(object_id);
auto entity = registry->findEntity(object_id);
if (entity) {
state.entity.entity_class = QString::fromStdString(entity->declaration().name());
if (!state.property_sets.isEmpty() && !state.property_sets[1].rows.isEmpty()) {
+3 -6
View File
@@ -25,8 +25,7 @@
#include <QObject>
namespace ifcinterface { class ElementRegistry; }
class ViewportWindow;
namespace ifcinterface { class SessionState; }
namespace ifcinterface::panels::properties {
class PropertiesPanelWidget;
@@ -35,16 +34,14 @@ class PropertiesPanelView : public QObject {
Q_OBJECT
public:
explicit PropertiesPanelView(PropertiesPanelWidget* widget,
ViewportWindow* viewport,
ifcinterface::ElementRegistry* registry,
ifcinterface::SessionState* session_state,
QObject* parent = nullptr);
void clearSelection();
private:
void refresh(uint32_t object_id);
PropertiesPanelWidget* widget_ = nullptr;
ifcinterface::ElementRegistry* registry_ = nullptr;
ifcinterface::SessionState* session_state_ = nullptr;
};
} // namespace ifcinterface::panels::properties
@@ -22,6 +22,8 @@
#include "Widget.h"
#include "../../SessionState.h"
namespace ifcinterface::panels::spatial_hierarchy {
namespace {
@@ -37,8 +39,10 @@ TreeNode* findNodeRecursive(QList<TreeNode>& nodes, const NodePath& path, int de
} // namespace
SpatialHierarchyPanelView::SpatialHierarchyPanelView(SpatialHierarchyPanelWidget* widget, QObject* parent)
: QObject(parent), widget_(widget)
SpatialHierarchyPanelView::SpatialHierarchyPanelView(SpatialHierarchyPanelWidget* widget,
ifcinterface::SessionState* session_state,
QObject* parent)
: QObject(parent), widget_(widget), session_state_(session_state)
{
nodes_ = {
{"Site A", ItemKind::Site, true,
@@ -52,7 +56,7 @@ SpatialHierarchyPanelView::SpatialHierarchyPanelView(SpatialHierarchyPanelWidget
if (auto* node = findNode(path)) {
node->visible = !node->visible;
reload();
emit statusMessageRequested("Spatial", node->visible ? "Item shown" : "Item hidden");
session_state_->setStatusMessage("Spatial", node->visible ? "Item shown" : "Item hidden");
}
});
@@ -25,6 +25,7 @@
#include <QObject>
namespace ifcinterface { class SessionState; }
namespace ifcinterface::panels::spatial_hierarchy {
class SpatialHierarchyPanelWidget;
@@ -32,16 +33,16 @@ class SpatialHierarchyPanelWidget;
class SpatialHierarchyPanelView : public QObject {
Q_OBJECT
public:
explicit SpatialHierarchyPanelView(SpatialHierarchyPanelWidget* widget, QObject* parent = nullptr);
signals:
void statusMessageRequested(const QString& mode, const QString& detail);
explicit SpatialHierarchyPanelView(SpatialHierarchyPanelWidget* widget,
ifcinterface::SessionState* session_state,
QObject* parent = nullptr);
private:
void reload();
TreeNode* findNode(const NodePath& path);
SpatialHierarchyPanelWidget* widget_ = nullptr;
ifcinterface::SessionState* session_state_ = nullptr;
QList<TreeNode> nodes_;
};
+65 -34
View File
@@ -20,6 +20,7 @@
#include "Controller.h"
#include "../../SessionState.h"
#include "../../../ifcviewer/AppSettings.h"
#include "../../../ifcviewer/Federation.h"
#include "../../../ifcviewer/SceneLoader.h"
@@ -29,61 +30,74 @@
namespace ifcinterface::panels::viewport {
ViewportController::ViewportController(Federation* federation,
SceneLoader* loader,
ViewportController::ViewportController(ifcinterface::SessionState* session_state,
ViewportWindow* viewport,
const QHash<QString, uint32_t>* fed_id_to_model_id,
const QHash<uint32_t, QString>* model_id_to_fed_id,
QObject* parent)
: QObject(parent)
, federation_(federation)
, loader_(loader)
, session_state_(session_state)
, viewport_(viewport)
, fed_id_to_model_id_(fed_id_to_model_id)
, model_id_to_fed_id_(model_id_to_fed_id)
{
connect(federation_, &Federation::federatedFalseOriginChanged,
Federation* federation = session_state_->federation();
SceneLoader* loader = session_state_->loader();
connect(federation, &Federation::federatedFalseOriginChanged,
this, &ViewportController::applyFederatedFalseOrigin);
connect(federation_, &Federation::configChanged, this, [this]() {
connect(federation, &Federation::configChanged, this, [this]() {
applyFederatedFalseOrigin();
for (auto it = model_id_to_fed_id_->cbegin(); it != model_id_to_fed_id_->cend(); ++it) {
applyModelTransformation(it.key());
for (uint32_t mid : session_state_->modelIds()) {
applyModelTransformation(mid);
}
});
connect(federation_, &Federation::modelTransformationChanged,
connect(federation, &Federation::modelTransformationChanged,
this, [this](const QString& fed_id) {
auto it = fed_id_to_model_id_->find(fed_id);
if (it != fed_id_to_model_id_->end()) {
applyModelTransformation(it.value());
const uint32_t mid = session_state_->modelIdForFedId(fed_id);
if (mid != 0) applyModelTransformation(mid);
});
connect(federation, &Federation::modelVisibilityChanged,
this, [this](const QString& fed_id, bool /*visible*/) {
const uint32_t mid = session_state_->modelIdForFedId(fed_id);
if (mid != 0) applyModelVisibility(mid);
});
connect(federation, &Federation::modelGroupChanged,
this, [this](const QString& fed_id, const QString& /*group_id*/) {
const uint32_t mid = session_state_->modelIdForFedId(fed_id);
if (mid != 0) applyModelVisibility(mid);
});
connect(federation, &Federation::groupVisibilityChanged,
this, [this](const QString&, bool /*visible*/) {
for (uint32_t mid : session_state_->modelIds()) {
applyModelVisibility(mid);
}
});
connect(loader_, &SceneLoader::loadedFromSidecar, this,
connect(loader, &SceneLoader::loadedFromSidecar, this,
[this](uint32_t mid, qint64 /*elapsed_ms*/) {
applyCoordinateOperation(mid);
applyModelVisibility(mid);
maybeGuessFederatedFalseOrigin(mid);
});
connect(loader_, &SceneLoader::dataSourceReady, this,
connect(loader, &SceneLoader::dataSourceReady, this,
[this](uint32_t mid) {
applyCoordinateOperation(mid);
});
connect(loader_, &SceneLoader::loadedFromStream, this,
connect(loader, &SceneLoader::loadedFromStream, this,
[this](uint32_t mid, qint64 /*elapsed_ms*/) {
applyCoordinateOperation(mid);
applyModelVisibility(mid);
maybeGuessFederatedFalseOrigin(mid);
});
connect(&AppSettings::instance(),
&AppSettings::applyCoordinateOperationChanged,
this, [this](bool /*enabled*/) {
for (auto it = model_id_to_fed_id_->cbegin(); it != model_id_to_fed_id_->cend(); ++it) {
applyCoordinateOperation(it.key());
for (uint32_t mid : session_state_->modelIds()) {
applyCoordinateOperation(mid);
}
});
}
void ViewportController::applyCoordinateOperation(uint32_t mid) {
SceneLoader* loader = session_state_->loader();
Eigen::Matrix4d matrix = Eigen::Matrix4d::Identity();
if (AppSettings::instance().applyCoordinateOperation()) {
if (const ModelGeoref* georef = loader_->modelGeoref(mid)) {
if (const ModelGeoref* georef = loader->modelGeoref(mid)) {
if (georef->has_coordinate_operation) {
matrix = georef->coordinate_operation_meters;
}
@@ -94,13 +108,15 @@ void ViewportController::applyCoordinateOperation(uint32_t mid) {
}
void ViewportController::applyModelTransformation(uint32_t mid) {
Federation* federation = session_state_->federation();
SceneLoader* loader = session_state_->loader();
Eigen::Matrix4d matrix = Eigen::Matrix4d::Identity();
auto fed_it = model_id_to_fed_id_->find(mid);
if (fed_it != model_id_to_fed_id_->end()) {
if (const Federation::Model* model = federation_->findById(fed_it.value())) {
const QString fed_id = session_state_->fedIdForModelId(mid);
if (!fed_id.isEmpty()) {
if (const Federation::Model* model = federation->findById(fed_id)) {
ModelUnits units;
Eigen::Matrix4d coordinate_operation = Eigen::Matrix4d::Identity();
if (const ModelGeoref* georef = loader_->modelGeoref(mid)) {
if (const ModelGeoref* georef = loader->modelGeoref(mid)) {
units = georef->units;
if (AppSettings::instance().applyCoordinateOperation() &&
georef->has_coordinate_operation) {
@@ -108,30 +124,45 @@ void ViewportController::applyModelTransformation(uint32_t mid) {
}
}
matrix = composeModelTransformation(
model->model_transformation, federation_->config(), units, coordinate_operation);
model->model_transformation, federation->config(), units, coordinate_operation);
}
}
viewport_->setModelTransformation(mid, matrix);
}
void ViewportController::applyModelVisibility(uint32_t mid) {
Federation* federation = session_state_->federation();
const QString fed_id = session_state_->fedIdForModelId(mid);
if (fed_id.isEmpty()) return;
if (federation->isModelEffectivelyVisible(fed_id)) {
viewport_->showModel(mid);
} else {
viewport_->hideModel(mid);
}
}
void ViewportController::applyFederatedFalseOrigin() {
Federation* federation = session_state_->federation();
viewport_->setFederatedFalseOrigin(
composeFederatedFalseOrigin(federation_->federatedFalseOrigin(), federation_->config()));
composeFederatedFalseOrigin(federation->federatedFalseOrigin(), federation->config()));
}
void ViewportController::maybeGuessFederatedFalseOrigin(uint32_t mid) {
if (!federation_->filePath().isEmpty()) return;
Federation* federation = session_state_->federation();
SceneLoader* loader = session_state_->loader();
if (!federation->filePath().isEmpty()) return;
const FederatedFalseOrigin& current = federation_->federatedFalseOrigin();
const FederatedFalseOrigin& current = federation->federatedFalseOrigin();
const FederatedFalseOrigin defaults;
if (current.xyz != defaults.xyz || current.rz_deg != defaults.rz_deg) return;
const Eigen::Matrix4d* placement = loader_->firstPlacement(mid);
const ModelGeoref* georef = loader_->modelGeoref(mid);
const Eigen::Matrix4d* placement = loader->firstPlacement(mid);
const ModelGeoref* georef = loader->modelGeoref(mid);
if (placement == nullptr || georef == nullptr) return;
federation_->setFederatedFalseOrigin(guessFederatedFalseOrigin(
*placement, *georef, federation_->config(),
federation->setFederatedFalseOrigin(guessFederatedFalseOrigin(
*placement, *georef, federation->config(),
AppSettings::instance().applyCoordinateOperation()));
}
+4 -11
View File
@@ -21,11 +21,9 @@
#ifndef IFCINTERFACE_PANELS_VIEWPORT_CONTROLLER_H
#define IFCINTERFACE_PANELS_VIEWPORT_CONTROLLER_H
#include <QHash>
#include <QObject>
class Federation;
class SceneLoader;
namespace ifcinterface { class SessionState; }
class ViewportWindow;
namespace ifcinterface::panels::viewport {
@@ -34,11 +32,8 @@ class ViewportController : public QObject {
Q_OBJECT
public:
explicit ViewportController(Federation* federation,
SceneLoader* loader,
explicit ViewportController(ifcinterface::SessionState* session_state,
ViewportWindow* viewport,
const QHash<QString, uint32_t>* fed_id_to_model_id,
const QHash<uint32_t, QString>* model_id_to_fed_id,
QObject* parent = nullptr);
void applyFederatedFalseOrigin();
@@ -46,13 +41,11 @@ public:
private:
void applyCoordinateOperation(uint32_t mid);
void applyModelTransformation(uint32_t mid);
void applyModelVisibility(uint32_t mid);
void maybeGuessFederatedFalseOrigin(uint32_t mid);
Federation* federation_ = nullptr;
SceneLoader* loader_ = nullptr;
ifcinterface::SessionState* session_state_ = nullptr;
ViewportWindow* viewport_ = nullptr;
const QHash<QString, uint32_t>* fed_id_to_model_id_ = nullptr;
const QHash<uint32_t, QString>* model_id_to_fed_id_ = nullptr;
};
} // namespace ifcinterface::panels::viewport