728 lines
24 KiB
C++
728 lines
24 KiB
C++
#include "WidgetCutter.h"
|
||
#include <vtkCellData.h>
|
||
#include <vtkPointData.h>
|
||
#include <vtkDataSet.h>
|
||
#include <vtkOutlineFilter.h>
|
||
#include <vtkScalarBarRepresentation.h>
|
||
#include <vtkPolyDataWriter.h>
|
||
#include <vtkCutter.h>
|
||
#include <vtkActor.h>
|
||
#include <vtkPlane.h>
|
||
#include <vtkPlanes.h>
|
||
#include <vtkPolyDataMapper.h>
|
||
#include <vtkProperty.h>
|
||
#include <vtkLookupTable.h>
|
||
#include <vtkScalarBarWidget.h>
|
||
#include <vtkScalarBarActor.h>
|
||
#include <vtkRenderWindowInteractor.h>
|
||
#include <vtkDoubleArray.h>
|
||
|
||
namespace pst
|
||
{
|
||
|
||
WidgetCutter::WidgetCutter()
|
||
: m_inputData(vtkSmartPointer<vtkPolyData>::New())
|
||
, m_inputDataOriginal(vtkSmartPointer<vtkPolyData>::New())
|
||
, m_planeWidget(vtkSmartPointer<vtkPlaneWidget>::New())
|
||
, m_plane(vtkSmartPointer<vtkPlane>::New())
|
||
, m_boxWidget(vtkSmartPointer<vtkBoxWidget>::New())
|
||
, m_planes(vtkSmartPointer<vtkPlanes>::New())
|
||
, m_cutter(vtkSmartPointer<vtkCutter>::New())
|
||
, m_selectedDataMapper(vtkSmartPointer<vtkPolyDataMapper>::New())
|
||
, m_cutterDataActor(vtkSmartPointer<vtkActor>::New())
|
||
, m_cutterWidgetCall(vtkSmartPointer<vtkWidgetCall>::New())
|
||
, m_lookupTable(vtkSmartPointer<vtkLookupTable>::New())
|
||
, m_scalarBarWidget(vtkSmartPointer<vtkScalarBarWidget>::New())
|
||
, m_scalarBarActor(vtkSmartPointer<vtkScalarBarActor>::New())
|
||
, m_dataOutlineActor(vtkSmartPointer<vtkActor>::New())
|
||
, m_interactor(vtkSmartPointer<vtkRenderWindowInteractor>::New())
|
||
, m_cutterDataToSave(vtkSmartPointer<vtkPolyData>::New())
|
||
, m_currentWidgetType(WidgetType::PLANE)
|
||
, m_currentAddedPointArrayIndex{ -1 }
|
||
, m_currentAddedCellArrayIndex{ -1 }
|
||
, m_isScalarAttributeSet{ false }
|
||
, m_currentArrayRange{ 0,11 }
|
||
{
|
||
InitLookupTable();
|
||
InitPipeLine();
|
||
}
|
||
|
||
void WidgetCutter::SetInteractor(vtkRenderWindowInteractor* iren)
|
||
{
|
||
m_planeWidget->SetInteractor(iren);
|
||
m_boxWidget->SetInteractor(iren);
|
||
m_scalarBarWidget->SetInteractor(iren);
|
||
|
||
m_interactor = iren;
|
||
}
|
||
|
||
void WidgetCutter::SetInputData(vtkDataSet* dataSet)
|
||
{
|
||
m_inputData = dataSet;
|
||
m_inputDataOriginal->DeepCopy(dataSet);
|
||
}
|
||
|
||
std::vector<WidgetCutter::ArrayInformation>
|
||
WidgetCutter::GetPointsArrayIndexAndNames()
|
||
{
|
||
return GetPointsArrayIndexAndNames(m_inputDataOriginal);
|
||
}
|
||
|
||
std::vector<WidgetCutter::ArrayInformation>
|
||
WidgetCutter::GetCellsArrayIndexAndNames()
|
||
{
|
||
return GetCellsArrayIndexAndNames(m_inputDataOriginal);
|
||
}
|
||
|
||
bool WidgetCutter::SetActiveScalarAttribute(int index,
|
||
const StructureType type, const int compIndex)
|
||
{
|
||
auto polyData = vtkPointSet::SafeDownCast(m_inputData);
|
||
//移除上次额外添加的数组
|
||
polyData->GetPointData()->RemoveArray(m_currentAddedPointArrayIndex);
|
||
polyData->GetCellData()->RemoveArray(m_currentAddedCellArrayIndex);
|
||
|
||
switch (type)
|
||
{
|
||
case StructureType::POINTS:
|
||
{
|
||
if (index >= m_inputData->GetPointData()->GetNumberOfArrays() || index < -1)
|
||
{
|
||
std::cout << "Error! Index illegal!" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
auto activeScalarArray = m_inputData->GetPointData()->GetArray(index);
|
||
const auto nComponents = activeScalarArray->GetNumberOfComponents();
|
||
|
||
auto time1 = clock();
|
||
//单组分array,忽略组分提取,直接设置
|
||
if (nComponents == 1)
|
||
{
|
||
m_inputData->GetPointData()->SetActiveAttribute(
|
||
index, vtkDataSetAttributes::AttributeTypes::SCALARS);
|
||
m_lookupTable->SetTableRange(activeScalarArray->GetRange());
|
||
m_currentArrayRange[0] = activeScalarArray->GetRange()[0];
|
||
m_currentArrayRange[1] = activeScalarArray->GetRange()[1];
|
||
}
|
||
else
|
||
{
|
||
if (compIndex < -1 || compIndex >= nComponents)
|
||
{
|
||
std::cout << "Error! Extracting component index is " << compIndex
|
||
<< ", current array component is " << nComponents << std::endl;
|
||
return false;
|
||
}
|
||
|
||
vtkNew<vtkDoubleArray> magArray;
|
||
bool isSuccess = GetSingleComponent(activeScalarArray, compIndex, magArray);
|
||
if (!isSuccess)
|
||
{
|
||
std::cout << "Extract component failed!" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
m_currentAddedPointArrayIndex = polyData->GetPointData()->AddArray(magArray);
|
||
m_inputData->GetPointData()->SetActiveAttribute(
|
||
m_currentAddedPointArrayIndex, vtkDataSetAttributes::AttributeTypes::SCALARS);
|
||
m_lookupTable->SetTableRange(magArray->GetRange());
|
||
m_currentArrayRange[0] = magArray->GetRange()[0];
|
||
m_currentArrayRange[1] = magArray->GetRange()[1];
|
||
}
|
||
auto time2 = clock();
|
||
std::cout << "Add scalar time = " << time2 - time1 << std::endl;
|
||
m_selectedDataMapper->SetScalarModeToUsePointData();
|
||
break;
|
||
}
|
||
|
||
case StructureType::CELLS:
|
||
{
|
||
if (index >= m_inputData->GetCellData()->GetNumberOfArrays() || index < 0)
|
||
{
|
||
std::cout << "Error! Index illegal!" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
|
||
auto activeScalarArray = m_inputData->GetCellData()->GetArray(index);
|
||
const auto nComponents = activeScalarArray->GetNumberOfComponents();
|
||
|
||
auto time1 = clock();
|
||
//单组分array,忽略组分提取,直接设置
|
||
if (nComponents == 1)
|
||
{
|
||
m_inputData->GetCellData()->SetActiveAttribute(
|
||
index, vtkDataSetAttributes::AttributeTypes::SCALARS);
|
||
m_lookupTable->SetTableRange(activeScalarArray->GetRange());
|
||
m_currentArrayRange[0] = activeScalarArray->GetRange()[0];
|
||
m_currentArrayRange[1] = activeScalarArray->GetRange()[1];
|
||
}
|
||
else
|
||
{
|
||
if (compIndex < -1 || compIndex >= nComponents)
|
||
{
|
||
std::cout << "Error! Extracting component index is " << compIndex
|
||
<< ", current array component is " << nComponents << std::endl;
|
||
return false;
|
||
}
|
||
|
||
vtkNew<vtkDoubleArray> magArray;
|
||
bool isSuccess = GetSingleComponent(activeScalarArray, compIndex, magArray);
|
||
if (!isSuccess)
|
||
{
|
||
std::cout << "Extract component failed!" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
m_currentAddedCellArrayIndex = polyData->GetCellData()->AddArray(magArray);
|
||
std::cout << "indexxxxx = " << m_currentAddedCellArrayIndex << std::endl;
|
||
m_inputData->GetCellData()->SetActiveAttribute(
|
||
m_currentAddedCellArrayIndex, vtkDataSetAttributes::AttributeTypes::SCALARS);
|
||
m_lookupTable->SetTableRange(magArray->GetRange());
|
||
m_currentArrayRange[0] = magArray->GetRange()[0];
|
||
m_currentArrayRange[1] = magArray->GetRange()[1];
|
||
}
|
||
auto time2 = clock();
|
||
std::cout << "Add scalar time = " << time2 - time1 << std::endl;
|
||
m_selectedDataMapper->SetScalarModeToUseCellData();
|
||
// m_currentUsingScalarType = StructureType::CELLS;
|
||
break;
|
||
}
|
||
|
||
default:
|
||
std::cout << "Wrong structure type" << std::endl;
|
||
return false;
|
||
break;
|
||
}
|
||
m_isScalarAttributeSet = true;
|
||
return true;
|
||
}
|
||
|
||
void WidgetCutter::SetWidgetType(WidgetType type)
|
||
{
|
||
m_currentWidgetType = type;
|
||
}
|
||
|
||
void WidgetCutter::SetPlaneNormalDirection(PlaneNormalDirection direction)
|
||
{
|
||
//PlaceWidget必须先于SetNormal调用,但似乎该函数并无效果。
|
||
// m_planeWidget->PlaceWidget(m_inputData->GetBounds());
|
||
switch (direction)
|
||
{
|
||
case PlaneNormalDirection::X:
|
||
{
|
||
m_planeWidget->SetNormal(1, 0, 0);
|
||
m_plane->SetNormal(1, 0, 0);
|
||
break;
|
||
}
|
||
case PlaneNormalDirection::Y:
|
||
{
|
||
m_planeWidget->SetNormal(0, 1, 0);
|
||
m_plane->SetNormal(0, 1, 0);
|
||
break;
|
||
}
|
||
case PlaneNormalDirection::Z:
|
||
{
|
||
m_planeWidget->SetNormal(0, 0, 1);
|
||
m_plane->SetNormal(0, 0, 1);
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void WidgetCutter::SetRepresentationType(PlaneRepresentation type)
|
||
{
|
||
switch (type)
|
||
{
|
||
// case PlaneRepresentation::OUTLINE:
|
||
// {
|
||
//// m_planeWidget->SetRepresentationToOutline();
|
||
// m_cutterDataActor->GetProperty()->SetRepresentationToPoints();
|
||
// break;
|
||
// }
|
||
case PlaneRepresentation::WIREFRAME:
|
||
{
|
||
// m_planeWidget->SetRepresentationToWireframe();
|
||
m_cutterDataActor->GetProperty()->SetRepresentationToWireframe();
|
||
break;
|
||
}
|
||
case PlaneRepresentation::SURFACE:
|
||
{
|
||
// m_planeWidget->SetRepresentationToSurface();
|
||
m_cutterDataActor->GetProperty()->SetRepresentationToSurface();
|
||
break;
|
||
}
|
||
case PlaneRepresentation::POINTS:
|
||
{
|
||
m_cutterDataActor->GetProperty()->SetRepresentationToPoints();
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void WidgetCutter::SetCenter(double x[3])
|
||
{
|
||
m_planeWidget->SetCenter(x);
|
||
m_plane->SetOrigin(x);
|
||
}
|
||
|
||
void WidgetCutter::TurnAllWidgetOff()
|
||
{
|
||
if (m_planeWidget->GetInteractor())
|
||
{
|
||
m_planeWidget->Off();
|
||
}
|
||
if (m_boxWidget->GetInteractor())
|
||
{
|
||
m_boxWidget->Off();
|
||
}
|
||
}
|
||
|
||
void WidgetCutter::TurnWidgetOn()
|
||
{
|
||
switch (m_currentWidgetType)
|
||
{
|
||
case WidgetType::BOX:
|
||
m_boxWidget->On();
|
||
break;
|
||
case WidgetType::PLANE:
|
||
m_planeWidget->On();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void WidgetCutter::Update()
|
||
{
|
||
m_boxWidget->SetInputData(m_inputData);
|
||
m_boxWidget->PlaceWidget(m_inputData->GetBounds());
|
||
m_planes->SetBounds(m_inputData->GetBounds());
|
||
|
||
//默认开启plane
|
||
m_planeWidget->SetInputData(m_inputData);
|
||
m_planeWidget->PlaceWidget(m_inputData->GetBounds());
|
||
m_planeWidget->On();
|
||
m_cutterWidgetCall->SetCallbackWidgetType(vtkWidgetCall::CallbackWidgetType::PLANE);
|
||
|
||
m_cutter->SetCutFunction(m_plane);
|
||
m_cutter->SetInputData(m_inputData);
|
||
m_cutter->Update();
|
||
|
||
m_selectedDataMapper->Update();
|
||
|
||
m_scalarBarWidget->SetScalarBarActor(m_scalarBarActor);
|
||
// m_scalarBarWidget->SetResizable(true);
|
||
|
||
vtkScalarBarRepresentation* rep =
|
||
vtkScalarBarRepresentation::SafeDownCast(m_scalarBarWidget->GetRepresentation());
|
||
rep->SetPosition2(0.05, 0.7);
|
||
rep->SetPosition(0.01, 0.1);
|
||
m_scalarBarWidget->On();
|
||
|
||
GenerateDataOutlineBox();
|
||
}
|
||
|
||
void WidgetCutter::refreshWidget()
|
||
{
|
||
switch (m_currentWidgetType)
|
||
{
|
||
//将widget的interactor置空SetInteractor(NULL)
|
||
//是为了能让每个widget都能响应键盘事件,否则其只响应最早设置interactor的widget
|
||
case WidgetType::BOX:
|
||
{
|
||
m_planeWidget->Off();
|
||
m_planeWidget->SetInteractor(nullptr);
|
||
|
||
m_boxWidget->SetInteractor(m_interactor);
|
||
m_boxWidget->On();
|
||
|
||
//置空再设置是为了让interactor优先响应m_boxWidget键盘事件
|
||
m_scalarBarWidget->SetInteractor(nullptr);
|
||
m_scalarBarWidget->SetInteractor(m_interactor);
|
||
m_scalarBarWidget->On();
|
||
|
||
m_cutter->SetCutFunction(m_planes);
|
||
m_cutterWidgetCall->SetCallbackWidgetType(vtkWidgetCall::CallbackWidgetType::BOX);
|
||
m_cutterWidgetCall->Execute(m_boxWidget, 0, nullptr);
|
||
break;
|
||
}
|
||
case WidgetType::PLANE:
|
||
{
|
||
m_boxWidget->Off();
|
||
m_boxWidget->SetInteractor(nullptr);
|
||
|
||
m_planeWidget->SetInteractor(m_interactor);
|
||
m_planeWidget->On();
|
||
|
||
//置空再设置是为了让interactor优先响应m_planeWidget键盘事件
|
||
m_scalarBarWidget->SetInteractor(nullptr);
|
||
m_scalarBarWidget->SetInteractor(m_interactor);
|
||
m_scalarBarWidget->On();
|
||
|
||
m_cutter->SetCutFunction(m_plane);
|
||
m_cutterWidgetCall->SetCallbackWidgetType(vtkWidgetCall::CallbackWidgetType::PLANE);
|
||
m_cutterWidgetCall->Execute(m_planeWidget, 0, nullptr);
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
vtkProperty* WidgetCutter::GetWidgetPlaneProperty()
|
||
{
|
||
return m_planeWidget->GetPlaneProperty();
|
||
}
|
||
|
||
vtkProperty* WidgetCutter::GetWidgetHandelProperty()
|
||
{
|
||
return m_planeWidget->GetHandleProperty();
|
||
}
|
||
|
||
vtkPlaneWidget* WidgetCutter::GetPlaneWidget()
|
||
{
|
||
return m_planeWidget;
|
||
}
|
||
|
||
vtkBoxWidget* WidgetCutter::GetBoxWidget()
|
||
{
|
||
return m_boxWidget;
|
||
}
|
||
|
||
vtkCutter* WidgetCutter::GetCutter()
|
||
{
|
||
return m_cutter;
|
||
}
|
||
|
||
vtkPolyDataMapper* WidgetCutter::GetMapper()
|
||
{
|
||
return m_selectedDataMapper;
|
||
}
|
||
|
||
vtkActor* WidgetCutter::GetCutterActor()
|
||
{
|
||
return m_cutterDataActor;
|
||
}
|
||
|
||
bool WidgetCutter::SetScalarBarRangeToAuto()
|
||
{
|
||
if (!m_isScalarAttributeSet)
|
||
{
|
||
std::cout << "Error, scalars attribute must be set !" << std::endl;
|
||
return false;
|
||
}
|
||
m_lookupTable->SetTableRange(m_currentArrayRange[0], m_currentArrayRange[1]);
|
||
return true;
|
||
}
|
||
|
||
void WidgetCutter::SetScalarBarRange(const double min, const double max)
|
||
{
|
||
m_lookupTable->SetTableRange(min, max);
|
||
}
|
||
|
||
void WidgetCutter::SetScalarBarTitle(const std::string& title)
|
||
{
|
||
m_scalarBarActor->SetTitle(title.c_str());
|
||
}
|
||
|
||
void WidgetCutter::SetScalarBarNumberOfLabel(const int num)
|
||
{
|
||
m_scalarBarActor->SetNumberOfLabels(num);
|
||
}
|
||
|
||
void WidgetCutter::SetScalarBarDisplayPosition(const int x, const int y)
|
||
{
|
||
m_scalarBarActor->SetDisplayPosition(x, y);
|
||
}
|
||
|
||
vtkScalarBarActor* WidgetCutter::GetScalarBar()
|
||
{
|
||
return m_scalarBarActor;
|
||
}
|
||
|
||
void WidgetCutter::SetDataOutlineActorColor(const double r, const double g, const double b)
|
||
{
|
||
m_dataOutlineActor->GetProperty()->SetColor(r, g, b);
|
||
}
|
||
|
||
vtkActor* WidgetCutter::GetDataOutlineActor()
|
||
{
|
||
return m_dataOutlineActor;
|
||
}
|
||
|
||
void WidgetCutter::WriteTheCutterData(const std::string& fileName)
|
||
{
|
||
vtkNew<vtkPolyDataWriter> writer;
|
||
writer->SetInputData(m_cutterDataToSave);
|
||
writer->SetFileName(fileName.c_str());
|
||
try
|
||
{
|
||
writer->Update();
|
||
}
|
||
catch (const std::exception& e)
|
||
{
|
||
std::cout << e.what() << std::endl;
|
||
}
|
||
}
|
||
|
||
void WidgetCutter::ResetCurrentWidgetPositon()
|
||
{
|
||
switch (m_currentWidgetType)
|
||
{
|
||
case WidgetType::BOX:
|
||
m_boxWidget->PlaceWidget(m_inputData->GetBounds());
|
||
break;
|
||
case WidgetType::PLANE:
|
||
m_planeWidget->SetCenter(m_inputData->GetCenter());
|
||
m_planeWidget->PlaceWidget(m_inputData->GetBounds());
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
vtkLookupTable* WidgetCutter::GetLookupTable()
|
||
{
|
||
return m_lookupTable;
|
||
}
|
||
|
||
void WidgetCutter::SetLookupTable(vtkLookupTable* lookupTable)
|
||
{
|
||
m_lookupTable = lookupTable;
|
||
}
|
||
|
||
void WidgetCutter::InitPipeLine()
|
||
{
|
||
m_planeWidget->SetResolution(10);
|
||
m_planeWidget->SetHandleSize(0.001);
|
||
m_planeWidget->SetPlaceFactor(0.1);
|
||
m_planeWidget->GetPlaneProperty()->SetColor(.9, .4, .4);
|
||
m_planeWidget->GetPlaneProperty()->SetPointSize(2);
|
||
m_planeWidget->GetHandleProperty()->SetColor(0, .4, .7);
|
||
m_planeWidget->GetHandleProperty()->SetLineWidth(1.5);
|
||
m_planeWidget->SetRepresentationToOutline();
|
||
m_planeWidget->SetPlaceFactor(1);
|
||
|
||
m_boxWidget->SetPlaceFactor(1);
|
||
m_boxWidget->SetHandleSize(0.003);
|
||
m_boxWidget->SetPlaceFactor(1);
|
||
|
||
m_cutterWidgetCall->m_planes = m_planes;
|
||
|
||
|
||
|
||
m_scalarBarActor->SetTitle("Cutter");
|
||
m_scalarBarActor->SetLookupTable(m_lookupTable);
|
||
// m_scalarBarActor->SetDisplayPosition(10,10);
|
||
m_scalarBarActor->SetPosition(0.01, 0.1);
|
||
m_scalarBarActor->SetPosition2(0.05, 0.7);
|
||
m_cutterWidgetCall->m_singlePlane = m_plane;
|
||
m_planeWidget->AddObserver(vtkCommand::InteractionEvent, m_cutterWidgetCall);
|
||
m_boxWidget->AddObserver(vtkCommand::InteractionEvent, m_cutterWidgetCall);
|
||
|
||
m_selectedDataMapper->SetInterpolateScalarsBeforeMapping(true);
|
||
m_selectedDataMapper->SetColorModeToMapScalars();
|
||
m_selectedDataMapper->ScalarVisibilityOn();
|
||
m_selectedDataMapper->SetUseLookupTableScalarRange(1);
|
||
m_selectedDataMapper->SetInputConnection(m_cutter->GetOutputPort());
|
||
m_selectedDataMapper->SetLookupTable(m_lookupTable);
|
||
m_cutterDataActor->SetMapper(m_selectedDataMapper);
|
||
}
|
||
|
||
void WidgetCutter::InitLookupTable()
|
||
{
|
||
//色调范围从蓝色到红色
|
||
m_lookupTable->SetNumberOfColors(600);
|
||
m_lookupTable->SetHueRange(0.67, 0.0);
|
||
m_lookupTable->Build();
|
||
}
|
||
|
||
void WidgetCutter::GenerateDataOutlineBox()
|
||
{
|
||
vtkNew<vtkOutlineFilter> outline;
|
||
outline->SetInputData(m_inputData);
|
||
vtkNew<vtkPolyDataMapper> outlineMapper;
|
||
outlineMapper->SetInputConnection(outline->GetOutputPort());
|
||
outlineMapper->Update();
|
||
m_dataOutlineActor->SetMapper(outlineMapper);
|
||
}
|
||
|
||
bool
|
||
WidgetCutter::GetSingleComponent(vtkDataArray* array,
|
||
const int componentIndex, vtkDoubleArray* returnArray)
|
||
{
|
||
|
||
auto nComponents = array->GetNumberOfComponents();
|
||
std::cout << " nComponents = " << nComponents << std::endl;
|
||
|
||
//检查下标合法性,-1代表取magnitude
|
||
if (componentIndex < -1 || componentIndex >= nComponents)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//取单个组分的属性的0组分,即返回自己
|
||
if (componentIndex == 0 && nComponents == 1)
|
||
{
|
||
returnArray->DeepCopy(vtkDoubleArray::SafeDownCast(array));
|
||
return true;
|
||
}
|
||
|
||
const auto nTuples = array->GetNumberOfTuples();
|
||
std::cout << " nTuples = " << nTuples << std::endl;
|
||
|
||
vtkNew<vtkDoubleArray> singleArray;
|
||
singleArray->SetNumberOfComponents(1);
|
||
singleArray->SetNumberOfTuples(nTuples);
|
||
|
||
//取magnitude
|
||
if (componentIndex == -1)
|
||
{
|
||
std::cout << "magnitude " << std::endl;
|
||
singleArray->SetName("Magnitude");
|
||
for (vtkIdType i = 0; i < nTuples; ++i)
|
||
{
|
||
double mag = 0;
|
||
for (int j = 0; j < nComponents; ++j)
|
||
{
|
||
double tmp = array->GetComponent(i, j);
|
||
mag += tmp * tmp;
|
||
}
|
||
mag = sqrt(mag);
|
||
singleArray->InsertTuple1(i, mag);
|
||
}
|
||
}
|
||
else //取现有的单个组件
|
||
{
|
||
std::cout << "extract comp = " << componentIndex << std::endl;
|
||
|
||
if (componentIndex == 0)
|
||
{
|
||
singleArray->SetName("X");
|
||
}
|
||
else if (componentIndex == 1)
|
||
{
|
||
singleArray->SetName("Y");
|
||
}
|
||
else if (componentIndex == 2)
|
||
{
|
||
singleArray->SetName("Z");
|
||
}
|
||
else
|
||
{
|
||
singleArray->SetName(std::to_string(componentIndex).c_str());
|
||
}
|
||
|
||
for (vtkIdType j = 0; j < nTuples; ++j)
|
||
{
|
||
singleArray->InsertTuple1(j, array->GetComponent(j, componentIndex));
|
||
}
|
||
}
|
||
returnArray->DeepCopy(singleArray);
|
||
return true;
|
||
}
|
||
|
||
void
|
||
WidgetCutter::SelectFieldsToSaveForCutter(bool useOrigianl,
|
||
const std::vector<ArrayInformation>& selectedPointsFiledId,
|
||
const std::vector<ArrayInformation>& selectedCellsFiledId)
|
||
{
|
||
m_cutterDataToSave->DeepCopy(m_cutter->GetOutput());
|
||
|
||
if (useOrigianl)
|
||
{
|
||
auto pointsInfoOriginal = GetPointsArrayIndexAndNames(m_inputDataOriginal);
|
||
auto cellsInfoOriginal = GetCellsArrayIndexAndNames(m_inputDataOriginal);
|
||
SelectArrayFromCutterData(pointsInfoOriginal, cellsInfoOriginal);
|
||
}
|
||
else
|
||
{
|
||
SelectArrayFromCutterData(selectedPointsFiledId, selectedCellsFiledId);
|
||
}
|
||
}
|
||
|
||
std::vector<WidgetCutter::ArrayInformation>
|
||
WidgetCutter::GetPointsArrayIndexAndNames(vtkDataSet* data)
|
||
{
|
||
std::vector<WidgetCutter::ArrayInformation> arrayInfoVector;
|
||
WidgetCutter::ArrayInformation tempInfo;
|
||
|
||
for (int i = 0; i < data->GetPointData()->GetNumberOfArrays(); ++i)
|
||
{
|
||
tempInfo.arrayIndex = i;
|
||
tempInfo.arrayName = data->GetPointData()->GetArrayName(i);
|
||
tempInfo.arrayComponent = data->GetPointData()->GetArray(i)->GetNumberOfComponents();
|
||
arrayInfoVector.push_back(tempInfo);
|
||
}
|
||
return arrayInfoVector;
|
||
}
|
||
|
||
std::vector<WidgetCutter::ArrayInformation>
|
||
WidgetCutter::GetCellsArrayIndexAndNames(vtkDataSet* data)
|
||
{
|
||
std::vector<WidgetCutter::ArrayInformation> arrayInfoVector;
|
||
WidgetCutter::ArrayInformation tempInfo;
|
||
|
||
for (int i = 0; i < data->GetCellData()->GetNumberOfArrays(); ++i)
|
||
{
|
||
tempInfo.arrayIndex = i;
|
||
tempInfo.arrayName = data->GetCellData()->GetArrayName(i);
|
||
tempInfo.arrayComponent = data->GetCellData()->GetArray(i)->GetNumberOfComponents();
|
||
arrayInfoVector.push_back(tempInfo);
|
||
}
|
||
return arrayInfoVector;
|
||
}
|
||
|
||
void WidgetCutter::SelectArrayFromCutterData(
|
||
const std::vector<ArrayInformation>& selectedPointsFiled,
|
||
const std::vector<ArrayInformation>& selectedCellsFiled)
|
||
{
|
||
auto pointsInfoCutter = GetPointsArrayIndexAndNames(m_cutterDataToSave);
|
||
auto cellsInfoCutter = GetCellsArrayIndexAndNames(m_cutterDataToSave);
|
||
|
||
for (int i = 0; i < pointsInfoCutter.size(); ++i)
|
||
{
|
||
for (int j = 0; j < selectedPointsFiled.size(); ++j)
|
||
{
|
||
//在其中,需要保留
|
||
if (pointsInfoCutter[i].arrayIndex == selectedPointsFiled[j].arrayIndex)
|
||
{
|
||
break;
|
||
}
|
||
//没找到,不在其中,移除多余列
|
||
if (j == selectedPointsFiled.size() - 1)
|
||
{
|
||
m_cutterDataToSave->GetPointData()->RemoveArray(pointsInfoCutter[i].arrayIndex);
|
||
}
|
||
}
|
||
}
|
||
|
||
for (int i = 0; i < cellsInfoCutter.size(); ++i)
|
||
{
|
||
for (int j = 0; j < selectedCellsFiled.size(); ++j)
|
||
{
|
||
//在其中,需要保留
|
||
if (cellsInfoCutter[i].arrayIndex == selectedCellsFiled[j].arrayIndex)
|
||
{
|
||
break;
|
||
}
|
||
if (j == selectedCellsFiled.size() - 1)
|
||
{
|
||
m_cutterDataToSave->GetCellData()->RemoveArray(cellsInfoCutter[i].arrayIndex);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|