|
|
|
|
|
#include "nmPebiResultWellAnnotationLayer.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmPebiResultSnapshot.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
|
#include <QSet>
|
|
|
|
|
|
#include <QThread>
|
|
|
|
|
|
|
|
|
|
|
|
#include <vtkActor2D.h>
|
|
|
|
|
|
#include <vtkCellArray.h>
|
|
|
|
|
|
#include <vtkCoordinate.h>
|
|
|
|
|
|
#include <vtkLabeledDataMapper.h>
|
|
|
|
|
|
#include <vtkMath.h>
|
|
|
|
|
|
#include <vtkPointData.h>
|
|
|
|
|
|
#include <vtkPoints.h>
|
|
|
|
|
|
#include <vtkPolyData.h>
|
|
|
|
|
|
#include <vtkPolyDataMapper2D.h>
|
|
|
|
|
|
#include <vtkPropAssembly.h>
|
|
|
|
|
|
#include <vtkProperty2D.h>
|
|
|
|
|
|
#include <vtkStringArray.h>
|
|
|
|
|
|
#include <vtkTextProperty.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
|
|
bool isWellAnnotationGuiThread()
|
|
|
|
|
|
{
|
|
|
|
|
|
QCoreApplication* pApplication = QCoreApplication::instance();
|
|
|
|
|
|
return pApplication == nullptr ||
|
|
|
|
|
|
pApplication->thread() == QThread::currentThread();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmPebiResultWellAnnotationLayer::nmPebiResultWellAnnotationLayer(
|
|
|
|
|
|
const QString& sLayerId)
|
|
|
|
|
|
: nmVTKRenderLayer(sLayerId),
|
|
|
|
|
|
m_pRootAssembly(vtkSmartPointer<vtkPropAssembly>::New()),
|
|
|
|
|
|
m_pActiveSnapshotAssembly(nullptr),
|
|
|
|
|
|
m_pActiveMarkerGroup(nullptr),
|
|
|
|
|
|
m_pActiveNameGroup(nullptr),
|
|
|
|
|
|
m_pCandidateSnapshotAssembly(nullptr),
|
|
|
|
|
|
m_pCandidateMarkerGroup(nullptr),
|
|
|
|
|
|
m_pCandidateNameGroup(nullptr),
|
|
|
|
|
|
m_bWellMarkersVisible(true),
|
|
|
|
|
|
m_bWellNamesVisible(true)
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
// setRenderProp 只在未挂载时可调用,因此根 Assembly 在构造时一次固定。
|
|
|
|
|
|
setRenderProp(m_pRootAssembly);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmPebiResultWellAnnotationLayer::~nmPebiResultWellAnnotationLayer()
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
detach();
|
|
|
|
|
|
clear();
|
|
|
|
|
|
m_pRootAssembly = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmPebiResultWellAnnotationLayer::prepareCandidate(
|
|
|
|
|
|
const QSharedPointer<const nmPebiResultSnapshot>& pSnapshot)
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
discardCandidate();
|
|
|
|
|
|
if(!isWellAnnotationGuiThread() || pSnapshot.isNull() ||
|
|
|
|
|
|
!pSnapshot->isComplete()) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkPoints> pMarkerPoints =
|
|
|
|
|
|
vtkSmartPointer<vtkPoints>::New();
|
|
|
|
|
|
vtkSmartPointer<vtkCellArray> pMarkerVertices =
|
|
|
|
|
|
vtkSmartPointer<vtkCellArray>::New();
|
|
|
|
|
|
vtkSmartPointer<vtkPoints> pNamePoints =
|
|
|
|
|
|
vtkSmartPointer<vtkPoints>::New();
|
|
|
|
|
|
vtkSmartPointer<vtkStringArray> pWellNames =
|
|
|
|
|
|
vtkSmartPointer<vtkStringArray>::New();
|
|
|
|
|
|
pWellNames->SetName("WellName");
|
|
|
|
|
|
|
|
|
|
|
|
QSet<QString> setWellIds;
|
|
|
|
|
|
for(int nIndex = 0; nIndex < pSnapshot->getWellCount(); ++nIndex) {
|
|
|
|
|
|
const nmPebiResultWellSnapshot* pWell = pSnapshot->getWellAt(nIndex);
|
|
|
|
|
|
if(pWell == nullptr || pWell->m_sWellInstanceId.isEmpty() ||
|
|
|
|
|
|
pWell->m_sWellName.isEmpty() ||
|
|
|
|
|
|
!vtkMath::IsFinite(pWell->m_oLocation.x()) ||
|
|
|
|
|
|
!vtkMath::IsFinite(pWell->m_oLocation.y()) ||
|
|
|
|
|
|
setWellIds.contains(pWell->m_sWellInstanceId)) {
|
|
|
|
|
|
discardCandidate();
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
setWellIds.insert(pWell->m_sWellInstanceId);
|
|
|
|
|
|
|
|
|
|
|
|
// 保持快照存储顺序;二维 Overlay 不向业务位置写入虚构 Z 值。
|
|
|
|
|
|
const vtkIdType nPointId = pMarkerPoints->InsertNextPoint(
|
|
|
|
|
|
pWell->m_oLocation.x(), pWell->m_oLocation.y(), 0.0);
|
|
|
|
|
|
pMarkerVertices->InsertNextCell(1);
|
|
|
|
|
|
pMarkerVertices->InsertCellPoint(nPointId);
|
|
|
|
|
|
pNamePoints->InsertNextPoint(
|
|
|
|
|
|
pWell->m_oLocation.x(), pWell->m_oLocation.y(), 0.0);
|
|
|
|
|
|
const QByteArray aWellName = pWell->m_sWellName.toUtf8();
|
|
|
|
|
|
pWellNames->InsertNextValue(aWellName.constData());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkPropAssembly> pSnapshotAssembly =
|
|
|
|
|
|
vtkSmartPointer<vtkPropAssembly>::New();
|
|
|
|
|
|
vtkSmartPointer<vtkPropAssembly> pMarkerGroup =
|
|
|
|
|
|
vtkSmartPointer<vtkPropAssembly>::New();
|
|
|
|
|
|
vtkSmartPointer<vtkPropAssembly> pNameGroup =
|
|
|
|
|
|
vtkSmartPointer<vtkPropAssembly>::New();
|
|
|
|
|
|
|
|
|
|
|
|
if(pSnapshot->getWellCount() > 0) {
|
|
|
|
|
|
vtkSmartPointer<vtkPolyData> pMarkerData =
|
|
|
|
|
|
vtkSmartPointer<vtkPolyData>::New();
|
|
|
|
|
|
pMarkerData->SetPoints(pMarkerPoints);
|
|
|
|
|
|
pMarkerData->SetVerts(pMarkerVertices);
|
|
|
|
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkCoordinate> pWorldCoordinate =
|
|
|
|
|
|
vtkSmartPointer<vtkCoordinate>::New();
|
|
|
|
|
|
pWorldCoordinate->SetCoordinateSystemToWorld();
|
|
|
|
|
|
vtkSmartPointer<vtkPolyDataMapper2D> pMarkerMapper =
|
|
|
|
|
|
vtkSmartPointer<vtkPolyDataMapper2D>::New();
|
|
|
|
|
|
pMarkerMapper->SetInputData(pMarkerData);
|
|
|
|
|
|
pMarkerMapper->SetTransformCoordinate(pWorldCoordinate);
|
|
|
|
|
|
pMarkerMapper->ScalarVisibilityOff();
|
|
|
|
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkActor2D> pMarkerActor =
|
|
|
|
|
|
vtkSmartPointer<vtkActor2D>::New();
|
|
|
|
|
|
pMarkerActor->SetMapper(pMarkerMapper);
|
|
|
|
|
|
pMarkerActor->GetProperty()->SetColor(0.12, 0.12, 0.12);
|
|
|
|
|
|
pMarkerActor->GetProperty()->SetPointSize(9.0);
|
|
|
|
|
|
pMarkerGroup->AddPart(pMarkerActor);
|
|
|
|
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkPolyData> pNameData =
|
|
|
|
|
|
vtkSmartPointer<vtkPolyData>::New();
|
|
|
|
|
|
pNameData->SetPoints(pNamePoints);
|
|
|
|
|
|
pNameData->GetPointData()->AddArray(pWellNames);
|
|
|
|
|
|
vtkSmartPointer<vtkLabeledDataMapper> pNameMapper =
|
|
|
|
|
|
vtkSmartPointer<vtkLabeledDataMapper>::New();
|
|
|
|
|
|
pNameMapper->SetInputData(pNameData);
|
|
|
|
|
|
pNameMapper->SetLabelModeToLabelFieldData();
|
|
|
|
|
|
pNameMapper->SetFieldDataName("WellName");
|
|
|
|
|
|
pNameMapper->SetLabelFormat("%s");
|
|
|
|
|
|
pNameMapper->GetLabelTextProperty()->SetFontSize(12);
|
|
|
|
|
|
pNameMapper->GetLabelTextProperty()->SetColor(0.10, 0.10, 0.10);
|
|
|
|
|
|
pNameMapper->GetLabelTextProperty()->BoldOff();
|
|
|
|
|
|
pNameMapper->GetLabelTextProperty()->ItalicOff();
|
|
|
|
|
|
pNameMapper->GetLabelTextProperty()->ShadowOff();
|
|
|
|
|
|
pNameMapper->GetLabelTextProperty()->SetJustificationToLeft();
|
|
|
|
|
|
pNameMapper->GetLabelTextProperty()->SetVerticalJustificationToBottom();
|
|
|
|
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkActor2D> pNameActor =
|
|
|
|
|
|
vtkSmartPointer<vtkActor2D>::New();
|
|
|
|
|
|
pNameActor->SetMapper(pNameMapper);
|
|
|
|
|
|
// Actor2D 的显示坐标偏移固定为像素,不随相机缩放改变。
|
|
|
|
|
|
pNameActor->SetDisplayPosition(7, 6);
|
|
|
|
|
|
pNameGroup->AddPart(pNameActor);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pMarkerGroup->SetVisibility(m_bWellMarkersVisible ? 1 : 0);
|
|
|
|
|
|
pNameGroup->SetVisibility(m_bWellNamesVisible ? 1 : 0);
|
|
|
|
|
|
pSnapshotAssembly->AddPart(pMarkerGroup);
|
|
|
|
|
|
pSnapshotAssembly->AddPart(pNameGroup);
|
|
|
|
|
|
|
|
|
|
|
|
// 所有校验和 VTK 对象构造成功后才记录候选;活动子树仍未触碰。
|
|
|
|
|
|
m_pCandidateSnapshotAssembly = pSnapshotAssembly;
|
|
|
|
|
|
m_pCandidateMarkerGroup = pMarkerGroup;
|
|
|
|
|
|
m_pCandidateNameGroup = pNameGroup;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmPebiResultWellAnnotationLayer::discardCandidate()
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
m_pCandidateNameGroup = nullptr;
|
|
|
|
|
|
m_pCandidateMarkerGroup = nullptr;
|
|
|
|
|
|
m_pCandidateSnapshotAssembly = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmPebiResultWellAnnotationLayer::commitCandidate()
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
Q_ASSERT(m_pCandidateSnapshotAssembly != nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
if(m_pActiveSnapshotAssembly != nullptr) {
|
|
|
|
|
|
m_pRootAssembly->RemovePart(m_pActiveSnapshotAssembly);
|
|
|
|
|
|
}
|
|
|
|
|
|
m_pActiveSnapshotAssembly = m_pCandidateSnapshotAssembly;
|
|
|
|
|
|
m_pActiveMarkerGroup = m_pCandidateMarkerGroup;
|
|
|
|
|
|
m_pActiveNameGroup = m_pCandidateNameGroup;
|
|
|
|
|
|
m_pRootAssembly->AddPart(m_pActiveSnapshotAssembly);
|
|
|
|
|
|
discardCandidate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmPebiResultWellAnnotationLayer::clear()
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
discardCandidate();
|
|
|
|
|
|
if(m_pRootAssembly != nullptr &&
|
|
|
|
|
|
m_pActiveSnapshotAssembly != nullptr) {
|
|
|
|
|
|
m_pRootAssembly->RemovePart(m_pActiveSnapshotAssembly);
|
|
|
|
|
|
}
|
|
|
|
|
|
m_pActiveNameGroup = nullptr;
|
|
|
|
|
|
m_pActiveMarkerGroup = nullptr;
|
|
|
|
|
|
m_pActiveSnapshotAssembly = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmPebiResultWellAnnotationLayer::hasActiveAnnotations() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_pActiveSnapshotAssembly != nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmPebiResultWellAnnotationLayer::setWellMarkersVisible(bool bVisible)
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
if(!isWellAnnotationGuiThread()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
m_bWellMarkersVisible = bVisible;
|
|
|
|
|
|
if(m_pActiveMarkerGroup != nullptr) {
|
|
|
|
|
|
m_pActiveMarkerGroup->SetVisibility(bVisible ? 1 : 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
if(m_pCandidateMarkerGroup != nullptr) {
|
|
|
|
|
|
m_pCandidateMarkerGroup->SetVisibility(bVisible ? 1 : 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmPebiResultWellAnnotationLayer::setWellNamesVisible(bool bVisible)
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_ASSERT(isWellAnnotationGuiThread());
|
|
|
|
|
|
if(!isWellAnnotationGuiThread()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
m_bWellNamesVisible = bVisible;
|
|
|
|
|
|
if(m_pActiveNameGroup != nullptr) {
|
|
|
|
|
|
m_pActiveNameGroup->SetVisibility(bVisible ? 1 : 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
if(m_pCandidateNameGroup != nullptr) {
|
|
|
|
|
|
m_pCandidateNameGroup->SetVisibility(bVisible ? 1 : 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmPebiResultWellAnnotationLayer::areWellMarkersVisible() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_bWellMarkersVisible;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmPebiResultWellAnnotationLayer::areWellNamesVisible() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_bWellNamesVisible;
|
|
|
|
|
|
}
|