refactor(nmSubWxs): 收敛 PEBI 网格几何预览

- 移除网格预览的属性选择、Material 探测和色标功能
- 固定显示灰色网格表面与黑色单元边线
- 增加正视图并精简右侧工具栏和右键菜单
- 调整底部网格信息及空载、加载和失败状态
- 补充预览数据、场景控制器和窗口中文注释
- 更新中文翻译及后处理开发清单
feature/nmNum-postprocessing-view-20260910
lh 2 hours ago
parent 7e76a16cda
commit 18184b549d

Binary file not shown.

@ -2806,16 +2806,9 @@ Reason: %1</source>
<context>
<name>nmWxPebiGridViewWidget</name>
<message><source>No grid data.</source><translation></translation></message>
<message><source>Property:</source><translation></translation></message>
<message><source>Show Grid Lines</source><translation>线</translation></message>
<message><source>Show Scalar Bar</source><translation></translation></message>
<message><source>Scale Grid</source><translation></translation></message>
<message><source>The grid preview data is invalid.</source><translation></translation></message>
<message><source>No property</source><translation></translation></message>
<message><source>Material</source><translation></translation></message>
<message><source>%1 cells | %2</source><translation>%1 | %2</translation></message>
<message><source>0 cells | Unknown</source><translation>0 | </translation></message>
<message><source>Unknown</source><translation></translation></message>
<message><source>PEBI | %1 valid cells | XY planar grid</source><translation>PEBI | %1 | XY </translation></message>
<message><source>Generating grid...</source><translation>...</translation></message>
</context>
<context>
@ -5036,7 +5029,7 @@ Please check your input coordinates.</source>
<message><source>Zoom Out</source><translation></translation></message>
<message><source>Fit to Window</source><translation></translation></message>
<message><source>Top View</source><translation></translation></message>
<message><source>Front View</source><translation></translation></message>
<message><source>Front View</source><translation></translation></message>
<message><source>Right View</source><translation></translation></message>
<message><source>Isometric View</source><translation></translation></message>
<message><source>Reset Rotation Center</source><translation></translation></message>
@ -5071,7 +5064,7 @@ Please check your input coordinates.</source>
</message>
<message>
<source>Front View</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Right View</source>

@ -12,8 +12,8 @@ class nmWxVTKRenderContainerWidget;
/**
* @brief PEBI nmRender
*
* Scene Mesh ScalarBar
*
* Scene Mesh
*
*/
class NM_SUB_WXS_EXPORT nmPebiGridSceneController
{
@ -29,19 +29,10 @@ public:
/** @brief 解除网格引用并隐藏图层,不销毁 Scene 或 Renderer。 */
void clear();
/** @brief 切换单元边线;网格表面始终保持不透明。 */
void setGridLinesVisible(bool bVisible);
/** @brief 明确选择属性;空字符串表示固定面色,当前只接受有效 Material。 */
bool setProperty(const QString& sPropertyName);
/** @brief 保存色标显示偏好;无活动属性时色标仍保持隐藏。 */
void setScalarBarVisible(bool bVisible);
/** @brief 切换 XY 坐标比例网格。 */
void setBoundsGridVisible(bool bVisible);
bool hasViewData() const;
QString getProperty() const;
bool isGridLinesVisible() const;
bool isScalarBarVisible() const;
bool isBoundsGridVisible() const;
private:

@ -15,11 +15,17 @@ class vtkUnstructuredGrid;
* @brief PEBI
*
* VTK vtkSmartPointer DeepCopy
* nmDataAnalyzeManager QObject
* nmDataAnalyzeManager QObject
* VTK
*
*
* Builder 使
*
*/
class NM_SUB_WXS_EXPORT nmPebiGridViewData
{
public:
/** @brief 创建不持有网格的空预览数据。 */
nmPebiGridViewData();
/** @brief 释放共享网格并清空与该版本对应的预览元数据。 */
@ -27,21 +33,22 @@ public:
/** @brief 网格、点和单元均存在时返回 true。 */
bool isValid() const;
/** 以下访问函数均不转移所有权。 */
/** @brief 返回共享网格的非所有权指针。 */
vtkUnstructuredGrid* getGrid() const;
/** @brief 返回已提交网格类型;当前 Builder 只接受 PEBI。 */
NM_Grid_Type getGridType() const;
/** @brief 返回生成当前网格时对应的输入版本。 */
quint64 getGridInputRevision() const;
/** @brief 返回最终 VTK 网格中的有效单元数量。 */
vtkIdType getValidCellCount() const;
bool hasMaterial() const;
private:
friend class nmPebiGridViewDataBuilder;
friend class nmPebiGridViewDataBuilder; ///< 仅 Builder 可提交完整候选数据。
vtkSmartPointer<vtkUnstructuredGrid> m_pGrid; ///< 共享已提交网格的 VTK 引用。
NM_Grid_Type m_eGridType;
quint64 m_nGridInputRevision;
vtkIdType m_nValidCellCount;
bool m_bHasMaterial; ///< 仅表示存在维度正确的 CellData/Material。
NM_Grid_Type m_eGridType; ///< 与共享网格对应的业务网格类型。
quint64 m_nGridInputRevision; ///< 构建该网格所使用的输入版本。
vtkIdType m_nValidCellCount; ///< 经过业务过滤后实际进入 VTK 的单元数。
};
#endif // NMPEBIGRIDVIEWDATA_H

@ -11,6 +11,8 @@ class nmPebiGridViewData;
/**
* @brief GUI 线 nmData
*
* Builder PEBI
* DataManagerAnalysisCase
*
*/
class NM_SUB_WXS_EXPORT nmPebiGridViewDataBuilder
@ -19,7 +21,8 @@ public:
/**
* @param pDataManager
* @param pViewData
* @param pError
* @param pError
* @return 线 true
*/
static bool build(nmDataAnalyzeManager* pDataManager,
nmPebiGridViewData* pViewData,

@ -6,7 +6,6 @@
#include <QWidget>
class QAction;
class QComboBox;
class QLabel;
class QMenu;
class QToolBar;
@ -18,8 +17,14 @@ class nmWxVTKRenderContainerWidget;
/**
* @brief PEBI
*
*
* nmRender
* 线
* XY
* QAction
* nmRender
*
* setViewData/showLoading/showFailure/clearView
*
* PEBI
*/
class NM_SUB_WXS_EXPORT nmWxPebiGridViewWidget : public QWidget
{
@ -36,37 +41,35 @@ public:
void showLoading();
/** @brief 有旧数据时恢复画面并显示提示,否则显示错误状态页。 */
void showFailure(const QString& sMessage);
/** @brief 清除旧分析网格、属性选择和视图命令状态。 */
/** @brief 清除旧分析网格和视图命令状态。 */
void clearView();
/** @brief 当前场景是否保留一份绑定成功的网格数据。 */
bool hasViewData() const;
private slots:
void onPropertyChanged(int nIndex);
void onGridLinesToggled(bool bVisible);
void onScalarBarToggled(bool bVisible);
/** @brief 切换世界坐标中的 XY 比例网格,不改变相机。 */
void onBoundsGridToggled(bool bVisible);
/** @brief 向通用右键菜单追加本窗口独占的比例网格动作。 */
void appendContextMenuActions(QMenu* pMenu);
private:
Q_DISABLE_COPY(nmWxPebiGridViewWidget)
/** @brief 创建右侧命令栏、状态提示栏和底部网格信息栏。 */
void createUi();
/** @brief 恢复无数据时的比例网格偏好和底栏文字。 */
void resetControls();
/** @brief 统一启停依赖有效网格的业务动作。 */
void setControlsEnabled(bool bEnabled);
void updateScalarBarActionState();
QString gridTypeText(int nGridType) const;
nmWxVTKRenderContainerWidget* m_pRenderContainer; ///< Qt 父对象拥有。
nmPebiGridSceneController* m_pSceneController; ///< 本类独占并先于容器销毁。
QToolBar* m_pToolBar;
QAction* m_pGridLinesAction;
QAction* m_pScalarBarAction;
QAction* m_pBoundsGridAction;
QComboBox* m_pPropertyComboBox;
QLabel* m_pGridInfoLabel;
QLabel* m_pStatusLabel;
bool m_bHasViewData;
nmWxVTKRenderContainerWidget* m_pRenderContainer; ///< Qt 父对象拥有的通用渲染容器。
nmPebiGridSceneController* m_pSceneController; ///< 本类独占,必须先于容器销毁。
QToolBar* m_pToolBar; ///< Qt 父对象拥有的右侧竖向工具栏。
QAction* m_pBoundsGridAction; ///< 工具栏和右键菜单共享的比例网格动作。
QLabel* m_pGridInfoLabel; ///< 底栏左侧的网格类型、单元数和平面信息。
QLabel* m_pStatusLabel; ///< 建网失败且保留旧网格时使用的黄色提示栏。
bool m_bHasViewData; ///< 与场景控制器的成功数据状态保持同步。
};
#endif // NMWXPEBIGRIDVIEWWIDGET_H

@ -43,7 +43,7 @@ nmVTKViewCommandController::nmVTKViewCommandController(
"NmZoomReset.png", SLOT(fitView()));
createAction(ViewCommand_Top, tr("Top View"), "NmTopView.png",
SLOT(setTopView()));
createAction(ViewCommand_Front, tr("Front View"), QString(),
createAction(ViewCommand_Front, tr("Front View"), "NmSideView.png",
SLOT(setFrontView()));
createAction(ViewCommand_Right, tr("Right View"), QString(),
SLOT(setRightView()));

@ -4,7 +4,6 @@
#include "nmVTKMeshLayer.h"
#include "nmVTKPlanarScaleGridLayer.h"
#include "nmVTKScalarBarLayer.h"
#include "nmVTKScene.h"
#include "nmWxVTKRenderContainerWidget.h"
@ -52,12 +51,8 @@ public:
nmWxVTKRenderContainerWidget* pRenderContainer)
: m_pContainer(pRenderContainer),
m_pMeshLayer(nullptr),
m_pScalarBarLayer(nullptr),
m_pPlanarScaleGridLayer(nullptr),
m_bGridLinesVisible(true),
m_bScalarBarVisible(true),
m_bBoundsGridVisible(false),
m_bPropertySelectionExplicit(false),
m_bHasData(false)
{
}
@ -81,7 +76,7 @@ public:
return false;
}
m_pMeshLayer = pLayer;
// 无属性时使用稳定灰色Material 有效时仍由 MeshLayer 的 LUT 着色
// PEBI 预览固定使用稳定灰色表面和黑色单元边线
m_pMeshLayer->getActor()->GetProperty()->SetColor(
211.0 / 255.0, 211.0 / 255.0,
211.0 / 255.0);
@ -104,75 +99,7 @@ public:
return true;
}
bool ensureScalarBarLayer()
{
if(m_pScalarBarLayer != nullptr) {
return true;
}
nmVTKScene* pScene = m_pContainer != nullptr
? m_pContainer->getScene() : nullptr;
if(pScene == nullptr || m_pMeshLayer == nullptr) {
return false;
}
// 色标只在第一次选择有效标量时创建,并共享 MeshLayer 的 LUT。
nmVTKScalarBarLayer* pLayer =
new nmVTKScalarBarLayer("pebi.grid.scalar_bar");
pLayer->setLookupTable(m_pMeshLayer->getLookupTable());
pLayer->setPosition(0.86, 0.12);
pLayer->setSize(0.10, 0.76);
pLayer->setVisible(false);
if(!pScene->addLayer(pLayer)) {
delete pLayer;
return false;
}
m_pScalarBarLayer = pLayer;
return true;
}
bool applyProperty(const QString& sPropertyName)
{
if(m_pMeshLayer == nullptr) {
return false;
}
if(sPropertyName.isEmpty()) {
m_sPropertyName.clear();
m_pMeshLayer->setScalarVisibility(false);
if(m_pScalarBarLayer != nullptr) {
m_pScalarBarLayer->setVisible(false);
}
return true;
}
if(sPropertyName != "Material" || !m_oViewData.hasMaterial() ||
!m_pMeshLayer->setScalarArray(
sPropertyName, nmVTKMeshLayer::ScalarAssociation_CellData)) {
// 无效属性不能沿用上一网格的标量着色或色标范围。
m_sPropertyName.clear();
m_pMeshLayer->setScalarVisibility(false);
if(m_pScalarBarLayer != nullptr) {
m_pScalarBarLayer->setVisible(false);
}
return false;
}
if(!ensureScalarBarLayer()) {
m_sPropertyName.clear();
m_pMeshLayer->setScalarVisibility(false);
return false;
}
m_sPropertyName = sPropertyName;
m_pMeshLayer->setScalarVisibility(true);
m_pScalarBarLayer->setLookupTable(
m_pMeshLayer->getLookupTable());
m_pScalarBarLayer->setTitle(sPropertyName);
m_pScalarBarLayer->setVisible(m_bScalarBarVisible);
return true;
}
bool bindViewData(const nmPebiGridViewData& oViewData,
const QString& sRequestedProperty,
const double dBounds[6])
{
if(m_pMeshLayer == nullptr || m_pPlanarScaleGridLayer == nullptr ||
@ -186,7 +113,10 @@ public:
m_oViewData.clear();
return false;
}
m_pMeshLayer->setEdgeVisibility(m_bGridLinesVisible);
// 输入可能包含历史数组,网格预览始终关闭标量着色并显示单元边线。
m_pMeshLayer->setScalarVisibility(false);
m_pMeshLayer->setDisplayMode(
nmVTKMeshLayer::DisplayMode_SurfaceWithEdges);
m_pMeshLayer->setVisible(true);
if(!m_pPlanarScaleGridLayer->setBounds(
@ -200,8 +130,6 @@ public:
m_pPlanarScaleGridLayer->setVisible(m_bBoundsGridVisible);
m_bHasData = true;
// 属性不可用只回退固定面色,不影响已经验证成功的网格几何提交。
applyProperty(sRequestedProperty);
// 只有整份网格绑定成功后才允许公共拾取器命中主 Mesh Actor。
if(m_pContainer != nullptr) {
m_pContainer->setRotationCenterPickTarget(
@ -222,29 +150,19 @@ public:
m_pMeshLayer->setDataSet(nullptr);
m_pMeshLayer->setVisible(false);
}
if(m_pScalarBarLayer != nullptr) {
m_pScalarBarLayer->setVisible(false);
}
if(m_pPlanarScaleGridLayer != nullptr) {
m_pPlanarScaleGridLayer->setVisible(false);
}
m_oViewData.clear();
m_sPropertyName.clear();
m_bHasData = false;
}
nmWxVTKRenderContainerWidget* m_pContainer; ///< 非所有权指针。
nmVTKMeshLayer* m_pMeshLayer; ///< Scene 所有,控制器只观察。
nmVTKScalarBarLayer* m_pScalarBarLayer; ///< Scene 所有,按需创建。
nmVTKPlanarScaleGridLayer* m_pPlanarScaleGridLayer; ///< Scene 所有。
nmPebiGridViewData m_oViewData;
bool m_bGridLinesVisible;
bool m_bScalarBarVisible; ///< 用户偏好,无属性时仍保留。
bool m_bBoundsGridVisible;
bool m_bPropertySelectionExplicit; ///< 是否已由业务界面明确选择属性。
bool m_bHasData;
QString m_sRequestedPropertyName; ///< 显式选择偏好,可暂时不可用。
QString m_sPropertyName;
};
nmPebiGridSceneController::nmPebiGridSceneController(
@ -260,7 +178,6 @@ nmPebiGridSceneController::~nmPebiGridSceneController()
m_pPrivate->releaseGridData();
m_pPrivate->m_pContainer = nullptr;
m_pPrivate->m_pMeshLayer = nullptr;
m_pPrivate->m_pScalarBarLayer = nullptr;
m_pPrivate->m_pPlanarScaleGridLayer = nullptr;
delete m_pPrivate;
m_pPrivate = nullptr;
@ -296,32 +213,21 @@ bool nmPebiGridSceneController::setViewData(
return false;
}
QString sRequestedProperty;
if(m_pPrivate->m_bPropertySelectionExplicit) {
// 用户明确选择优先;即使属性暂时缺失,也保留偏好供后续网格恢复。
sRequestedProperty = m_pPrivate->m_sRequestedPropertyName;
} else if(oViewData.hasMaterial()) {
// 默认选择与“是否首次装入网格”无关,首次出现 Material 时同样生效。
sRequestedProperty = "Material";
}
// 强引用保留上一份成功数据,提交任一步失败时可以完整恢复旧画面。
const bool bHadPreviousData = m_pPrivate->m_bHasData;
const nmPebiGridViewData oPreviousViewData = m_pPrivate->m_oViewData;
const QString sPreviousProperty = m_pPrivate->m_sPropertyName;
double dPreviousBounds[6];
const bool bHasPreviousBounds = bHadPreviousData &&
getFiniteGridBounds(oPreviousViewData.getGrid(), dPreviousBounds);
// 几何替换先解除旧输入再共享新网格Renderer 和图层对象保持不变。
m_pPrivate->releaseGridData();
if(!m_pPrivate->bindViewData(oViewData, sRequestedProperty, dBounds)) {
if(!m_pPrivate->bindViewData(oViewData, dBounds)) {
// 回滚同样不渲染;外层失败状态会决定恢复旧画面还是显示错误页。
m_pPrivate->releaseGridData();
if(bHadPreviousData && bHasPreviousBounds) {
m_pPrivate->bindViewData(
oPreviousViewData,
sPreviousProperty,
dPreviousBounds);
}
if(pError != nullptr) {
@ -344,59 +250,7 @@ void nmPebiGridSceneController::clear()
return;
}
m_pPrivate->releaseGridData();
m_pPrivate->m_sPropertyName.clear();
m_pPrivate->m_sRequestedPropertyName.clear();
m_pPrivate->m_bGridLinesVisible = true;
m_pPrivate->m_bScalarBarVisible = true;
m_pPrivate->m_bBoundsGridVisible = false;
m_pPrivate->m_bPropertySelectionExplicit = false;
}
void nmPebiGridSceneController::setGridLinesVisible(bool bVisible)
{
if(m_pPrivate == nullptr) {
return;
}
m_pPrivate->m_bGridLinesVisible = bVisible;
if(m_pPrivate->m_pMeshLayer != nullptr) {
m_pPrivate->m_pMeshLayer->setEdgeVisibility(bVisible);
}
if(m_pPrivate->m_bHasData && m_pPrivate->m_pContainer != nullptr) {
m_pPrivate->m_pContainer->renderView();
}
}
bool nmPebiGridSceneController::setProperty(const QString& sPropertyName)
{
if(m_pPrivate == nullptr || !m_pPrivate->m_bHasData) {
return false;
}
const bool bSucceeded = m_pPrivate->applyProperty(sPropertyName);
// 只有公开入口代表用户/业务明确选择,内部默认绑定不会污染该状态。
m_pPrivate->m_bPropertySelectionExplicit = true;
m_pPrivate->m_sRequestedPropertyName = bSucceeded
? sPropertyName : QString();
if(m_pPrivate->m_pContainer != nullptr) {
m_pPrivate->m_pContainer->renderView();
}
return bSucceeded;
}
void nmPebiGridSceneController::setScalarBarVisible(bool bVisible)
{
if(m_pPrivate == nullptr) {
return;
}
// 无属性时只保存偏好;重新选择 Material 后按该偏好恢复色标。
m_pPrivate->m_bScalarBarVisible = bVisible;
if(m_pPrivate->m_pScalarBarLayer != nullptr) {
m_pPrivate->m_pScalarBarLayer->setVisible(
bVisible && m_pPrivate->m_bHasData &&
!m_pPrivate->m_sPropertyName.isEmpty());
}
if(m_pPrivate->m_bHasData && m_pPrivate->m_pContainer != nullptr) {
m_pPrivate->m_pContainer->renderView();
}
}
void nmPebiGridSceneController::setBoundsGridVisible(bool bVisible)
@ -419,22 +273,6 @@ bool nmPebiGridSceneController::hasViewData() const
return m_pPrivate != nullptr && m_pPrivate->m_bHasData;
}
QString nmPebiGridSceneController::getProperty() const
{
return m_pPrivate != nullptr
? m_pPrivate->m_sPropertyName : QString();
}
bool nmPebiGridSceneController::isGridLinesVisible() const
{
return m_pPrivate != nullptr && m_pPrivate->m_bGridLinesVisible;
}
bool nmPebiGridSceneController::isScalarBarVisible() const
{
return m_pPrivate != nullptr && m_pPrivate->m_bScalarBarVisible;
}
bool nmPebiGridSceneController::isBoundsGridVisible() const
{
return m_pPrivate != nullptr && m_pPrivate->m_bBoundsGridVisible;

@ -6,8 +6,7 @@ nmPebiGridViewData::nmPebiGridViewData()
: m_pGrid(nullptr),
m_eGridType(NM_Grid_UNKNWON),
m_nGridInputRevision(0),
m_nValidCellCount(0),
m_bHasMaterial(false)
m_nValidCellCount(0)
{
}
@ -18,11 +17,11 @@ void nmPebiGridViewData::clear()
m_eGridType = NM_Grid_UNKNWON;
m_nGridInputRevision = 0;
m_nValidCellCount = 0;
m_bHasMaterial = false;
}
bool nmPebiGridViewData::isValid() const
{
// 预览必须同时具备有效引用、点、单元和业务确认的有效单元计数。
return m_pGrid != nullptr &&
m_pGrid->GetNumberOfPoints() > 0 &&
m_pGrid->GetNumberOfCells() > 0 &&
@ -48,8 +47,3 @@ vtkIdType nmPebiGridViewData::getValidCellCount() const
{
return m_nValidCellCount;
}
bool nmPebiGridViewData::hasMaterial() const
{
return m_bHasMaterial;
}

@ -8,9 +8,6 @@
#include <QCoreApplication>
#include <QThread>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkMath.h>
#include <vtkUnstructuredGrid.h>
namespace {
@ -98,13 +95,6 @@ bool nmPebiGridViewDataBuilder::build(
pAnalysisCase->getGridInputRevision();
oCandidate.m_nValidCellCount = pGrid->GetNumberOfCells();
// Material 只认可 CellData 中与 VTK 单元一一对应的数组。
vtkCellData* pCellData = pGrid->GetCellData();
vtkDataArray* pMaterialArray = pCellData != nullptr
? pCellData->GetArray("Material") : nullptr;
oCandidate.m_bHasMaterial = pMaterialArray != nullptr &&
pMaterialArray->GetNumberOfTuples() == pGrid->GetNumberOfCells();
*pViewData = oCandidate;
return true;
}

@ -7,7 +7,6 @@
#include "nmWxVTKRenderContainerWidget.h"
#include <QAction>
#include <QComboBox>
#include <QCoreApplication>
#include <QHBoxLayout>
#include <QIcon>
@ -16,7 +15,6 @@
#include <QSize>
#include <QToolBar>
#include <QVBoxLayout>
#include <QVariant>
namespace {
@ -34,10 +32,7 @@ nmWxPebiGridViewWidget::nmWxPebiGridViewWidget(QWidget* pParent)
m_pRenderContainer(nullptr),
m_pSceneController(nullptr),
m_pToolBar(nullptr),
m_pGridLinesAction(nullptr),
m_pScalarBarAction(nullptr),
m_pBoundsGridAction(nullptr),
m_pPropertyComboBox(nullptr),
m_pGridInfoLabel(nullptr),
m_pStatusLabel(nullptr),
m_bHasViewData(false)
@ -70,6 +65,7 @@ void nmWxPebiGridViewWidget::createUi()
pRenderLayout->setContentsMargins(0, 0, 0, 0);
pRenderLayout->setSpacing(0);
// 公共容器独占 Renderer、相机和交互对象本类只裁剪可见命令能力。
m_pRenderContainer = new nmWxVTKRenderContainerWidget(pRenderArea);
m_pRenderContainer->setSizePolicy(
QSizePolicy::Expanding, QSizePolicy::Expanding);
@ -78,6 +74,7 @@ void nmWxPebiGridViewWidget::createUi()
nmVTKViewCommandController::ViewCommand_ZoomOut |
nmVTKViewCommandController::ViewCommand_Fit |
nmVTKViewCommandController::ViewCommand_Top |
nmVTKViewCommandController::ViewCommand_Front |
nmVTKViewCommandController::ViewCommand_SetRotationCenter |
nmVTKViewCommandController::ViewCommand_SaveImage |
nmVTKViewCommandController::ViewCommand_CopyImage |
@ -95,17 +92,7 @@ void nmWxPebiGridViewWidget::createUi()
nmVTKViewCommandController* pCommandController =
m_pRenderContainer->getViewCommandController();
// 三个业务 QAction 与公共命令一样长期持有,并同时用于工具栏和右键菜单。
m_pGridLinesAction = new QAction(
QIcon(gridViewIconPath("Grids.png")),
tr("Show Grid Lines"), this);
m_pGridLinesAction->setToolTip(tr("Show Grid Lines"));
m_pGridLinesAction->setCheckable(true);
m_pScalarBarAction = new QAction(
QIcon(gridViewIconPath("NmColorScale.png")),
tr("Show Scalar Bar"), this);
m_pScalarBarAction->setToolTip(tr("Show Scalar Bar"));
m_pScalarBarAction->setCheckable(true);
// 比例网格 QAction 长期持有,并同时用于工具栏和右键菜单。
m_pBoundsGridAction = new QAction(
QIcon(gridViewIconPath("NmScaleGrid.png")),
tr("Scale Grid"), this);
@ -122,11 +109,14 @@ void nmWxPebiGridViewWidget::createUi()
nmVTKViewCommandController::ViewCommand_ZoomIn);
QAction* pTopAction = pCommandController->getAction(
nmVTKViewCommandController::ViewCommand_Top);
QAction* pFrontAction = pCommandController->getAction(
nmVTKViewCommandController::ViewCommand_Front);
QAction* pSetRotationCenterAction = pCommandController->getAction(
nmVTKViewCommandController::
ViewCommand_SetRotationCenter);
QAction* pCopyAction = pCommandController->getAction(
nmVTKViewCommandController::ViewCommand_CopyImage);
// 按“缩放、标准视角、显示、输出”分组,空组不会留下多余分隔线。
bool bHasPreviousGroup = false;
if(pZoomOutAction != nullptr) {
m_pToolBar->addAction(pZoomOutAction);
@ -141,6 +131,7 @@ void nmWxPebiGridViewWidget::createUi()
bHasPreviousGroup = true;
}
const bool bHasViewGroup = pTopAction != nullptr ||
pFrontAction != nullptr ||
pSetRotationCenterAction != nullptr;
if(bHasViewGroup && bHasPreviousGroup) {
m_pToolBar->addSeparator();
@ -149,6 +140,10 @@ void nmWxPebiGridViewWidget::createUi()
m_pToolBar->addAction(pTopAction);
bHasPreviousGroup = true;
}
if(pFrontAction != nullptr) {
m_pToolBar->addAction(pFrontAction);
bHasPreviousGroup = true;
}
if(pSetRotationCenterAction != nullptr) {
m_pToolBar->addAction(pSetRotationCenterAction);
bHasPreviousGroup = true;
@ -156,8 +151,6 @@ void nmWxPebiGridViewWidget::createUi()
if(bHasPreviousGroup) {
m_pToolBar->addSeparator();
}
m_pToolBar->addAction(m_pGridLinesAction);
m_pToolBar->addAction(m_pScalarBarAction);
m_pToolBar->addAction(m_pBoundsGridAction);
if(pCopyAction != nullptr) {
m_pToolBar->addSeparator();
@ -165,8 +158,6 @@ void nmWxPebiGridViewWidget::createUi()
}
} else {
// 理论上不会进入;仍保留业务动作,避免容器初始化异常时布局跳动。
m_pToolBar->addAction(m_pGridLinesAction);
m_pToolBar->addAction(m_pScalarBarAction);
m_pToolBar->addAction(m_pBoundsGridAction);
}
@ -185,29 +176,18 @@ void nmWxPebiGridViewWidget::createUi()
m_pStatusLabel->hide();
pMainLayout->addWidget(m_pStatusLabel);
// 底栏只承担几何信息展示,不放置属性或渲染模式控件。
QWidget* pControlBar = new QWidget(this);
QHBoxLayout* pControlLayout = new QHBoxLayout(pControlBar);
pControlLayout->setContentsMargins(8, 5, 8, 5);
pControlLayout->setSpacing(6);
QLabel* pPropertyLabel = new QLabel(tr("Property:"), pControlBar);
m_pPropertyComboBox = new QComboBox(pControlBar);
m_pPropertyComboBox->setMinimumContentsLength(9);
pControlLayout->addWidget(pPropertyLabel);
pControlLayout->addWidget(m_pPropertyComboBox);
pControlLayout->addStretch(1);
m_pGridInfoLabel = new QLabel(pControlBar);
m_pGridInfoLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
m_pGridInfoLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
pControlLayout->addWidget(m_pGridInfoLabel);
pControlLayout->addStretch(1);
pMainLayout->addWidget(pControlBar);
connect(m_pPropertyComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(onPropertyChanged(int)));
connect(m_pGridLinesAction, SIGNAL(toggled(bool)),
this, SLOT(onGridLinesToggled(bool)));
connect(m_pScalarBarAction, SIGNAL(toggled(bool)),
this, SLOT(onScalarBarToggled(bool)));
connect(m_pBoundsGridAction, SIGNAL(toggled(bool)),
this, SLOT(onBoundsGridToggled(bool)));
connect(m_pRenderContainer, SIGNAL(contextMenuAboutToShow(QMenu*)),
@ -224,38 +204,21 @@ bool nmWxPebiGridViewWidget::setViewData(
}
return false;
}
// SceneController 负责事务式绑定;失败时这里按其回滚结果同步外层状态。
if(!m_pSceneController->setViewData(oViewData, pError)) {
// 控制器回滚失败时同步清除外层标志,避免把空场景误当作旧成功网格。
m_bHasViewData = m_pSceneController->hasViewData();
return false;
}
// 属性列表只登记 Builder 已确认与 CellData 单元数一致的 Material。
const bool bOldBlockState = m_pPropertyComboBox->blockSignals(true);
m_pPropertyComboBox->clear();
m_pPropertyComboBox->addItem(tr("No property"), QString());
if(oViewData.hasMaterial()) {
m_pPropertyComboBox->addItem(tr("Material"), QString("Material"));
}
const QString sActiveProperty = m_pSceneController->getProperty();
for(int nIndex = 0; nIndex < m_pPropertyComboBox->count(); ++nIndex) {
if(m_pPropertyComboBox->itemData(nIndex).toString() ==
sActiveProperty) {
m_pPropertyComboBox->setCurrentIndex(nIndex);
break;
}
}
m_pPropertyComboBox->blockSignals(bOldBlockState);
// Builder 只接受已提交的 PEBI 网格,因此底栏无需再显示“未知类型”。
m_pGridInfoLabel->setText(
tr("%1 cells | %2")
tr("PEBI | %1 valid cells | XY planar grid")
.arg(static_cast<qlonglong>(
oViewData.getValidCellCount()))
.arg(gridTypeText(static_cast<int>(oViewData.getGridType()))));
oViewData.getValidCellCount())));
m_pStatusLabel->hide();
m_bHasViewData = true;
setControlsEnabled(true);
updateScalarBarActionState();
return true;
}
@ -274,10 +237,10 @@ void nmWxPebiGridViewWidget::showFailure(const QString& sMessage)
m_pStatusLabel->setText(sMessage);
m_pStatusLabel->show();
setControlsEnabled(true);
updateScalarBarActionState();
m_pRenderContainer->showReadyState();
} else {
m_pStatusLabel->hide();
resetControls();
setControlsEnabled(false);
m_pRenderContainer->showErrorState(sMessage);
}
@ -302,80 +265,16 @@ bool nmWxPebiGridViewWidget::hasViewData() const
void nmWxPebiGridViewWidget::resetControls()
{
bool bBlocked = m_pPropertyComboBox->blockSignals(true);
m_pPropertyComboBox->clear();
m_pPropertyComboBox->addItem(tr("No property"), QString());
m_pPropertyComboBox->blockSignals(bBlocked);
bBlocked = m_pGridLinesAction->blockSignals(true);
m_pGridLinesAction->setChecked(true);
m_pGridLinesAction->blockSignals(bBlocked);
bBlocked = m_pScalarBarAction->blockSignals(true);
m_pScalarBarAction->setChecked(true);
m_pScalarBarAction->blockSignals(bBlocked);
bBlocked = m_pBoundsGridAction->blockSignals(true);
const bool bBlocked = m_pBoundsGridAction->blockSignals(true);
m_pBoundsGridAction->setChecked(false);
m_pBoundsGridAction->blockSignals(bBlocked);
m_pGridInfoLabel->setText(tr("0 cells | Unknown"));
m_pGridInfoLabel->setText(
tr("PEBI | %1 valid cells | XY planar grid").arg(0));
}
void nmWxPebiGridViewWidget::setControlsEnabled(bool bEnabled)
{
m_pPropertyComboBox->setEnabled(bEnabled);
m_pGridLinesAction->setEnabled(bEnabled);
m_pBoundsGridAction->setEnabled(bEnabled);
m_pScalarBarAction->setEnabled(
bEnabled && m_pSceneController != nullptr &&
!m_pSceneController->getProperty().isEmpty());
}
void nmWxPebiGridViewWidget::updateScalarBarActionState()
{
if(m_pSceneController == nullptr) {
return;
}
const bool bBlocked = m_pScalarBarAction->blockSignals(true);
m_pScalarBarAction->setChecked(
m_pSceneController->isScalarBarVisible());
m_pScalarBarAction->blockSignals(bBlocked);
m_pScalarBarAction->setEnabled(
m_bHasViewData &&
!m_pSceneController->getProperty().isEmpty());
}
QString nmWxPebiGridViewWidget::gridTypeText(int nGridType) const
{
return nGridType == static_cast<int>(NM_Grid_PEBI)
? QString("PEBI") : tr("Unknown");
}
void nmWxPebiGridViewWidget::onPropertyChanged(int nIndex)
{
if(!m_bHasViewData || nIndex < 0 || m_pSceneController == nullptr) {
return;
}
const QString sPropertyName =
m_pPropertyComboBox->itemData(nIndex).toString();
if(!m_pSceneController->setProperty(sPropertyName)) {
const bool bBlocked = m_pPropertyComboBox->blockSignals(true);
m_pPropertyComboBox->setCurrentIndex(0);
m_pPropertyComboBox->blockSignals(bBlocked);
}
updateScalarBarActionState();
}
void nmWxPebiGridViewWidget::onGridLinesToggled(bool bVisible)
{
if(m_bHasViewData && m_pSceneController != nullptr) {
m_pSceneController->setGridLinesVisible(bVisible);
}
}
void nmWxPebiGridViewWidget::onScalarBarToggled(bool bVisible)
{
if(m_bHasViewData && m_pSceneController != nullptr) {
m_pSceneController->setScalarBarVisible(bVisible);
}
}
void nmWxPebiGridViewWidget::onBoundsGridToggled(bool bVisible)
@ -390,8 +289,6 @@ void nmWxPebiGridViewWidget::appendContextMenuActions(QMenu* pMenu)
if(pMenu == nullptr) {
return;
}
// 右键菜单与工具栏引用同三个业务 QAction勾选状态不会发生分叉。
pMenu->addAction(m_pGridLinesAction);
pMenu->addAction(m_pScalarBarAction);
// 右键菜单与工具栏引用同一个比例网格 QAction勾选状态不会发生分叉。
pMenu->addAction(m_pBoundsGridAction);
}

Loading…
Cancel
Save