You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Include/nmNum/nmRender/nmVTKMeshLayer.h

188 lines
8.7 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef NMVTKMESHLAYER_H
#define NMVTKMESHLAYER_H
#include "nmVTKRenderLayer.h"
#include <QByteArray>
#include <vtkSmartPointer.h>
class vtkActor;
class vtkAlgorithmOutput;
class vtkDataArray;
class vtkDataSet;
class vtkDataSetMapper;
class vtkLookupTable;
/**
* @brief 通用数据集表面图层,不包含任何业务属性名称。
*
* 图层共享输入数据集的 VTK 引用,独占 Mapper、Actor 和 LookupTable。
* 所有修改只更新管线状态,不主动触发 Render。
*/
class NM_RENDER_EXPORT nmVTKMeshLayer : public nmVTKRenderLayer
{
public:
enum DisplayMode
{
DisplayMode_Surface = 0, ///< 只显示填充表面。
DisplayMode_SurfaceWithEdges ///< 同时显示表面和单元边线。
};
enum ScalarAssociation
{
ScalarAssociation_CellData = 0, ///< 从 CellData 选择标量数组。
ScalarAssociation_PointData ///< 从 PointData 选择标量数组。
};
/** @brief 创建空数据图层并建立默认表面渲染管线。 */
explicit nmVTKMeshLayer(const QString& sLayerId);
/** @brief 先解除 Renderer,再释放共享数据引用。 */
virtual ~nmVTKMeshLayer();
/**
* @brief 共享传入数据集的 VTK 引用,不执行 DeepCopy。
* @return 数据集非空且原标量选择在新数据集中仍有效时返回 true;失败时
* 保留原输入、标量选择和 Mapper 状态。传入 nullptr 会清除输入。
*/
bool setDataSet(vtkDataSet* pDataSet);
/**
* @brief 连接通用 VTK 管线输出,不取得 Producer 所有权。
* @return 输出为数据集且原标量选择仍有效时返回 true;失败时保留原输入。
*/
bool setInputConnection(vtkAlgorithmOutput* pInputConnection);
/**
* @brief 原子提交管线输出、标量数组和显式显示范围。
*
* 候选输出、数组、数据范围和显示范围会在 Mapper 改动前完整验证;
* 返回 false 时原输入、数组选择、范围和 LookupTable 均保持不变。
*/
bool setInputConnection(vtkAlgorithmOutput* pInputConnection,
const QString& sArrayName,
ScalarAssociation eAssociation,
double dMinimum,
double dMaximum);
/**
* @brief 原子提交管线输入、标量数组和完整候选颜色表。
* @note 候选 LookupTable 必须已包含范围、色带、比例和越界颜色;失败时
* 原输入、Mapper 和活动 LookupTable 均保持不变。
*/
bool setInputConnection(vtkAlgorithmOutput* pInputConnection,
const QString& sArrayName,
ScalarAssociation eAssociation,
vtkLookupTable* pCandidateLookupTable);
/** @brief 解除直接数据或管线连接,并清除当前标量选择。 */
void clearInput();
/** @brief 返回当前直接数据或管线输出数据集的非所有权指针。 */
vtkDataSet* getDataSet() const;
/** @brief 设置表面或表面加边线显示模式。 */
void setDisplayMode(DisplayMode eMode);
/** @brief 返回当前显示模式。 */
DisplayMode getDisplayMode() const;
/** @brief 直接控制表面边线,供不暴露双显示模式的组合视图使用。 */
void setEdgeVisibility(bool bVisible);
bool isEdgeVisible() const;
/** @return 透明度为有限数时返回 true,并限制到 [0, 1]。 */
bool setOpacity(double dOpacity);
/** @brief 返回 Actor 当前透明度。 */
double getOpacity() const;
/** @brief 打开或关闭 Mapper 的标量着色。 */
void setScalarVisibility(bool bVisible);
/** @brief 返回 Mapper 当前是否启用标量着色。 */
bool isScalarVisible() const;
/**
* @brief 选择 CellData 或 PointData 数组作为标量来源。
* @return 数据集和指定数组存在,且自动范围有效时返回 true;失败时保留
* 原数组选择和 Mapper 状态。
*/
bool setScalarArray(const QString& sArrayName,
ScalarAssociation eAssociation);
/**
* @brief 原子提交当前输入的标量数组和显式显示范围。
* @return 数组和两个范围均有效时返回 true;失败时保留原 Mapper 状态。
*/
bool setScalarArray(const QString& sArrayName,
ScalarAssociation eAssociation,
double dMinimum,
double dMaximum);
/**
* @brief 原子提交当前输入的标量数组和完整候选颜色表。
* @return 数组和候选颜色表全部有效时返回 true;失败不修改活动状态。
*/
bool setScalarArray(const QString& sArrayName,
ScalarAssociation eAssociation,
vtkLookupTable* pCandidateLookupTable);
/** @brief 返回当前选中的数组名称。 */
QString getScalarArrayName() const;
/** @brief 返回当前数组来自 CellData 还是 PointData。 */
ScalarAssociation getScalarAssociation() const;
/** @brief 设置显式标量范围;不读取数据集。 */
bool setScalarRange(double dMinimum, double dMaximum);
/** @brief 从当前选中数组恢复数据范围。 */
bool restoreDataScalarRange();
/** @brief 返回当前范围是否由调用方显式指定。 */
bool isUsingExplicitScalarRange() const;
/**
* @brief 原子替换当前标量数组使用的完整颜色表。
* @note 成功后 Mapper 与外部 ScalarBar 可以共享同一对象;不主动 Render。
*/
bool setLookupTable(vtkLookupTable* pCandidateLookupTable);
/** 以下访问函数均返回图层持有对象的非所有权指针。 */
vtkDataSetMapper* getMapper() const;
vtkActor* getActor() const;
vtkLookupTable* getLookupTable() const;
private:
Q_DISABLE_COPY(nmVTKMeshLayer)
/** @brief 解析直接输入或当前管线输出;按需先更新上游 Producer。 */
vtkDataSet* getInputDataSet(bool bUpdatePipeline) const;
/** @brief 在不修改 Mapper 的前提下校验候选数据及保留的标量选择。 */
bool validateInputDataSet(vtkDataSet* pDataSet,
double dScalarRange[2]) const;
/** @brief 查询指定关联中的数组,并验证其实际数据范围为有限值。 */
vtkDataArray* validateScalarArray(vtkDataSet* pDataSet,
const QByteArray& aArrayName,
ScalarAssociation eAssociation,
double dDataRange[2]) const;
/** @brief 校验候选颜色表的表项、有限范围及 Log10 正下限。 */
bool validateLookupTable(vtkLookupTable* pLookupTable,
double dRange[2]) const;
/** @brief 提交已经完整验证的数组选择和范围;本函数内部没有失败分支。 */
void applyExplicitScalarState(const QByteArray& aArrayName,
ScalarAssociation eAssociation,
double dMinimum,
double dMaximum);
/** @brief 提交已验证的数组选择和候选颜色表;内部没有失败分支。 */
void applyLookupTableScalarState(const QByteArray& aArrayName,
ScalarAssociation eAssociation,
vtkLookupTable* pLookupTable,
const double dRange[2]);
/** @brief 对新输入重新应用已经验证的标量模式、名称和自动范围。 */
void applyRetainedScalarState(const double dScalarRange[2]);
/** @brief 从当前数据集解析已记录的数组选择。 */
vtkDataArray* getSelectedScalarArray() const;
/** @brief 校验数组范围并同步到 Mapper 和 LookupTable。 */
bool applyDataScalarRange();
/** @brief 清除失效数组选择、关闭标量着色并恢复默认范围。 */
void clearInvalidScalarState();
vtkSmartPointer<vtkDataSet> m_pDataSet; ///< 共享输入数据,不执行深拷贝。
vtkSmartPointer<vtkAlgorithmOutput> m_pInputConnection; ///< 共享管线输出端口。
vtkSmartPointer<vtkDataSetMapper> m_pMapper; ///< 图层独占的映射器。
vtkSmartPointer<vtkActor> m_pActor; ///< 图层主 Prop,由基类同步持有。
vtkSmartPointer<vtkLookupTable> m_pLookupTable; ///< 图层独占的颜色表。
DisplayMode m_eDisplayMode;
ScalarAssociation m_eScalarAssociation;
QByteArray m_aScalarArrayName; ///< 供 VTK 7.1 接口使用的 UTF-8 数组名。
bool m_bUsingExplicitScalarRange; ///< 为 true 时更换数据不覆盖调用方范围。
};
#endif // NMVTKMESHLAYER_H