#ifndef NMPEBIREGIONPRESSURECALCULATOR_H #define NMPEBIREGIONPRESSURECALCULATOR_H #include "nmData_global.h" #include #include #include #include #include class nmPebiRegionPressureCalculatorPrivate; class nmPebiResultSnapshot; /** * @brief 一帧区域压力的孔隙体积加权统计结果。 * * 压力使用快照基础单位 MPa;面积和孔隙体积的单位分别为 m2 和 m3。 * m_bAvailable 为 false 时,计数仍可用于解释没有有效加权结果的原因。 */ struct NM_DATA_EXPORT nmPebiRegionPressureStatistics { /** @brief 初始化为空且不可用的统计结果。 */ nmPebiRegionPressureStatistics(); /** @brief 清除所有计数和值,使对象恢复到默认状态。 */ void clear(); bool m_bAvailable; ///< 是否存在至少一个可用于压力加权的有效单元。 int m_nPressureFrameIndex; ///< 本结果对应的零基压力帧。 double m_dPressureTimeHours; ///< 压力帧求解时间,单位 h。 vtkIdType m_nIntersectingCellCount; ///< 与选区存在正面积交叠的二维单元数。 vtkIdType m_nValidCellCount; ///< 实际参与本帧压力统计的单元数。 vtkIdType m_nIgnoredCellCount; ///< 因权重或压力无效而忽略的相交单元数。 double m_dSelectedCellAreaSquareMeters; ///< 相交单元完整面积之和,单位 m2。 double m_dEffectivePoreVolumeCubicMeters; ///< 有效单元孔隙体积之和,单位 m3。 double m_dMinimumPressureMpa; ///< 有效单元最小压力,单位 MPa。 double m_dMaximumPressureMpa; ///< 有效单元最大压力,单位 MPa。 double m_dPoreVolumeWeightedPressureMpa; ///< 孔隙体积加权压力,单位 MPa。 }; /** * @brief 在不可变 PEBI 快照上准备区域并逐帧计算压力统计。 * * 准备阶段基于基础网格执行真实二维多边形相交判定;只要交叠面积为正, * 整个单元即被选中。相交基础 Cell ID、完整面积和 A*h*phi 权重会被缓存, * 后续切帧只读取已缓存单元的压力,不依赖 Mapper 或显示筛选管线。 */ class NM_DATA_EXPORT nmPebiRegionPressureCalculator { public: /** @brief 创建尚未绑定快照和区域的计算器。 */ nmPebiRegionPressureCalculator(); /** @brief 释放快照强引用和全部区域缓存。 */ ~nmPebiRegionPressureCalculator(); /** * @brief 事务式准备一份简单二维多边形选区。 * @param pSnapshot 只读结果快照,成功后由计算器保持强引用。 * @param vecPolygonPoints 按边界顺序给出的 XY 世界坐标;首点无需重复。 * @note 非有限、退化或自相交多边形会失败并保留旧区域缓存。 */ bool prepare( const QSharedPointer& pSnapshot, const QVector& vecPolygonPoints, QString* pError = NULL); /** @brief 清除当前区域、快照引用和所有相交单元缓存。 */ void clear(); /** @brief 返回是否已经成功准备过一份快照区域。 */ bool isPrepared() const; /** @brief 返回当前区域所属快照 ID;未准备时为空。 */ QString getSnapshotId() const; /** @brief 返回规范化后的区域顶点,引用在下次 prepare 或 clear 前有效。 */ const QVector& getPolygonPoints() const; /** @brief 返回相交基础 VTK Cell ID,引用在下次 prepare 或 clear 前有效。 */ const QVector& getIntersectingCellIds() const; /** * @brief 使用缓存权重计算指定压力帧的最小、最大和加权平均值。 * @note 无相交单元或无有效权重属于成功的不可用结果,不返回伪造的零压力。 */ bool calculateFrame(int nPressureFrameIndex, nmPebiRegionPressureStatistics& oStatistics, QString* pError = NULL) const; private: Q_DISABLE_COPY(nmPebiRegionPressureCalculator) nmPebiRegionPressureCalculatorPrivate* m_pPrivate; ///< 独占区域缓存实现。 }; #endif // NMPEBIREGIONPRESSURECALCULATOR_H