mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Interface mockup 12
This commit is contained in:
@@ -27,6 +27,8 @@ set(INTERFACE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ElementRegistry.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ElementRegistry.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SessionState.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SessionState.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/components/SvgIcon.cpp
|
||||
@@ -48,6 +50,8 @@ set(INTERFACE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/add_model/Dialog.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/add_model/Dialog.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/Types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/Controller.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/Controller.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/Widget.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/Widget.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/View.cpp
|
||||
|
||||
@@ -43,6 +43,16 @@ void ElementRegistry::clear() {
|
||||
elements_.clear();
|
||||
}
|
||||
|
||||
void ElementRegistry::removeModel(uint32_t model_id) {
|
||||
for (auto it = elements_.begin(); it != elements_.end();) {
|
||||
if (it->second.model_id == model_id) {
|
||||
it = elements_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<BasicElementInfo> ElementRegistry::findBasicElementInfo(uint32_t object_id) const {
|
||||
auto it = elements_.find(object_id);
|
||||
if (it == elements_.end()) return std::nullopt;
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
|
||||
void bindLoader(SceneLoader* loader);
|
||||
void clear();
|
||||
void removeModel(uint32_t model_id);
|
||||
std::optional<BasicElementInfo> findBasicElementInfo(uint32_t object_id) const;
|
||||
std::optional<express::Base> findEntity(uint32_t object_id) const;
|
||||
|
||||
|
||||
@@ -25,11 +25,13 @@
|
||||
#include "../ifcviewer/SceneLoader.h"
|
||||
#include "../ifcviewer/ViewportWindow.h"
|
||||
#include "ElementRegistry.h"
|
||||
#include "SessionState.h"
|
||||
#include "components/Buttons.h"
|
||||
#include "components/Panel.h"
|
||||
#include "components/Style.h"
|
||||
#include "components/Tabs.h"
|
||||
#include "panels/add_model/Dialog.h"
|
||||
#include "panels/models/Controller.h"
|
||||
#include "panels/todo/Widget.h"
|
||||
#include "panels/models/View.h"
|
||||
#include "panels/models/Widget.h"
|
||||
@@ -63,6 +65,9 @@ MainWindow::MainWindow(QWidget* parent)
|
||||
{
|
||||
federation_ = new Federation(this);
|
||||
element_registry_ = new ifcinterface::ElementRegistry(this);
|
||||
session_state_ = new ifcinterface::SessionState(this);
|
||||
session_state_->bindFederation(federation_);
|
||||
session_state_->bindElementRegistry(element_registry_);
|
||||
connect(federation_, &Federation::dirtyChanged, this, [this](bool dirty) {
|
||||
setWindowModified(dirty);
|
||||
updateWindowTitle();
|
||||
@@ -92,11 +97,6 @@ QWidget* MainWindow::makeRibbonGroup(const QString& title, const QList<QToolButt
|
||||
return components::buttons::makeButtonGroup(title, buttons, this);
|
||||
}
|
||||
|
||||
void MainWindow::setStatusMessage(const QString& mode, const QString& detail) {
|
||||
status_mode_label_->setText(mode);
|
||||
status_selection_label_->setText(detail);
|
||||
}
|
||||
|
||||
QToolButton* MainWindow::makePanelToggle(const QString& text, QDockWidget* dock) {
|
||||
auto* button = makeRibbonAction(text, ":/icons/sidebar-expand.svg");
|
||||
button->setCheckable(true);
|
||||
@@ -125,11 +125,11 @@ QWidget* MainWindow::buildHomeRibbonPage() {
|
||||
connect(open_project, &QToolButton::clicked, this, &MainWindow::onOpenProject);
|
||||
auto* open_cloud = makeRibbonAction("Open Cloud", ":/icons/cloud-square.svg");
|
||||
connect(open_cloud, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Project", "Open Cloud Project coming soon");
|
||||
session_state_->setStatusMessage("Project", "Open Cloud Project coming soon");
|
||||
});
|
||||
auto* open_recent = makeRibbonAction("Open Recent", ":/icons/clock-rotate-right.svg");
|
||||
connect(open_recent, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Project", "Open Recent coming soon");
|
||||
session_state_->setStatusMessage("Project", "Open Recent coming soon");
|
||||
});
|
||||
auto* save_project = makeRibbonAction("Save Project", ":/icons/floppy-disk.svg");
|
||||
connect(save_project, &QToolButton::clicked, this, &MainWindow::onSaveProject);
|
||||
@@ -140,7 +140,7 @@ QWidget* MainWindow::buildHomeRibbonPage() {
|
||||
connect(add_model, &QToolButton::clicked, this, &MainWindow::onAddFiles);
|
||||
auto* sync_models = makeRibbonAction("Sync Models", ":/icons/refresh-double.svg");
|
||||
connect(sync_models, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Models", "Sync models coming soon");
|
||||
session_state_->setStatusMessage("Models", "Sync models coming soon");
|
||||
});
|
||||
|
||||
auto* settings_button = makeRibbonAction("Settings", ":/icons/settings.svg");
|
||||
@@ -190,7 +190,7 @@ QWidget* MainWindow::buildNavigateRibbonPage() {
|
||||
});
|
||||
auto* align_object = makeRibbonAction("Align Object", ":/icons/cellar.svg");
|
||||
connect(align_object, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Orientation", "Align to object coming soon");
|
||||
session_state_->setStatusMessage("Orientation", "Align to object coming soon");
|
||||
});
|
||||
auto* projection_button = makeRibbonAction("Perspective", ":/icons/perspective-view.svg");
|
||||
connect(projection_button, &QToolButton::clicked, this, [this, projection_button]() {
|
||||
@@ -202,11 +202,11 @@ QWidget* MainWindow::buildNavigateRibbonPage() {
|
||||
|
||||
auto* orbit_mode = makeRibbonAction("Orbit", ":/icons/rotate-camera-right.svg");
|
||||
connect(orbit_mode, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Mode", "Orbit mode active");
|
||||
session_state_->setStatusMessage("Mode", "Orbit mode active");
|
||||
});
|
||||
auto* fly_mode = makeRibbonAction("Fly", ":/icons/drone.svg");
|
||||
connect(fly_mode, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Mode", "Fly mode coming soon");
|
||||
session_state_->setStatusMessage("Mode", "Fly mode coming soon");
|
||||
});
|
||||
|
||||
row->addWidget(makeRibbonGroup("CAMERA", {set_home, go_home, view_all, view_selected}));
|
||||
@@ -225,32 +225,32 @@ QWidget* MainWindow::buildInspectRibbonPage() {
|
||||
|
||||
auto* hide_selected = makeRibbonAction("Hide", ":/icons/eye-closed.svg");
|
||||
connect(hide_selected, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Selection", "Hide selected coming soon");
|
||||
session_state_->setStatusMessage("Selection", "Hide selected coming soon");
|
||||
});
|
||||
auto* isolate_selected = makeRibbonAction("Isolate", ":/icons/eye-solid.svg");
|
||||
connect(isolate_selected, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Selection", "Isolate selected coming soon");
|
||||
session_state_->setStatusMessage("Selection", "Isolate selected coming soon");
|
||||
});
|
||||
auto* show_all = makeRibbonAction("Show All", ":/icons/eye.svg");
|
||||
connect(show_all, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Selection", "Show all coming soon");
|
||||
session_state_->setStatusMessage("Selection", "Show all coming soon");
|
||||
});
|
||||
auto* invert_selection = makeRibbonAction("Invert", ":/icons/intersect.svg");
|
||||
connect(invert_selection, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Selection", "Invert selection coming soon");
|
||||
session_state_->setStatusMessage("Selection", "Invert selection coming soon");
|
||||
});
|
||||
|
||||
auto* distance = makeRibbonAction("Distance", ":/icons/select-edge3d.svg");
|
||||
connect(distance, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Measure", "Distance coming soon");
|
||||
session_state_->setStatusMessage("Measure", "Distance coming soon");
|
||||
});
|
||||
auto* area = makeRibbonAction("Area", ":/icons/select-face3d.svg");
|
||||
connect(area, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Measure", "Area coming soon");
|
||||
session_state_->setStatusMessage("Measure", "Area coming soon");
|
||||
});
|
||||
auto* volume = makeRibbonAction("Volume", ":/icons/select-point3d.svg");
|
||||
connect(volume, &QToolButton::clicked, this, [this]() {
|
||||
setStatusMessage("Measure", "Volume coming soon");
|
||||
session_state_->setStatusMessage("Measure", "Volume coming soon");
|
||||
});
|
||||
|
||||
row->addWidget(makeRibbonGroup("SELECTION", {hide_selected, isolate_selected, show_all, invert_selection}));
|
||||
@@ -333,15 +333,11 @@ void MainWindow::setupPanels() {
|
||||
spatial_panel_ = new panels::spatial_hierarchy::SpatialHierarchyPanelWidget(this);
|
||||
properties_panel_ = new panels::properties::PropertiesPanelWidget(this);
|
||||
|
||||
models_view_ = new panels::models::ModelsPanelView(models_panel_, this);
|
||||
spatial_view_ = new panels::spatial_hierarchy::SpatialHierarchyPanelView(spatial_panel_, this);
|
||||
properties_view_ = new panels::properties::PropertiesPanelView(
|
||||
properties_panel_, viewport_widget_->viewport(), element_registry_, this);
|
||||
|
||||
connect(models_view_, &panels::models::ModelsPanelView::statusMessageRequested,
|
||||
this, &MainWindow::setStatusMessage);
|
||||
connect(spatial_view_, &panels::spatial_hierarchy::SpatialHierarchyPanelView::statusMessageRequested,
|
||||
this, &MainWindow::setStatusMessage);
|
||||
models_controller_ = new panels::models::ModelsPanelController(
|
||||
models_panel_, session_state_, viewport_widget_->viewport(), element_registry_, this);
|
||||
models_view_ = new panels::models::ModelsPanelView(models_panel_, session_state_, this);
|
||||
spatial_view_ = new panels::spatial_hierarchy::SpatialHierarchyPanelView(spatial_panel_, session_state_, this);
|
||||
properties_view_ = new panels::properties::PropertiesPanelView(properties_panel_, session_state_, this);
|
||||
|
||||
layers_panel_ = new components::Panel("Layers", new panels::todo::TodoPanelWidget("Layers", this), this);
|
||||
stored_views_panel_ = new components::Panel(
|
||||
@@ -403,14 +399,20 @@ void MainWindow::setupStatus() {
|
||||
status_perf_label_->setVisible(show);
|
||||
if (!show) status_perf_label_->clear();
|
||||
});
|
||||
connect(session_state_, &ifcinterface::SessionState::statusMessageChanged,
|
||||
this, [this](const QString& mode, const QString& detail) {
|
||||
status_mode_label_->setText(mode);
|
||||
status_selection_label_->setText(detail);
|
||||
});
|
||||
session_state_->setStatusMessage("Ready", "No selection");
|
||||
}
|
||||
|
||||
void MainWindow::setupLoader() {
|
||||
loader_ = new SceneLoader(viewport_widget_->viewport(), this);
|
||||
element_registry_->bindLoader(loader_);
|
||||
session_state_->bindLoader(loader_);
|
||||
viewport_controller_ = new panels::viewport::ViewportController(
|
||||
federation_, loader_, viewport_widget_->viewport(),
|
||||
&fed_id_to_model_id_, &model_id_to_fed_id_, this);
|
||||
session_state_, viewport_widget_->viewport(), this);
|
||||
connect(loader_, &SceneLoader::loadStarted, this, &MainWindow::onLoadStarted);
|
||||
connect(loader_, &SceneLoader::loadedFromSidecar, this, &MainWindow::onLoadedFromSidecar);
|
||||
connect(loader_, &SceneLoader::loadedFromStream, this, &MainWindow::onLoadedFromStream);
|
||||
@@ -431,7 +433,11 @@ void MainWindow::setupLoader() {
|
||||
.arg(s.total_triangles)
|
||||
.arg(s.gl_draw_calls));
|
||||
});
|
||||
|
||||
connect(viewport_widget_->viewport(), &ViewportWindow::objectPicked,
|
||||
this, [this](uint32_t object_id) {
|
||||
session_state_->setSelectedObjectId(object_id);
|
||||
session_state_->notifySelectionChanged();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::addFiles(const QStringList& paths) {
|
||||
@@ -504,17 +510,18 @@ void MainWindow::onAddFiles() {
|
||||
|
||||
void MainWindow::clearScene() {
|
||||
if (viewport_widget_) viewport_widget_->viewport()->setSelectedObjectId(0);
|
||||
if (properties_view_) properties_view_->clearSelection();
|
||||
session_state_->setSelectedObjectId(0);
|
||||
session_state_->notifySelectionChanged();
|
||||
|
||||
const auto model_ids = model_id_to_fed_id_.keys();
|
||||
const auto model_ids = session_state_->modelIds();
|
||||
for (uint32_t mid : model_ids) {
|
||||
viewport_widget_->viewport()->removeModel(mid);
|
||||
loader_->removeModel(mid);
|
||||
}
|
||||
|
||||
fed_id_to_model_id_.clear();
|
||||
model_id_to_fed_id_.clear();
|
||||
session_state_->clearModelMappings();
|
||||
element_registry_->clear();
|
||||
session_state_->notifyModelsChanged();
|
||||
}
|
||||
|
||||
bool MainWindow::confirmDiscardIfDirty() {
|
||||
@@ -533,9 +540,9 @@ void MainWindow::loadModelsFromPaths(const QStringList& paths, const QStringList
|
||||
if (paths.isEmpty()) return;
|
||||
const auto ids = loader_->addFiles(paths);
|
||||
for (int i = 0; i < paths.size() && i < static_cast<int>(ids.size()) && i < fed_ids.size(); ++i) {
|
||||
fed_id_to_model_id_[fed_ids[i]] = ids[i];
|
||||
model_id_to_fed_id_[ids[i]] = fed_ids[i];
|
||||
session_state_->setModelMapping(fed_ids[i], ids[i]);
|
||||
}
|
||||
session_state_->notifyModelsChanged();
|
||||
}
|
||||
|
||||
bool MainWindow::openProject(const QString& path) {
|
||||
@@ -587,7 +594,8 @@ bool MainWindow::openProject(const QString& path) {
|
||||
hv.target.x(), hv.target.y(), hv.target.z(), hv.distance, hv.yaw, hv.pitch);
|
||||
}
|
||||
updateWindowTitle();
|
||||
setStatusMessage("Project", QFileInfo(path).fileName());
|
||||
session_state_->setStatusMessage("Project", QFileInfo(path).fileName());
|
||||
session_state_->notifyProjectOpened(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -601,7 +609,7 @@ bool MainWindow::saveProject() {
|
||||
return false;
|
||||
}
|
||||
updateWindowTitle();
|
||||
setStatusMessage("Project", QFileInfo(federation_->filePath()).fileName());
|
||||
session_state_->setStatusMessage("Project", QFileInfo(federation_->filePath()).fileName());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -626,7 +634,7 @@ bool MainWindow::saveProjectAs() {
|
||||
return false;
|
||||
}
|
||||
updateWindowTitle();
|
||||
setStatusMessage("Project", QFileInfo(path).fileName());
|
||||
session_state_->setStatusMessage("Project", QFileInfo(path).fileName());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -653,7 +661,8 @@ void MainWindow::onNewProject() {
|
||||
federation_->clear();
|
||||
viewport_controller_->applyFederatedFalseOrigin();
|
||||
updateWindowTitle();
|
||||
setStatusMessage("Project", "Untitled");
|
||||
session_state_->setStatusMessage("Project", "Untitled");
|
||||
session_state_->notifyProjectReset();
|
||||
}
|
||||
|
||||
void MainWindow::onOpenProject() {
|
||||
@@ -684,12 +693,12 @@ void MainWindow::onSetHomeView() {
|
||||
home_view.pitch = camera.pitch;
|
||||
federation_->setHomeView(home_view);
|
||||
updateWindowTitle();
|
||||
setStatusMessage("Camera", "Home view updated");
|
||||
session_state_->setStatusMessage("Camera", "Home view updated");
|
||||
}
|
||||
|
||||
void MainWindow::onGoHomeView() {
|
||||
if (!federation_->hasHomeView()) {
|
||||
setStatusMessage("Camera", "No home view set for this project");
|
||||
session_state_->setStatusMessage("Camera", "No home view set for this project");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -697,44 +706,40 @@ void MainWindow::onGoHomeView() {
|
||||
viewport_widget_->viewport()->setCamera(
|
||||
home_view.target.x(), home_view.target.y(), home_view.target.z(),
|
||||
home_view.distance, home_view.yaw, home_view.pitch);
|
||||
setStatusMessage("Camera", "Home view restored");
|
||||
session_state_->setStatusMessage("Camera", "Home view restored");
|
||||
}
|
||||
|
||||
void MainWindow::onLoadStarted(uint32_t /*mid*/, QString display_name) {
|
||||
status_mode_label_->setText("Loading");
|
||||
status_selection_label_->setText(display_name);
|
||||
session_state_->setStatusMessage("Loading", display_name);
|
||||
}
|
||||
|
||||
void MainWindow::onLoadedFromSidecar(uint32_t mid, qint64 elapsed_ms) {
|
||||
status_mode_label_->setText("Loaded");
|
||||
status_selection_label_->setText(
|
||||
session_state_->setStatusMessage(
|
||||
"Loaded",
|
||||
QString("%1 from cache in %2")
|
||||
.arg(loader_->displayName(mid))
|
||||
.arg(formatElapsed(elapsed_ms)));
|
||||
}
|
||||
|
||||
void MainWindow::onLoadedFromStream(uint32_t mid, qint64 elapsed_ms) {
|
||||
status_mode_label_->setText("Loaded");
|
||||
status_selection_label_->setText(
|
||||
session_state_->setStatusMessage(
|
||||
"Loaded",
|
||||
QString("%1 streamed in %2")
|
||||
.arg(loader_->displayName(mid))
|
||||
.arg(formatElapsed(elapsed_ms)));
|
||||
}
|
||||
|
||||
void MainWindow::onLoadCancelled(uint32_t mid) {
|
||||
status_mode_label_->setText("Cancelled");
|
||||
status_selection_label_->setText(loader_->displayName(mid));
|
||||
session_state_->setStatusMessage("Cancelled", loader_->displayName(mid));
|
||||
}
|
||||
|
||||
void MainWindow::onLoadError(uint32_t /*mid*/, QString message) {
|
||||
status_mode_label_->setText("Error");
|
||||
status_selection_label_->setText(message);
|
||||
session_state_->setStatusMessage("Error", message);
|
||||
QMessageBox::warning(this, "IfcInterfaceMockup", message);
|
||||
}
|
||||
|
||||
void MainWindow::onAllLoadsFinished() {
|
||||
status_mode_label_->setText("Loaded");
|
||||
status_selection_label_->setText(QString("%1 model(s)").arg(loader_->modelCount()));
|
||||
session_state_->setStatusMessage("Loaded", QString("%1 model(s)").arg(loader_->modelCount()));
|
||||
}
|
||||
|
||||
} // namespace ifcinterface::shell
|
||||
|
||||
@@ -32,7 +32,9 @@ class QToolButton;
|
||||
class Federation;
|
||||
class SceneLoader;
|
||||
namespace ifcinterface { class ElementRegistry; }
|
||||
namespace ifcinterface { class SessionState; }
|
||||
namespace ifcinterface::components { class TabBar; }
|
||||
namespace ifcinterface::panels::models { class ModelsPanelController; }
|
||||
namespace ifcinterface::panels::models { class ModelsPanelWidget; }
|
||||
namespace ifcinterface::panels::models { class ModelsPanelView; }
|
||||
namespace ifcinterface::panels::spatial_hierarchy { class SpatialHierarchyPanelWidget; }
|
||||
@@ -70,7 +72,6 @@ private:
|
||||
QToolButton* makeRibbonAction(const QString& text, const QString& icon_path);
|
||||
QWidget* makeRibbonGroup(const QString& title, const QList<QToolButton*>& buttons);
|
||||
QToolButton* makePanelToggle(const QString& text, QDockWidget* dock);
|
||||
void setStatusMessage(const QString& mode, const QString& detail);
|
||||
void addFiles(const QStringList& paths);
|
||||
QString formatElapsed(qint64 ms) const;
|
||||
|
||||
@@ -100,6 +101,7 @@ private:
|
||||
ifcinterface::panels::viewport::ViewportController* viewport_controller_ = nullptr;
|
||||
SceneLoader* loader_ = nullptr;
|
||||
ifcinterface::ElementRegistry* element_registry_ = nullptr;
|
||||
ifcinterface::SessionState* session_state_ = nullptr;
|
||||
ifcinterface::panels::models::ModelsPanelWidget* models_panel_ = nullptr;
|
||||
ifcinterface::panels::spatial_hierarchy::SpatialHierarchyPanelWidget* spatial_panel_ = nullptr;
|
||||
QDockWidget* layers_panel_ = nullptr;
|
||||
@@ -110,11 +112,10 @@ private:
|
||||
QDockWidget* audit_panel_ = nullptr;
|
||||
QDockWidget* clash_panel_ = nullptr;
|
||||
QDockWidget* issues_panel_ = nullptr;
|
||||
ifcinterface::panels::models::ModelsPanelController* models_controller_ = nullptr;
|
||||
ifcinterface::panels::models::ModelsPanelView* models_view_ = nullptr;
|
||||
ifcinterface::panels::spatial_hierarchy::SpatialHierarchyPanelView* spatial_view_ = nullptr;
|
||||
ifcinterface::panels::properties::PropertiesPanelView* properties_view_ = nullptr;
|
||||
QHash<QString, uint32_t> fed_id_to_model_id_;
|
||||
QHash<uint32_t, QString> model_id_to_fed_id_;
|
||||
};
|
||||
|
||||
} // namespace ifcinterface::shell
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// This file was generated with the assistance of an AI coding tool.
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "SessionState.h"
|
||||
|
||||
#include "../ifcviewer/Federation.h"
|
||||
|
||||
namespace ifcinterface {
|
||||
|
||||
SessionState::SessionState(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void SessionState::bindFederation(Federation* federation) {
|
||||
federation_ = federation;
|
||||
}
|
||||
|
||||
void SessionState::bindLoader(SceneLoader* loader) {
|
||||
loader_ = loader;
|
||||
}
|
||||
|
||||
void SessionState::bindElementRegistry(ElementRegistry* element_registry) {
|
||||
element_registry_ = element_registry;
|
||||
}
|
||||
|
||||
void SessionState::setSelectedObjectId(uint32_t object_id) {
|
||||
selected_object_id_ = object_id;
|
||||
}
|
||||
|
||||
void SessionState::setStatusMessage(const QString& mode, const QString& detail) {
|
||||
status_mode_ = mode;
|
||||
status_detail_ = detail;
|
||||
emit statusMessageChanged(status_mode_, status_detail_);
|
||||
}
|
||||
|
||||
void SessionState::setModelMapping(const QString& fed_id, uint32_t model_id) {
|
||||
fed_id_to_model_id_[fed_id] = model_id;
|
||||
model_id_to_fed_id_[model_id] = fed_id;
|
||||
}
|
||||
|
||||
void SessionState::removeModelMappingByFedId(const QString& fed_id) {
|
||||
auto it = fed_id_to_model_id_.find(fed_id);
|
||||
if (it == fed_id_to_model_id_.end()) return;
|
||||
model_id_to_fed_id_.remove(it.value());
|
||||
fed_id_to_model_id_.erase(it);
|
||||
}
|
||||
|
||||
void SessionState::clearModelMappings() {
|
||||
fed_id_to_model_id_.clear();
|
||||
model_id_to_fed_id_.clear();
|
||||
}
|
||||
|
||||
uint32_t SessionState::modelIdForFedId(const QString& fed_id) const {
|
||||
return fed_id_to_model_id_.value(fed_id, 0);
|
||||
}
|
||||
|
||||
QString SessionState::fedIdForModelId(uint32_t model_id) const {
|
||||
return model_id_to_fed_id_.value(model_id);
|
||||
}
|
||||
|
||||
QList<uint32_t> SessionState::modelIds() const {
|
||||
return model_id_to_fed_id_.keys();
|
||||
}
|
||||
|
||||
void SessionState::notifySelectionChanged() {
|
||||
emit selectionChanged(selected_object_id_);
|
||||
}
|
||||
|
||||
void SessionState::notifyModelsChanged() {
|
||||
emit modelsChanged();
|
||||
}
|
||||
|
||||
void SessionState::notifyFederationStructureChanged() {
|
||||
emit federationStructureChanged();
|
||||
}
|
||||
|
||||
void SessionState::notifyVisibilityChanged() {
|
||||
emit visibilityChanged();
|
||||
}
|
||||
|
||||
void SessionState::notifyProjectOpened(const QString& path) {
|
||||
emit projectOpened(path);
|
||||
}
|
||||
|
||||
void SessionState::notifyProjectReset() {
|
||||
emit projectReset();
|
||||
}
|
||||
|
||||
} // namespace ifcinterface
|
||||
@@ -0,0 +1,91 @@
|
||||
// This file was generated with the assistance of an AI coding tool.
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCINTERFACE_SESSIONSTATE_H
|
||||
#define IFCINTERFACE_SESSIONSTATE_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class Federation;
|
||||
class SceneLoader;
|
||||
|
||||
namespace ifcinterface {
|
||||
|
||||
class ElementRegistry;
|
||||
|
||||
class SessionState : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SessionState(QObject* parent = nullptr);
|
||||
|
||||
void bindFederation(Federation* federation);
|
||||
void bindLoader(SceneLoader* loader);
|
||||
void bindElementRegistry(ElementRegistry* element_registry);
|
||||
|
||||
Federation* federation() const { return federation_; }
|
||||
SceneLoader* loader() const { return loader_; }
|
||||
ElementRegistry* elementRegistry() const { return element_registry_; }
|
||||
QString statusMode() const { return status_mode_; }
|
||||
QString statusDetail() const { return status_detail_; }
|
||||
|
||||
void setSelectedObjectId(uint32_t object_id);
|
||||
uint32_t selectedObjectId() const { return selected_object_id_; }
|
||||
void setStatusMessage(const QString& mode, const QString& detail);
|
||||
|
||||
void setModelMapping(const QString& fed_id, uint32_t model_id);
|
||||
void removeModelMappingByFedId(const QString& fed_id);
|
||||
void clearModelMappings();
|
||||
uint32_t modelIdForFedId(const QString& fed_id) const;
|
||||
QString fedIdForModelId(uint32_t model_id) const;
|
||||
QList<uint32_t> modelIds() const;
|
||||
|
||||
void notifySelectionChanged();
|
||||
void notifyModelsChanged();
|
||||
void notifyFederationStructureChanged();
|
||||
void notifyVisibilityChanged();
|
||||
void notifyProjectOpened(const QString& path);
|
||||
void notifyProjectReset();
|
||||
|
||||
signals:
|
||||
void projectOpened(const QString& path);
|
||||
void projectReset();
|
||||
void modelsChanged();
|
||||
void federationStructureChanged();
|
||||
void visibilityChanged();
|
||||
void selectionChanged(uint32_t object_id);
|
||||
void statusMessageChanged(const QString& mode, const QString& detail);
|
||||
|
||||
private:
|
||||
Federation* federation_ = nullptr;
|
||||
SceneLoader* loader_ = nullptr;
|
||||
ElementRegistry* element_registry_ = nullptr;
|
||||
uint32_t selected_object_id_ = 0;
|
||||
QString status_mode_;
|
||||
QString status_detail_;
|
||||
QHash<QString, uint32_t> fed_id_to_model_id_;
|
||||
QHash<uint32_t, QString> model_id_to_fed_id_;
|
||||
};
|
||||
|
||||
} // namespace ifcinterface
|
||||
|
||||
#endif
|
||||
@@ -253,6 +253,33 @@ QString buildAppStyleSheet() {
|
||||
QPushButton:pressed {
|
||||
background: ${ribbon_button_pressed};
|
||||
}
|
||||
QMenu {
|
||||
background: ${panel_background};
|
||||
color: ${primary_text};
|
||||
border: 1px solid ${border};
|
||||
padding: 4px;
|
||||
}
|
||||
QMenu::item {
|
||||
background: transparent;
|
||||
color: ${primary_text};
|
||||
padding: 6px 24px 6px 10px;
|
||||
border-radius: ${panel_radius}px;
|
||||
}
|
||||
QMenu::item:selected {
|
||||
background: ${selection_background};
|
||||
color: ${selection_text};
|
||||
}
|
||||
QMenu::item:disabled {
|
||||
color: ${disabled_text};
|
||||
}
|
||||
QMenu::separator {
|
||||
height: 1px;
|
||||
background: ${border};
|
||||
margin: 4px 8px;
|
||||
}
|
||||
QMenu::icon {
|
||||
padding-left: 2px;
|
||||
}
|
||||
QFrame#entityClassBox,
|
||||
QGroupBox#propertySetBox {
|
||||
background: ${box_background};
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user