diff --git a/Bin/Config/Lang/cn/nmNum_cn.qm b/Bin/Config/Lang/cn/nmNum_cn.qm index 2b422c0..ee4d0fb 100644 Binary files a/Bin/Config/Lang/cn/nmNum_cn.qm and b/Bin/Config/Lang/cn/nmNum_cn.qm differ diff --git a/Bin/Config/Lang/cn/nmNum_cn.ts b/Bin/Config/Lang/cn/nmNum_cn.ts index 9ec454a..0a82dcc 100644 --- a/Bin/Config/Lang/cn/nmNum_cn.ts +++ b/Bin/Config/Lang/cn/nmNum_cn.ts @@ -2806,16 +2806,9 @@ Reason: %1 nmWxPebiGridViewWidget No grid data.暂无网格数据。 - Property:属性: - Show Grid Lines显示网格线 - Show Scalar Bar显示色标 Scale Grid比例网格 The grid preview data is invalid.网格预览数据无效。 - No property无属性 - Material材质 - %1 cells | %2%1 个单元 | %2 - 0 cells | Unknown0 个单元 | 未知 - Unknown未知 + PEBI | %1 valid cells | XY planar gridPEBI | %1 个有效单元 | XY 平面网格 Generating grid...正在生成网格... @@ -5036,7 +5029,7 @@ Please check your input coordinates. Zoom Out缩小 Fit to Window适应窗口 Top View顶视图 - Front View前视图 + Front View正视图 Right View右视图 Isometric View等轴测视图 Reset Rotation Center重置旋转中心 @@ -5071,7 +5064,7 @@ Please check your input coordinates. Front View - 前视图 + 正视图 Right View diff --git a/Include/nmNum/nmSubWxs/nmPebiGridSceneController.h b/Include/nmNum/nmSubWxs/nmPebiGridSceneController.h index d769e7d..4b5961a 100644 --- a/Include/nmNum/nmSubWxs/nmPebiGridSceneController.h +++ b/Include/nmNum/nmSubWxs/nmPebiGridSceneController.h @@ -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: diff --git a/Include/nmNum/nmSubWxs/nmPebiGridViewData.h b/Include/nmNum/nmSubWxs/nmPebiGridViewData.h index 23935c6..c858273 100644 --- a/Include/nmNum/nmSubWxs/nmPebiGridViewData.h +++ b/Include/nmNum/nmSubWxs/nmPebiGridViewData.h @@ -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 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 diff --git a/Include/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.h b/Include/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.h index b87187b..d005030 100644 --- a/Include/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.h +++ b/Include/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.h @@ -11,6 +11,8 @@ class nmPebiGridViewData; /** * @brief 在 GUI 线程把 nmData 对象转换成独立的网格预览数据。 * + * Builder 只读取已经提交的 PEBI 网格、网格类型和输入版本,不保存 + * DataManager、AnalysisCase 或其他业务对象指针,也不解释历史属性数组。 * 构建过程先完成全部校验,再一次性写入输出对象,失败时不会暴露半成品。 */ 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, diff --git a/Include/nmNum/nmSubWxs/nmWxPebiGridViewWidget.h b/Include/nmNum/nmSubWxs/nmWxPebiGridViewWidget.h index 1d4f7cc..ba110cb 100644 --- a/Include/nmNum/nmSubWxs/nmWxPebiGridViewWidget.h +++ b/Include/nmNum/nmSubWxs/nmWxPebiGridViewWidget.h @@ -6,7 +6,6 @@ #include 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 diff --git a/Src/nmNum/nmRender/nmVTKViewCommandController.cpp b/Src/nmNum/nmRender/nmVTKViewCommandController.cpp index 0b7b53e..6c8c5dd 100644 --- a/Src/nmNum/nmRender/nmVTKViewCommandController.cpp +++ b/Src/nmNum/nmRender/nmVTKViewCommandController.cpp @@ -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())); diff --git a/Src/nmNum/nmSubWxs/nmPebiGridSceneController.cpp b/Src/nmNum/nmSubWxs/nmPebiGridSceneController.cpp index 0f6eaab..28cb766 100644 --- a/Src/nmNum/nmSubWxs/nmPebiGridSceneController.cpp +++ b/Src/nmNum/nmSubWxs/nmPebiGridSceneController.cpp @@ -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; diff --git a/Src/nmNum/nmSubWxs/nmPebiGridViewData.cpp b/Src/nmNum/nmSubWxs/nmPebiGridViewData.cpp index 7eb2a69..dfc7b7c 100644 --- a/Src/nmNum/nmSubWxs/nmPebiGridViewData.cpp +++ b/Src/nmNum/nmSubWxs/nmPebiGridViewData.cpp @@ -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; -} diff --git a/Src/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.cpp b/Src/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.cpp index e004762..6df8fd7 100644 --- a/Src/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.cpp +++ b/Src/nmNum/nmSubWxs/nmPebiGridViewDataBuilder.cpp @@ -8,9 +8,6 @@ #include #include -#include -#include -#include #include 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; } diff --git a/Src/nmNum/nmSubWxs/nmWxPebiGridViewWidget.cpp b/Src/nmNum/nmSubWxs/nmWxPebiGridViewWidget.cpp index 16235d9..3dd3dbf 100644 --- a/Src/nmNum/nmSubWxs/nmWxPebiGridViewWidget.cpp +++ b/Src/nmNum/nmSubWxs/nmWxPebiGridViewWidget.cpp @@ -7,7 +7,6 @@ #include "nmWxVTKRenderContainerWidget.h" #include -#include #include #include #include @@ -16,7 +15,6 @@ #include #include #include -#include 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( - oViewData.getValidCellCount())) - .arg(gridTypeText(static_cast(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(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); }