mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +00:00
Interface mockup 17
This commit is contained in:
@@ -1547,6 +1547,20 @@ void ViewportWindow::showAllElements() {
|
||||
visibility_.showAll();
|
||||
}
|
||||
|
||||
void ViewportWindow::invertElementVisibility() {
|
||||
std::unordered_set<uint32_t> inverted;
|
||||
for (const auto& [mid, m] : models_gpu_) {
|
||||
if (m.hidden) continue;
|
||||
for (const InstanceCpu& inst : m.instances) {
|
||||
if (inst.object_id == 0) continue;
|
||||
if (!visibility_.isHidden(inst.object_id)) {
|
||||
inverted.insert(inst.object_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
visibility_.setHidden(inverted);
|
||||
}
|
||||
|
||||
void ViewportWindow::setCamera(float tx, float ty, float tz,
|
||||
float dist, float yaw, float pitch) {
|
||||
camera_target_ = QVector3D(tx, ty, tz);
|
||||
@@ -1641,16 +1655,34 @@ void ViewportWindow::frameAabb(const QVector3D& mn, const QVector3D& mx,
|
||||
|
||||
void ViewportWindow::focusOnSelectedObject() {
|
||||
if (camera_mode_ == CameraMode::Fps) return;
|
||||
// F frames the *active* object so it's predictable across multi-select
|
||||
// states. Framing the union of every selected member would be more
|
||||
// expansive but ambiguous in a large set.
|
||||
const uint32_t target = selection_.activeObjectId();
|
||||
QVector3D mn, mx;
|
||||
if (!computeObjectAabb(target, mn, mx)) {
|
||||
const auto& sel = selection_.selectionIds();
|
||||
if (sel.empty()) {
|
||||
qDebug("Focus: no object selected or no AABB available");
|
||||
return;
|
||||
}
|
||||
frameAabb(mn, mx, 1.30f); // a bit of headroom around small objects
|
||||
|
||||
bool found = false;
|
||||
QVector3D lo(std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max());
|
||||
QVector3D hi(-std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max());
|
||||
for (uint32_t object_id : sel) {
|
||||
QVector3D mn, mx;
|
||||
if (!computeObjectAabb(object_id, mn, mx)) continue;
|
||||
for (int a = 0; a < 3; ++a) {
|
||||
if (mn[a] < lo[a]) lo[a] = mn[a];
|
||||
if (mx[a] > hi[a]) hi[a] = mx[a];
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
qDebug("Focus: no object selected or no AABB available");
|
||||
return;
|
||||
}
|
||||
frameAabb(lo, hi, 1.30f);
|
||||
}
|
||||
|
||||
void ViewportWindow::viewAll() {
|
||||
@@ -1758,23 +1790,6 @@ void ViewportWindow::keyPressEvent(QKeyEvent* event) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
// K toggles the section tool.
|
||||
if (key == Qt::Key_K
|
||||
&& event->modifiers() == Qt::NoModifier
|
||||
&& !event->isAutoRepeat()) {
|
||||
toggleSectionTool();
|
||||
return;
|
||||
}
|
||||
// Shift+K clears every section plane (and the selection).
|
||||
if (key == Qt::Key_K
|
||||
&& event->modifiers() == Qt::ShiftModifier
|
||||
&& !event->isAutoRepeat()) {
|
||||
clearSectionPlanes();
|
||||
section_plane_selected_ = -1;
|
||||
section_drag_active_ = false;
|
||||
section_drag_index_ = -1;
|
||||
return;
|
||||
}
|
||||
// While the section tool is active: Esc exits the tool, Delete removes
|
||||
// the selected plane.
|
||||
if (section_tool_active_) {
|
||||
|
||||
@@ -351,6 +351,9 @@ public:
|
||||
// Model-level `hidden` flags are not touched — a hidden model stays
|
||||
// hidden, matching the user's expectation of "show all *elements*".
|
||||
void showAllElements();
|
||||
// Flip element-level visibility across every live element in visible
|
||||
// models. Model-hidden objects are skipped and remain model-hidden.
|
||||
void invertElementVisibility();
|
||||
|
||||
// Extended pick: returns the object id, world-space hit point, and
|
||||
// world-space surface normal at (x, y). Renders the same pick pass as
|
||||
@@ -399,10 +402,9 @@ public:
|
||||
void setBenchmarkFrames(int n);
|
||||
QString cameraString() const;
|
||||
|
||||
// Move camera_target_ to the selected object's world-AABB centroid and
|
||||
// dolly camera_distance_ so the object's bounding sphere fits the
|
||||
// current viewport. Yaw/pitch are preserved. No-op if no object is
|
||||
// selected or its AABB is unknown.
|
||||
// Move camera_target_ to the selected set's world-AABB centroid and
|
||||
// dolly camera_distance_ so the union fits the current viewport.
|
||||
// Yaw/pitch are preserved. No-op if no selected object has an AABB.
|
||||
void focusOnSelectedObject();
|
||||
// Frame the union of all finalized models. No-op if the scene is empty.
|
||||
void viewAll();
|
||||
|
||||
@@ -110,6 +110,12 @@ void MainWindow::setupChrome() {
|
||||
bind_shortcut(QKeySequence(Qt::SHIFT | Qt::Key_F), [this]() {
|
||||
viewport_controller_->setFlyMode();
|
||||
});
|
||||
bind_shortcut(QKeySequence(Qt::Key_K), [this]() {
|
||||
viewport_controller_->toggleSectionMode();
|
||||
});
|
||||
bind_shortcut(QKeySequence(Qt::SHIFT | Qt::Key_K), [this]() {
|
||||
viewport_controller_->clearSectionPlanes();
|
||||
});
|
||||
bind_shortcut(QKeySequence(Qt::Key_H), [this]() {
|
||||
viewport_controller_->hideSelectedElements();
|
||||
});
|
||||
@@ -212,7 +218,7 @@ QWidget* MainWindow::buildNavigateRibbonPage() {
|
||||
});
|
||||
auto* view_selected = components::buttons::makeButton("View Selected", ":/icons/cube-scan-solid.svg", this);
|
||||
connect(view_selected, &QToolButton::clicked, this, [this]() {
|
||||
if (viewport_widget_) viewport_widget_->viewport()->focusOnSelectedObject();
|
||||
viewport_controller_->focusSelectedObject();
|
||||
});
|
||||
|
||||
auto* plan_view = components::buttons::makeButton("Plan", ":/icons/planimetry.svg", this);
|
||||
@@ -243,10 +249,14 @@ QWidget* MainWindow::buildNavigateRibbonPage() {
|
||||
connect(fly_mode, &QToolButton::clicked, this, [this]() {
|
||||
viewport_controller_->setFlyMode();
|
||||
});
|
||||
auto* section_mode = components::buttons::makeButton("Section", ":/icons/cube-cut-with-curve.svg", this);
|
||||
connect(section_mode, &QToolButton::clicked, this, [this]() {
|
||||
viewport_controller_->toggleSectionMode();
|
||||
});
|
||||
|
||||
row->addWidget(components::buttons::makeButtonGroup("CAMERA", {set_home, go_home, view_all, view_selected}, this));
|
||||
row->addWidget(components::buttons::makeButtonGroup("ORIENTATION", {plan_view, front_view, side_view, align_object, projection_button}, this));
|
||||
row->addWidget(components::buttons::makeButtonGroup("MODE", {fly_mode}, this));
|
||||
row->addWidget(components::buttons::makeButtonGroup("MODE", {fly_mode, section_mode}, this));
|
||||
row->addStretch(1);
|
||||
return page;
|
||||
}
|
||||
@@ -272,7 +282,7 @@ QWidget* MainWindow::buildInspectRibbonPage() {
|
||||
});
|
||||
auto* invert_selection = components::buttons::makeButton("Invert", ":/icons/intersect.svg", this);
|
||||
connect(invert_selection, &QToolButton::clicked, this, [this]() {
|
||||
session_state_->setStatusMessage("Selection", "Invert selection coming soon");
|
||||
viewport_controller_->invertSelection();
|
||||
});
|
||||
|
||||
auto* distance = components::buttons::makeButton("Distance", ":/icons/select-edge3d.svg", this);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.52844 7.29346L9 10.3332" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M22 2L20 2M12 12L12 10C12 6.45478 14.3061 3.44817 17.5 2.39838" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M22 12L20 12M12 22L12 20C12 16.4548 14.3061 13.4482 17.5 12.3984" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 22L3.30861 17.1715C3.11813 17.0656 3 16.8649 3 16.647L2.99998 7.35304C2.99998 7.13514 3.11812 6.93437 3.3086 6.82855L11.7086 2.16188C11.8898 2.06121 12.1102 2.06121 12.2914 2.16188L15 3.66667" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 11.9999L3.52842 7.29346" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 21L12 12" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M15 13.5L15 4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1,6 +0,0 @@
|
||||
<svg width="24" height="24" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.0028 3V7.49704C22.0028 7.77482 21.7776 8 21.4998 8V8C21.2999 8 21.12 7.88104 21.034 7.70059C19.4262 4.32948 15.9866 2 12.0028 2C6.81746 2 2.55391 5.94668 2.05219 11" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 16.4V9.39365C6 9.06228 6.26863 8.79365 6.6 8.79365H7.77283C7.97677 8.79365 8.16674 8.69006 8.2772 8.51863L9.7228 6.27502C9.83326 6.10359 10.0232 6 10.2272 6H13.7728C13.9768 6 14.1667 6.10359 14.2772 6.27502L15.7228 8.51863C15.8333 8.69006 16.0232 8.79365 16.2272 8.79365H17.4C17.7314 8.79365 18 9.06228 18 9.39365V16.4C18 16.7314 17.7314 17 17.4 17H6.6C6.26863 17 6 16.7314 6 16.4Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.05078 21V16.503C2.05078 16.2252 2.27596 16 2.55374 16V16C2.75366 16 2.93357 16.119 3.01963 16.2994C4.62737 19.6705 8.06703 22 12.0508 22C17.2361 22 21.4997 18.0533 22.0014 13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -22,8 +22,8 @@
|
||||
<file alias="building.svg">icons/building.svg</file>
|
||||
<file alias="cellar.svg">icons/cellar.svg</file>
|
||||
<file alias="perspective-view.svg">icons/perspective-view.svg</file>
|
||||
<file alias="rotate-camera-right.svg">icons/rotate-camera-right.svg</file>
|
||||
<file alias="drone.svg">icons/drone.svg</file>
|
||||
<file alias="cube-cut-with-curve.svg">icons/cube-cut-with-curve.svg</file>
|
||||
<file alias="folder-plus.svg">icons/folder-plus.svg</file>
|
||||
<file alias="folder-minus.svg">icons/folder-minus.svg</file>
|
||||
<file alias="folder.svg">icons/folder.svg</file>
|
||||
|
||||
@@ -235,6 +235,20 @@ void ViewportController::setFlyMode() {
|
||||
session_state_->setStatusMessage("Mode", "Fly mode active");
|
||||
}
|
||||
|
||||
void ViewportController::toggleSectionMode() {
|
||||
viewport_->toggleSectionTool();
|
||||
if (viewport_->sectionToolActive()) {
|
||||
session_state_->setStatusMessage("Section", "Section tool active");
|
||||
} else {
|
||||
session_state_->setStatusMessage("Section", "Section tool off");
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportController::clearSectionPlanes() {
|
||||
viewport_->clearSectionPlanes();
|
||||
session_state_->setStatusMessage("Section", "Section planes cleared");
|
||||
}
|
||||
|
||||
void ViewportController::toggleDistanceMode() {
|
||||
viewport_->toggleLengthTool();
|
||||
}
|
||||
@@ -247,6 +261,10 @@ void ViewportController::toggleVolumeMode() {
|
||||
viewport_->toggleVolumeTool();
|
||||
}
|
||||
|
||||
void ViewportController::focusSelectedObject() {
|
||||
viewport_->focusOnSelectedObject();
|
||||
}
|
||||
|
||||
void ViewportController::hideSelectedElements() {
|
||||
viewport_->hideSelectedElements();
|
||||
}
|
||||
@@ -259,6 +277,10 @@ void ViewportController::showAllElements() {
|
||||
viewport_->showAllElements();
|
||||
}
|
||||
|
||||
void ViewportController::invertSelection() {
|
||||
viewport_->invertElementVisibility();
|
||||
}
|
||||
|
||||
void ViewportController::updateVolumeReadout() {
|
||||
if (viewport_->toolMode() != ViewportWindow::ToolMode::Volume) return;
|
||||
|
||||
|
||||
@@ -44,12 +44,16 @@ public:
|
||||
void setHomeView();
|
||||
void goHomeView();
|
||||
void setFlyMode();
|
||||
void toggleSectionMode();
|
||||
void clearSectionPlanes();
|
||||
void toggleDistanceMode();
|
||||
void toggleAreaMode();
|
||||
void toggleVolumeMode();
|
||||
void focusSelectedObject();
|
||||
void hideSelectedElements();
|
||||
void isolateSelectedElements();
|
||||
void showAllElements();
|
||||
void invertSelection();
|
||||
|
||||
private:
|
||||
void applyCoordinateOperation(uint32_t mid);
|
||||
|
||||
Reference in New Issue
Block a user