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

#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