#ifndef PST_WIDGETCUTTER_H #define PST_WIDGETCUTTER_H #include #include #include #include #include #include #include class vtkDataArray; class vtkDoubleArray; class vtkCutter; class vtkActor; class vtkPlane; class vtkPlanes; class vtkDataSet; class vtkPolyDataMapper; class vtkProperty; class vtkLookupTable; class vtkScalarBarActor; class vtkRenderWindowInteractor; class vtkScalarBarWidget; /** * @class PlaneCutter * @brief 设置一个cutter来切割标量场(只显示切面数据,不更改源数据)。 * 目前包括box和plane两种widget。按i键可以激活/取消激活widget。 * 默认激活plane. 目前一个类只能实现一个切片,即plane和box都生成同一个actor. */ namespace pst { class vtkWidgetCall : public vtkCommand { public: static vtkWidgetCall* New() { return new vtkWidgetCall; } public: enum class CallbackWidgetType { BOX, PLANE, }; public: void SetCallbackWidgetType(CallbackWidgetType type) { m_currentWidgetType = type; } virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData) { switch (m_currentWidgetType) { case CallbackWidgetType::BOX: { vtkBoxWidget* widget = vtkBoxWidget::SafeDownCast(caller); widget->GetPlanes(m_planes); break; } case CallbackWidgetType::PLANE: { vtkPlaneWidget* pWidget = vtkPlaneWidget::SafeDownCast(caller); pWidget->GetPlane(m_singlePlane); break; } default: break; } } public: CallbackWidgetType m_currentWidgetType; vtkPlane* m_singlePlane; vtkPlanes* m_planes; }; class WidgetCutter { public: WidgetCutter(); public: enum class WidgetType { BOX, PLANE, }; //平面cutter 平面法向朝向 enum class PlaneNormalDirection { X, Y, Z, }; enum class PlaneRepresentation { // OUTLINE, WIREFRAME, SURFACE, POINTS, }; enum class StructureType { POINTS, CELLS }; struct ArrayInformation { int arrayIndex; QString arrayName; int arrayComponent; }; public: void SetInteractor(vtkRenderWindowInteractor* iren); void SetInputData(vtkDataSet* dataSet); //获取输入数据的属性表points下标及其对应的数据名称 std::vector GetPointsArrayIndexAndNames(); //获取输入数据属性表cells下标及其对应的数据名称 std::vector GetCellsArrayIndexAndNames(); bool SetActiveScalarAttribute(int index, const StructureType type, const int compIndex = -1); //默认使用plane widget void SetWidgetType(WidgetType type); //plane widget控制方法 void SetPlaneNormalDirection(PlaneNormalDirection direction); vtkProperty* GetWidgetPlaneProperty(); vtkProperty* GetWidgetHandelProperty(); vtkPlaneWidget* GetPlaneWidget(); vtkBoxWidget* GetBoxWidget(); void SetRepresentationType(PlaneRepresentation type); void SetCenter(double x[3]); void TurnAllWidgetOff(); void TurnWidgetOn(); void Update(); void refreshWidget(); vtkCutter* GetCutter(); vtkPolyDataMapper* GetMapper(); vtkActor* GetCutterActor(); //lookupTable void SetScalarBarRange(const double min, const double max); bool SetScalarBarRangeToAuto(); void SetLookupTable(vtkLookupTable* lookupTable); vtkLookupTable* GetLookupTable(); //scalarBar void SetScalarBarTitle(const std::string& title); void SetScalarBarNumberOfLabel(const int num); void SetScalarBarDisplayPosition(const int x, const int y); vtkScalarBarActor* GetScalarBar(); //data outline actor void SetDataOutlineActorColor(const double r, const double g, const double b); vtkActor* GetDataOutlineActor(); //保存cutter的数据时,只保留指定的场数据 //useOrigianl为真时,直接保留和原数据对应的所有场,此时后面两个参数不起作用 //当useOrigianl为假时,使用用户指定的场 void SelectFieldsToSaveForCutter(bool useOrigianl, const std::vector& selectedPointsFiled = std::vector(), const std::vector& selectedCellsFiled = std::vector()); //直接将裁剪数据写入本地 void WriteTheCutterData(const std::string& fileName); //重置widget位置为图像中心 void ResetCurrentWidgetPositon(); private: void InitPipeLine(); void InitLookupTable(); void GenerateDataOutlineBox(); //提取每个属性的单个分量,最初设计目的是 用于将含有多个成分的属性(如三个组分的数据)设置为标量场属性时, //提取其中一个单独的组分作为显示。component为-1时,返回magnitude。 bool GetSingleComponent(vtkDataArray* array, const int component, vtkDoubleArray* returnArray); //获取属性表points单元下标及其对应的数据名称 std::vector GetPointsArrayIndexAndNames(vtkDataSet* data); //获取属性表cells单元下标及其对应的数据名称 std::vector GetCellsArrayIndexAndNames(vtkDataSet* data); void SelectArrayFromCutterData(const std::vector& selectedPointsFiled, const std::vector& selectedCellsFiled); private: // vtkDataSet* m_inputData{nullptr}; //输入数据,会随选择的矢量分量更改其内容 vtkSmartPointer m_inputData; //原输入数据备份,用作获取切片数据用 vtkSmartPointer m_inputDataOriginal; vtkSmartPointer m_planeWidget; vtkSmartPointer m_plane; vtkSmartPointer m_boxWidget; vtkSmartPointer m_planes; vtkSmartPointer m_cutter; vtkSmartPointer m_selectedDataMapper; vtkSmartPointer m_cutterDataActor; vtkSmartPointer m_cutterWidgetCall; vtkSmartPointer m_lookupTable; vtkSmartPointer m_scalarBarWidget; vtkSmartPointer m_scalarBarActor; vtkSmartPointer m_dataOutlineActor; vtkSmartPointer m_interactor; vtkSmartPointer m_cutterDataToSave; WidgetType m_currentWidgetType; int m_currentAddedPointArrayIndex; //设置标量场属性,当多组分array的一个分类被添加后,下次设置时,用于移除。 int m_currentAddedCellArrayIndex; //设置标量场属性,当多组分array的一个分类被添加后,下次设置时,用于移除。 bool m_isScalarAttributeSet;//是否设置了用于颜色渲染的标量场 std::array m_currentArrayRange; //当前设置的标量场数值范围 }; } //namespace pst #endif // PST_WIDGETCUTTER_H