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.
AppFlow/GUIWidget/PickedDataCalculator.cpp

224 lines
6.8 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.

#include "PickedDataCalculator.h"
// VTK
#include <vtkActor.h>
#include <vtkMapper.h>
#include <vtkPlanes.h>
// APP
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKKeyMouseStates.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
// Global data
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"
// Filter ( Algorithm )
#include "FITK_Interface/FITKVTKAlgorithm/FITKShellFeatureEdges.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKSurfaceFilter.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKExtractGeometry.h"
// Graph
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActor.h"
#include "FITK_Component/FITKFluidVTKGraphAdaptor/FITKFluidVTKCommons.h"
#include "FITK_Component/FITKFluidVTKGraphAdaptor/FITKFluidVTKGraphObject3D.h"
// Pick
#include "PickedData.h"
namespace GraphData
{
PickedDataCalculator::PickedDataCalculator(GraphData::PickedData* pickedData) :
m_pickedData(pickedData)
{
}
void PickedDataCalculator::calculate()
{
if (!m_pickedData)
{
return;
}
// 点选拾取方式
//@{
if (m_pickedData->getPickedMouseType() == PickedMouseType::PickedMouseClick)
{
// 获取拾取时的方式。
GUI::GUIPickInfoStru pickInfo = m_pickedData->getPickedInfo();
switch (pickInfo._pickMethod)
{
case GUI::GUIPickInfo::PickMethod::PMIndividually:
case GUI::GUIPickInfo::PickMethod::PMSingle:
{
individually();
break;
}
default:
return;
}
}
//@}
// 框选拾取方式
//@{
else if (m_pickedData->getPickedMouseType() == PickedMouseType::PickedMouseRubber)
{
byAreaPick();
}
//@}
// 不管计算完成都将是否需要计算标识置为false。
m_pickedData->calculateFinsish();
// 排序。
m_pickedData->sortIds();
}
void PickedDataCalculator::individually()
{
Exchange::FITKFluidVTKGraphObject3D* gobj = m_pickedData->getPickedGraphObejct();
int index = m_pickedData->getPickedIndex();
if (!gobj || index < 0)
{
return;
}
int id = -1;
// 根据拾取数据类型进行不同数据获取。
switch (m_pickedData->getPickedDataType())
{
case PickedDataType::ModelVertPick:
// 查找点。
id = gobj->getShapeIdByVTKCellId(index, Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_VERTEX);
break;
case PickedDataType::ModelEdgePick:
// 查找线。
id = gobj->getShapeIdByVTKCellId(index, Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_EDGE);
break;
case PickedDataType::ModelFacePick:
// 查找面。
id = gobj->getShapeIdByVTKCellId(index, Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_FACE);
break;
case PickedDataType::ModelSolidPick:
// 查找体。
id = gobj->getShapeIdByVTKCellId(index, Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_SOLID);
break;
default:
return;
}
if (id == -1)
{
return;
}
m_pickedData->getPickedIds().push_back(id);
}
void PickedDataCalculator::byAreaPick()
{
Exchange::FITKFluidVTKGraphObject3D* gobj = m_pickedData->getPickedGraphObejct();
vtkPlanes* planes = m_pickedData->getCutPlane();
vtkActor* actor = m_pickedData->getPickedActor();
if (!gobj || !planes || !actor)
{
return;
}
// 获取拾取数据集。
vtkDataSet* dataSet = actor->GetMapper()->GetInputAsDataSet();
if (!dataSet)
{
return;
}
vtkSmartPointer<FITKExtractGeometry> extractor = vtkSmartPointer<FITKExtractGeometry>::New();
extractor->SetImplicitFunction(planes);
extractor->SetInputData(dataSet);
extractor->Update();
// 通过单元索引获取单元ID。
const QList<int> cellsIndice = extractor->getSelectOriginalCells();
if (cellsIndice.isEmpty())
{
return;
}
int len = 0;
Exchange::FITKFluidVTKCommons::ShapeAbsEnum sType;
// 根据拾取数据类型进行不同数据获取。
switch (m_pickedData->getPickedDataType())
{
case PickedDataType::ModelVertPick:
len = gobj->getNumberOf(Exchange::FITKFluidVTKCommons::ShapeType::ModelVertex);
sType = Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_VERTEX;
break;
case PickedDataType::ModelEdgePick:
len = gobj->getNumberOf(Exchange::FITKFluidVTKCommons::ShapeType::ModelEdge);
sType = Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_EDGE;
break;
case PickedDataType::ModelFacePick:
len = gobj->getNumberOf(Exchange::FITKFluidVTKCommons::ShapeType::ModelFace);
sType = Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_FACE;
break;
case PickedDataType::ModelSolidPick:
len = gobj->getNumberOf(Exchange::FITKFluidVTKCommons::ShapeType::ModelSolid);
sType = Exchange::FITKFluidVTKCommons::ShapeAbsEnum::STA_SOLID;
break;
default:
return;
}
if (len == 0)
{
return;
}
// 被拾取形状编号。
QVector<int> shapeIds;
// 预处理拾取单元数据。加速判断拾取子Id包含关系
int nCells = dataSet->GetNumberOfCells();
QVector<int> cellPickedFlags;
cellPickedFlags.resize(nCells);
cellPickedFlags.fill(0);
// 获取形状数据Id。
for (const int & index : cellsIndice)
{
int id = gobj->getShapeIdByVTKCellId(index, sType);
if (!shapeIds.contains(id))
{
shapeIds.push_back(id);
}
cellPickedFlags[index] = 1;
}
// 保存拾取数据。
for (int i = 0; i < shapeIds.count(); i++)
{
int & shapeId = shapeIds[i];
// 检测当前OCC数据是否完全被选中。
QVector<int> subIds = gobj->getVTKCellIdsByShapeId(shapeId, sType);
bool isFullPicked = true;
for (const int & id : subIds)
{
isFullPicked &= (cellPickedFlags[id] == 1);
}
// 完全选中则视为被框选。
if (isFullPicked)
{
m_pickedData->getPickedIds().push_back(shapeId);
}
}
shapeIds.clear();
}
}