当前位置:网站首页>[VTK] MFC grid editor based on vtk8.2
[VTK] MFC grid editor based on vtk8.2
2022-06-29 11:49:00 【Ten year dream Lab】
Video demo


Screenshot of main interface
Main source code :
// appMeshEditorDlg.cpp : implementation file
//
#include "stdafx.h"
#include "appMeshEditor.h"
#include "appMeshEditorDlg.h"
#include "afxdialogex.h"
// transformation
//#include "atlstr.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CappMeshEditorDlg dialog
CappMeshEditorDlg::CappMeshEditorDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_APPMESHEDITOR_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CappMeshEditorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CappMeshEditorDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_CBN_SELCHANGE(IDC_NEIGHBOR_STEP, &CappMeshEditorDlg::OnSelchangeNeighborStep)
ON_BN_CLICKED(IDC_LOAD_STL, &CappMeshEditorDlg::OnBnClickedLoadStl)
ON_BN_CLICKED(IDC_NEIGHBORFACE_RING, &CappMeshEditorDlg::OnBnClickedNeighborfaceRing)
ON_BN_CLICKED(IDC_NEIGHBORFACE_AREA, &CappMeshEditorDlg::OnBnClickedNeighborfaceArea)
ON_BN_CLICKED(IDC_FILL_HOLE, &CappMeshEditorDlg::OnBnClickedFillHole)
ON_BN_CLICKED(IDC_DELETE_FACE, &CappMeshEditorDlg::OnBnClickedDeleteFace)
END_MESSAGE_MAP()
// CappMeshEditorDlg message handlers
BOOL CappMeshEditorDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// VTK Code
{
if (this->GetDlgItem(IDC_STATIC_MAINFRAME))
{
this->CreateVTKWindow(this->GetDlgItem(IDC_STATIC_MAINFRAME)->GetSafeHwnd());// establish VTK window
this->ResizeVtkWindow();
}
}
// Init ComboBox of NeighborStep
{
CComboBox* pComboBox = (CComboBox*)this->GetDlgItem(IDC_NEIGHBOR_STEP); // Get the drop-down list box
pComboBox->AddString(_T("00"));// add to item
pComboBox->AddString(_T("01"));
pComboBox->AddString(_T("02"));
pComboBox->AddString(_T("03"));
pComboBox->AddString(_T("04"));
pComboBox->AddString(_T("05"));
pComboBox->AddString(_T("06"));
pComboBox->AddString(_T("07"));
pComboBox->AddString(_T("08"));
pComboBox->AddString(_T("09"));
pComboBox->AddString(_T("10"));
pComboBox->SetCurSel(0);// Select the first item
this->m_nNeighborStep = pComboBox->GetCurSel();// Get the number of neighbors of the selected grid
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CappMeshEditorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CappMeshEditorDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CappMeshEditorDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
#pragma region // VTK Event
// Mouse hovering
void Callback_MouseOver_Face(vtkObject* caller, long unsigned int eventId,
void* clientData, void* callData)
{
// Interactor Get the interactor
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkRenderWindowInteractor::SafeDownCast(caller);
if (interactor == NULL)
return;
// ClientData Get client data
CappMeshEditorDlg* dlg = (CappMeshEditorDlg*)clientData;
if (dlg == NULL)
return;
// Mouse click location
int pos[2];
interactor->GetLastEventPosition(pos);
// Pick at the mouse click position
vtkSmartPointer<vtkCellPicker> picker =
vtkSmartPointer<vtkCellPicker>::New();
picker->SetTolerance(0.005); // Pick sensitivity setting
picker->Pick(pos[0], pos[1], 0,
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
vtkIdType mouseoverFaceIdx = picker->GetCellId(); // If -1, Is not selected .
if (mouseoverFaceIdx != -1)
{
// lookup polyData
vtkSmartPointer<vtkRenderer> renderer =
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer();
vtkSmartPointer<vtkActorCollection> actorCollection =
renderer->GetActors();
actorCollection->InitTraversal();
vtkSmartPointer<vtkActor> actor =
actorCollection->GetNextActor();
vtkSmartPointer<vtkMapper> mapper =
actor->GetMapper();
vtkSmartPointer<vtkPolyData> polyData = (vtkPolyData*)mapper->GetInput();
vtkSmartPointer<vtkTriangleFilter> triangleFilter =
vtkSmartPointer<vtkTriangleFilter>::New();
triangleFilter->SetInputData(polyData);
triangleFilter->Update();
// <#> MouseOverFace Select the face dataset mapper
vtkSmartPointer<vtkDataSetMapper> mapperPickingFace =
vtkSmartPointer<vtkDataSetMapper>::New();
{
vtkSmartPointer<vtkIdTypeArray> ids =
vtkSmartPointer<vtkIdTypeArray>::New();
ids->SetNumberOfComponents(1);
ids->InsertNextValue(mouseoverFaceIdx);
vtkSmartPointer<vtkSelectionNode> selectionNode =
vtkSmartPointer<vtkSelectionNode>::New();
selectionNode->SetFieldType(vtkSelectionNode::CELL);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(ids);
vtkSmartPointer<vtkSelection> selection =
vtkSmartPointer<vtkSelection>::New();
selection->AddNode(selectionNode);
vtkSmartPointer<vtkExtractSelection> extractSelection =
vtkSmartPointer<vtkExtractSelection>::New();
extractSelection->SetInputConnection(0, triangleFilter->GetOutputPort());
extractSelection->SetInputData(1, selection);
extractSelection->Update();
mapperPickingFace->SetInputConnection(extractSelection->GetOutputPort());
}
vtkSmartPointer<vtkActor> actorMouseoverFace =
vtkSmartPointer<vtkActor>::New();
actorMouseoverFace->SetMapper(mapperPickingFace);
actorMouseoverFace->GetProperty()->SetColor(0.0, 1.0, 0.0);
// <#> Display on screen
{
//Add the actors to the scene
renderer->RemoveAllViewProps();
renderer->AddActor(actor);
renderer->AddActor(actorMouseoverFace);
renderer->SetBackground(0.1, 0.2, 0.3);
interactor->GetRenderWindow()->Render();
}
}
}
// Neighborhood ring
void Callback_NeighborFace_Ring(vtkObject* caller, long unsigned int eventId,
void* clientData, void* callData)
{
// Interactor Get the interactor
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkRenderWindowInteractor::SafeDownCast(caller);
if (interactor == NULL)
return;
// ClientData Get dialog data : Incoming client data
CappMeshEditorDlg* dlg = (CappMeshEditorDlg*)clientData;
if (dlg == NULL)
return;
// Mouse click location
int pos[2];
interactor->GetLastEventPosition(pos);
// Pick at the mouse click position
vtkSmartPointer<vtkCellPicker> picker =
vtkSmartPointer<vtkCellPicker>::New();
picker->SetTolerance(0.005); // picking Sensitivity settings
// Use the selection points provided to perform the pick operation . Usually the first two values are picked up (x,y) Pixel coordinates , The third value is z=0. If you succeed in choosing something , Then the return value will be non-zero .
picker->Pick(pos[0], pos[1], 0,
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());// Pick operation , Calculate selected faces
// Selected faces ID
vtkIdType pikingFaceIdx = picker->GetCellId(); // If -1, Is not selected .
if (pikingFaceIdx != -1)
{
// Get grid data polyData
vtkSmartPointer<vtkRenderer> renderer =
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer();// Renderers
vtkSmartPointer<vtkActorCollection> actorCollection =
renderer->GetActors();// Get all actors actors
actorCollection->InitTraversal();// Initialize traversal of the collection . This means that the data pointer is set at the beginning of the list .
vtkSmartPointer<vtkActor> actor =
actorCollection->GetNextActor();// Get the first actor actor
vtkSmartPointer<vtkMapper> mapper =
actor->GetMapper();// Get the actor's mapper
vtkSmartPointer<vtkPolyData> polyData = (vtkPolyData*)mapper->GetInput();// Get grid data
// Triangular patch filter
vtkSmartPointer<vtkTriangleFilter> triangleFilter =
vtkSmartPointer<vtkTriangleFilter>::New();
triangleFilter->SetInputData(polyData);
triangleFilter->Update();
// m_vecNeighborFace initialization
dlg->m_vecNeighborFace.clear();
Find all adjacent faces of the face where the selected point is located
std::vector<vtkIdType> vec;
vec.push_back(pikingFaceIdx);
dlg->m_vecNeighborFace.push_back(vec);// First, add the currently selected face index to m_vecNeighborFace
vec.clear();
dlg->m_vecNeighborFace.push_back(vec);// Initializes an empty area index vector Add to m_vecNeighborFace
// call GenerateNeighborFace Generate neighbor patches
int nCntDepth = dlg->m_nNeighborStep;// Number and depth of neighbors
for (int i = 0; i < nCntDepth; ++i)
{// Calculate neighbors layer by layer
dlg->GenerateNeighborList(dlg->m_vecNeighborFace.at(i + 1),
dlg->m_vecNeighborFace.at(i),
triangleFilter);
// The first i+1 layer The neighbor goes to the heavy
dlg->Deduplication(dlg->m_vecNeighborFace.at(i + 1));
vec.clear();
dlg->m_vecNeighborFace.push_back(vec);// The new layer of neighbors is added to m_vecNeighborFace.
// <#> Debug Output
OutputDebugString(L"\n Point neighbor ids are: ");
for (std::vector<vtkIdType>::iterator it1 = dlg->m_vecNeighborFace.at(i + 1).begin(); it1 != dlg->m_vecNeighborFace.at(i + 1).end(); it1++)
{
CString strDebug;
/*strDebug.Format(L" %d", *it1);*/
strDebug.Format(_T(" %d"), *it1);
::OutputDebugString(strDebug);
}
OutputDebugString(L"\n");
}
/// <#> PickingFace Select the face Dataset mapper
vtkSmartPointer<vtkDataSetMapper> mapperPickingFace =
vtkSmartPointer<vtkDataSetMapper>::New();
{
vtkSmartPointer<vtkIdTypeArray> ids =
vtkSmartPointer<vtkIdTypeArray>::New();
ids->SetNumberOfComponents(1);
ids->InsertNextValue(dlg->m_vecNeighborFace.at(0).at(0));// Select the face id
vtkSmartPointer<vtkSelectionNode> selectionNode =
vtkSmartPointer<vtkSelectionNode>::New();
selectionNode->SetFieldType(vtkSelectionNode::CELL);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(ids);// The selected node
vtkSmartPointer<vtkSelection> selection =
vtkSmartPointer<vtkSelection>::New();
selection->AddNode(selectionNode);// Add to selected objects
vtkSmartPointer<vtkExtractSelection> extractSelection =
vtkSmartPointer<vtkExtractSelection>::New();
extractSelection->SetInputConnection(0, triangleFilter->GetOutputPort());
extractSelection->SetInputData(1, selection);
extractSelection->Update();// Extract selected faces
mapperPickingFace->SetInputConnection(extractSelection->GetOutputPort());// Associate the dataset mapper with Selected surface
}
// Selected surface actor actor
vtkSmartPointer<vtkActor> actorPickingFace =
vtkSmartPointer<vtkActor>::New();
actorPickingFace->SetMapper(mapperPickingFace);
actorPickingFace->GetProperty()->SetColor(1, 0, 0);
// <#> NeighborFace Outermost adjacent face dataset mapper
vtkSmartPointer<vtkDataSetMapper> mapperNeighborFace =
vtkSmartPointer<vtkDataSetMapper>::New();
{
// GenerateNeighborRing Calculate ring neighbors
std::vector<vtkIdType> vecNeighborRing;
if (nCntDepth >= 1)
{
dlg->GenerateNeighborRing(vecNeighborRing,
dlg->m_vecNeighborFace.at(nCntDepth),
dlg->m_vecNeighborFace.at(nCntDepth - 1),
dlg->m_vecNeighborFace.at(0)); //
}
else// Only selected faces
{
vecNeighborRing.push_back(dlg->m_vecNeighborFace.at(0).at(0));
}
vtkSmartPointer<vtkIdTypeArray> ids =
vtkSmartPointer<vtkIdTypeArray>::New();
ids->SetNumberOfComponents(1);
dlg->m_vecSelectedFace.clear();
for (std::vector<vtkIdType>::iterator it1 = vecNeighborRing.begin(); it1 != vecNeighborRing.end(); it1++)
{
ids->InsertNextValue(*it1);// Outermost neighbor ring Face index
dlg->m_vecSelectedFace.push_back(*it1);
}
// Select node
vtkSmartPointer<vtkSelectionNode> selectionNode =
vtkSmartPointer<vtkSelectionNode>::New();
selectionNode->SetFieldType(vtkSelectionNode::CELL);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(ids);// Outermost neighbor index
vtkSmartPointer<vtkSelection> selection =
vtkSmartPointer<vtkSelection>::New();
selection->AddNode(selectionNode);// Add to selected objects
vtkSmartPointer<vtkExtractSelection> extractSelection =
vtkSmartPointer<vtkExtractSelection>::New();
extractSelection->SetInputConnection(0, triangleFilter->GetOutputPort());
extractSelection->SetInputData(1, selection);
extractSelection->Update();
mapperNeighborFace->SetInputConnection(extractSelection->GetOutputPort());// Outermost neighbor Dataset mapper
}
vtkSmartPointer<vtkActor> actorNeighborFace =
vtkSmartPointer<vtkActor>::New();
actorNeighborFace->SetMapper(mapperNeighborFace);
actorNeighborFace->GetProperty()->SetColor(0, 1, 0);// green Outermost neighbor
// <#> Display on screen
{
//Add the actors to the scene
renderer->RemoveAllViewProps();
renderer->AddActor(actor);// All the actors
renderer->AddActor(actorPickingFace);// Selected surface
renderer->AddActor(actorNeighborFace);// Outermost surface
renderer->SetBackground(.1, .2, .3); // Background color dark red
interactor->GetRenderWindow()->Render();
}
}
}
// Neighbor patch area
void Callback_NeighborFace_Area(vtkObject* caller, long unsigned int eventId,
void* clientData, void* callData)
{
// Get the interactor
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkRenderWindowInteractor::SafeDownCast(caller);// Interactor
if (interactor == NULL)
return;
// Get customer data
CappMeshEditorDlg* dlg = (CappMeshEditorDlg*)clientData;// Client data
if (dlg == NULL)
return;
// Mouse click location
int pos[2];
interactor->GetLastEventPosition(pos);// Interactor : Get the left key press position
// Pick at the mouse click position
vtkSmartPointer<vtkCellPicker> picker =
vtkSmartPointer<vtkCellPicker>::New();
picker->SetTolerance(0.005); // Pick sensitivity setting
picker->Pick(pos[0], pos[1], 0,
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());// Pick the triangle patch according to the point
vtkIdType pikingFaceIdx = picker->GetCellId(); // Get the picked triangle patch index If -1, Is not selected .
if (pikingFaceIdx != -1)
{
// lookup polyData
vtkSmartPointer<vtkRenderer> renderer =
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer();// Get renderer
vtkSmartPointer<vtkActorCollection> actorCollection =
renderer->GetActors(); // Returns any... In this renderer actors.
actorCollection->InitTraversal();// Initialize traversal of the collection . This means that the data pointer is set at the beginning of the list .
/// All the actors
vtkSmartPointer<vtkActor> actor =
actorCollection->GetNextActor();
vtkSmartPointer<vtkMapper> mapper =
actor->GetMapper();// Back here actor The mapper from which the data is obtained .
vtkSmartPointer<vtkPolyData> polyData = (vtkPolyData*)mapper->GetInput();// Get all triangle patch data
vtkSmartPointer<vtkTriangleFilter> triangleFilter =
vtkSmartPointer<vtkTriangleFilter>::New();// Triangular patch filter
triangleFilter->SetInputData(polyData);// Add all triangle patches to the filter
triangleFilter->Update();
// m_vecNeighborFace Initialize the neighbor patch index of the selected point
dlg->m_vecNeighborFace.clear();
// Find connection to point 0 All cells of Find all cells connected to point 0
std::vector<vtkIdType> vec;
vec.push_back(pikingFaceIdx); // Selected patches id
dlg->m_vecNeighborFace.push_back(vec); // Add the selected patch vector first
vec.clear();
dlg->m_vecNeighborFace.push_back(vec);// add to The vector of the empty patch vector
/ Call generate neighbor patch call GenerateNeighborFace
int nCntDepth = dlg->m_nNeighborStep; // Set the number of neighbors
for (int i = 0; i < nCntDepth; ++i)
{
dlg->GenerateNeighborList(dlg->m_vecNeighborFace.at(i + 1),
dlg->m_vecNeighborFace.at(i),
triangleFilter);// Generate The first i Of the Group Patch vector Adjacent patch list
// vec repeat clear
dlg->Deduplication(dlg->m_vecNeighborFace.at(i + 1));// Delete duplicate data
vec.clear();
dlg->m_vecNeighborFace.push_back(vec);// Add the vector of the empty patch vector
// <#> Debug output
OutputDebugString(L"\n Point neighbor ids are: ");
for (std::vector<vtkIdType>::iterator it1 = dlg->m_vecNeighborFace.at(i + 1).begin(); it1 != dlg->m_vecNeighborFace.at(i + 1).end(); it1++)
{
CString strDebug;
/*strDebug.Format(L" %d", *it1);*/
strDebug.Format(_T(" %d"), *it1);
::OutputDebugString(strDebug);
}
OutputDebugString(L"\n");
}
/// <#> PickingFace : Get all selected faces Dataset mapper
vtkSmartPointer<vtkDataSetMapper> mapperPickingFace =
vtkSmartPointer<vtkDataSetMapper>::New();// Dataset mapper
{ // Select the triangle patch index array
vtkSmartPointer<vtkIdTypeArray> ids =
vtkSmartPointer<vtkIdTypeArray>::New();
ids->SetNumberOfComponents(1);
ids->InsertNextValue(dlg->m_vecNeighborFace.at(0).at(0));// Insert the selected patch
// Select node
vtkSmartPointer<vtkSelectionNode> selectionNode =
vtkSmartPointer<vtkSelectionNode>::New();
selectionNode->SetFieldType(vtkSelectionNode::CELL);// Field type : unit
selectionNode->SetContentType(vtkSelectionNode::INDICES);// Content type : Indexes
selectionNode->SetSelectionList(ids);// Set the list of selected triangles , Only one.
vtkSmartPointer<vtkSelection> selection =
vtkSmartPointer<vtkSelection>::New();
selection->AddNode(selectionNode);// Add selection node
// Extract the selected
vtkSmartPointer<vtkExtractSelection> extractSelection =
vtkSmartPointer<vtkExtractSelection>::New();
extractSelection->SetInputConnection(0, triangleFilter->GetOutputPort());// Set input set
extractSelection->SetInputData(1, selection);// Set input data
extractSelection->Update();
mapperPickingFace->SetInputConnection(extractSelection->GetOutputPort());// Selected faces : Dataset mapper
}
//actor actor : Selected faces , Red
vtkSmartPointer<vtkActor> actorPickingFace =
vtkSmartPointer<vtkActor>::New();
actorPickingFace->SetMapper(mapperPickingFace);// Set up actor Data mapper for
actorPickingFace->GetProperty()->SetColor(1, 0, 0);// Set properties : Color - Red
<#> NeighborFace Neighbor face dataset mapper
vtkSmartPointer<vtkDataSetMapper> mapperNeighborFace =
vtkSmartPointer<vtkDataSetMapper>::New();
{
// GenerateNeighborArea Get neighbor area
std::vector<vtkIdType> vecNeighborRing; // Neighbor index vector
dlg->GenerateNeighborArea(vecNeighborRing,
dlg->m_vecNeighborFace.at(nCntDepth),// Outermost layer ( The first nCntDepth Neighbors acquired for times ) All the neighbors
dlg->m_vecNeighborFace.at(0));
vtkSmartPointer<vtkIdTypeArray> ids =
vtkSmartPointer<vtkIdTypeArray>::New();
ids->SetNumberOfComponents(1);// A one-dimensional
dlg->m_vecSelectedFace.clear();
dlg->m_vecSelectedFace.push_back(pikingFaceIdx); // The selected patch Add to m_vecSelectedFace
for (std::vector<vtkIdType>::iterator it1 = vecNeighborRing.begin(); it1 != vecNeighborRing.end(); it1++)
{
ids->InsertNextValue(*it1);
dlg->m_vecSelectedFace.push_back(*it1);// The outermost neighbor index is added to m_vecSelectedFace
}
vtkSmartPointer<vtkSelectionNode> selectionNode =
vtkSmartPointer<vtkSelectionNode>::New();
selectionNode->SetFieldType(vtkSelectionNode::CELL);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(ids);// Selected node index
vtkSmartPointer<vtkSelection> selection =
vtkSmartPointer<vtkSelection>::New();
selection->AddNode(selectionNode);
vtkSmartPointer<vtkExtractSelection> extractSelection =
vtkSmartPointer<vtkExtractSelection>::New();
extractSelection->SetInputConnection(0, triangleFilter->GetOutputPort());// Triangular patch filter
extractSelection->SetInputData(1, selection);// Set input : Selected patch index
extractSelection->Update();
mapperNeighborFace->SetInputConnection(extractSelection->GetOutputPort());// obtain Neighbor face dataset mapper
}
//actor actor : Neighbor face , green
vtkSmartPointer<vtkActor> actorNeighborFace =
vtkSmartPointer<vtkActor>::New();// Neighbor patch
actorNeighborFace->SetMapper(mapperNeighborFace);// Set up mapper
actorNeighborFace->GetProperty()->SetColor(0, 1, 0);// Set properties
//<#> Display on screen
{
// Add actors to the scene
renderer->RemoveAllViewProps();
// Add... To the renderer / Delete different types of actors .
// All of these methods are AddViewProp and RemoveViewProp A synonym for .
// They are here for convenience and backward compatibility .
renderer->AddActor(actor);// All sides actor.loadstl obtain
renderer->AddActor(actorPickingFace);// Add selected faces actor
renderer->AddActor(actorNeighborFace);// Add a neighborhood actor
renderer->SetBackground(.1, .2, .3); // Background color dark red
interactor->GetRenderWindow()->Render();
}
}
}
#pragma endregion
#pragma region // MFC Event
// Select neighbor depth
void CappMeshEditorDlg::OnSelchangeNeighborStep()
{
CComboBox* pComboBox = (CComboBox*)this->GetDlgItem(IDC_NEIGHBOR_STEP);
this->m_nNeighborStep = pComboBox->GetCurSel();
}
// load stl
void CappMeshEditorDlg::OnBnClickedLoadStl()
{
try
{
// <#> File dialog filter
TCHAR szFilter[] = _T("STL (*.stl)|*.stl|All Files (*.*)|*.*||");
// <#> File dialog
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter);
// <#> data
{
// Get the executed appPath
TCHAR appPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, appPath);
// Separate appPath
CString strDefaultPath;
CString strSubPath;
int nCount = 0;
while (AfxExtractSubString(strSubPath, appPath, nCount, _T('\\')) == TRUE)
{
CString strTemp;
BOOL bRtn = AfxExtractSubString(strTemp, appPath, nCount + 1, _T('\\'));
if (bRtn == FALSE)
break;
strDefaultPath.Format(_T("%s%s\\"), strDefaultPath, strSubPath);
++nCount;
}
strDefaultPath.Format(_T("%s%s"), strDefaultPath, _T("data"));//data Folder
// CString to TCHAR[]
TCHAR szDataFolder[MAX_PATH];
memset(szDataFolder, 0x00, sizeof(TCHAR) * MAX_PATH);
_tcscpy_s(szDataFolder, MAX_PATH, strDefaultPath.GetBuffer(0));
strDefaultPath.ReleaseBuffer();
// Default Folder Default folder
dlg.m_ofn.lpstrInitialDir = szDataFolder;//data Folder
//char* szStr = "./data/";
//CString str = CString(szStr);
//USES_CONVERSION;
//LPCWSTR wszName = A2CW(W2A(str));
//str.ReleaseBuffer();
//dlg.m_ofn.lpstrInitialDir = wszName;
//dlg.m_ofn.lpstrInitialDir = appPath;
}
//char* szStr = "./data/";
//CString str = CString(szStr);
//USES_CONVERSION;
//LPCWSTR wszName = A2CW(W2A(str));
//str.ReleaseBuffer();
//dlg.m_ofn.lpstrInitialDir = wszName;
if (dlg.DoModal() == IDOK)
{
// Can only handle stl
CString strFilePath = dlg.GetPathName();// File path
CString strExtention = PathFindExtension(strFilePath);// File extension
if (strExtention.Compare(_T(".stl")) != 0)
{
::MessageBox(NULL, _T("Only Load STL Files"), _T("ERROR"), MB_OK);
return;
}
// <#> take STL Load into main window
{
if (m_vtkMainWindow == NULL)
throw;
// <#0> Initialize the renderer
vtkSmartPointer<vtkRenderer> prevRenderer =
m_vtkMainWindow->GetRenderers()->GetFirstRenderer();// Get the current renderer
if (prevRenderer != NULL)// The current renderer is not empty
m_vtkMainWindow->RemoveRenderer(prevRenderer);// Remove the current renderer
// <#1> load STL Model
vtkSmartPointer<vtkSTLReader> STLReader =
vtkSmartPointer<vtkSTLReader>::New();
STLReader->SetFileName(CT2A(strFilePath));
STLReader->Update();
// <#2> take STL Save to PolyData transformation
m_vtkPolyData = STLReader->GetOutput();
// <#3>STL FaceCnt & VertexCnt Information
//SetGeneralInfo(m_vtkPolyData);
// <#4> Create a grid data mapper
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(m_vtkPolyData);
mapper->Update();
// <#5> Create actors
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);//stl Data actor
actor->GetProperty()->SetEdgeColor(0.0, 0.0, 0.0);// Sets the color of the edge : black
actor->GetProperty()->EdgeVisibilityOn();
// <#6> Create a renderer
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);// Add render objects
renderer->SetBackground(0.1, 0.2, 0.3);// Background color
renderer->ResetCamera();// Reset camera
m_vtkMainWindow->AddRenderer(renderer);
// <#7> Interactor Interactor
//vtkSmartPointer<vtkRenderWindowInteractor> newIntoractor =
// vtkSmartPointer<vtkRenderWindowInteractor>::New();
//newIntoractor->SetInteractorStyle(
// vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New());
//m_vtkWindow->SetInteractor(newIntoractor);
// <#9> Draw on the screen
//m_vtkMainWindow->Render();
}
}
}
catch (...)
{
::MessageBox(NULL, _T("OnBnClickedLoadStl"), _T("Exception"), MB_OK);
}
}
// Neighborhood ring
void CappMeshEditorDlg::OnBnClickedNeighborfaceRing()
{
// <#1> Interactor Interactor
vtkSmartPointer<vtkRenderWindowInteractor> newIntoractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
newIntoractor->SetInteractorStyle(
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New());
m_vtkMainWindow->SetInteractor(newIntoractor);
// <#2> Callback function settings
vtkSmartPointer<vtkCallbackCommand> pickCallback =
vtkSmartPointer<vtkCallbackCommand>::New();
pickCallback->SetCallback(Callback_NeighborFace_Ring);// Neighborhood ring
pickCallback->SetClientData(this);
// <#3> Connect the callback function to the interleaver
m_vtkMainWindow->GetInteractor()->
AddObserver(vtkCommand::LeftButtonPressEvent, pickCallback);// Add a left button press event to the interleaver pickCallback Handler for left key press
// <#3> Draw on the screen
m_vtkMainWindow->Render();
}
// Neighbor patch area : Click the left mouse button , Select the triangle patch ( Draw in red ), Its neighbors are painted green .
void CappMeshEditorDlg::OnBnClickedNeighborfaceArea()
{
// <#1> New interleaver Interactor
vtkSmartPointer<vtkRenderWindowInteractor> newIntoractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
newIntoractor->SetInteractorStyle(
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New());// Set the interleaver style
m_vtkMainWindow->SetInteractor(newIntoractor);// Set the rendering window Interactor
// <#2> CallBack Feature set
vtkSmartPointer<vtkCallbackCommand> pickCallback =
vtkSmartPointer<vtkCallbackCommand>::New();
pickCallback->SetCallback(Callback_NeighborFace_Area);
pickCallback->SetClientData(this);// The window pointer is passed to the callback function as client data
// <#3> Connect the callback function to the interleaver
m_vtkMainWindow->GetInteractor()->
AddObserver(vtkCommand::LeftButtonPressEvent, pickCallback);
// <#3> Draw on the screen
m_vtkMainWindow->Render();
}
// Delete triangle patch
void CappMeshEditorDlg::OnBnClickedDeleteFace()
{
// <#1> Mark the selected cells as deleted .
for (std::vector<vtkIdType>::iterator iter = m_vecSelectedFace.begin(); iter != m_vecSelectedFace.end(); ++iter)
m_vtkPolyData->DeleteCell(*iter);// Mark as deleted
// <#2> Delete marked cells .
m_vtkPolyData->RemoveDeletedCells();
// <#3> STL FaceCnt & VertexCnt Information
//SetGeneralInfo(m_pPolyData);
// <#4> Create mapper
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(m_vtkPolyData);
mapper->Update();
// <#5> Create actors
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetEdgeColor(0, 0, 0);
actor->GetProperty()->EdgeVisibilityOn();
// <#6> Find camera
vtkSmartPointer<vtkCamera> camera =
m_vtkMainWindow->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
// <#7> Create a renderer
vtkSmartPointer<vtkRenderer> prevRenderer =
m_vtkMainWindow->GetRenderers()->GetFirstRenderer();
if (prevRenderer != NULL)
m_vtkMainWindow->RemoveRenderer(prevRenderer);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);// Add actors to the renderer
renderer->SetBackground(.1, .2, .3);
renderer->SetActiveCamera(camera);// Set the active camera
m_vtkMainWindow->AddRenderer(renderer);// Add renderer to Render window
// <#8> Draw on the screen
m_vtkMainWindow->Render();
}
// Fill the hole
void CappMeshEditorDlg::OnBnClickedFillHole()
{
try
{
// <#> Fill hole filter settings
vtkSmartPointer<vtkFillHolesFilter> fillHolesFilter =
vtkSmartPointer<vtkFillHolesFilter>::New();
fillHolesFilter->SetInputData(m_vtkPolyData);// Set input data
fillHolesFilter->SetHoleSize(100000.0);// Hole size
fillHolesFilter->Update();
// <#> Mapper Populated dataset mapper
vtkSmartPointer<vtkPolyDataMapper> filledMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
filledMapper->SetInputData(fillHolesFilter->GetOutput());
filledMapper->Update();
// <#> color setting
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
//original original ,backFace That's right. , But in FillHole in , It is FilledFace Color .
// stay FillHole in , To distinguish colors , We need to check whether the normal is inverted .
vtkSmartPointer<vtkProperty> backfaceProp =
vtkSmartPointer<vtkProperty>::New();
backfaceProp->SetDiffuseColor(colors->GetColor3d("red").GetData());// Red
// <#> Actor setup
vtkSmartPointer<vtkActor> filledActor =
vtkSmartPointer<vtkActor>::New();
filledActor->SetMapper(filledMapper);// Set up the dataset mapper
// Set up / Get control of the back of this actor backface Property object of property . This should be vtkProperty An instance of an object .
// If not specified , Will use front face Positive attributes . Multiple actor Can share a property object .
filledActor->SetBackfaceProperty(backfaceProp);//
filledActor->GetProperty()->SetDiffuseColor(
colors->GetColor3d("white").GetData());// Set up / Get diffuse surface color .
filledActor->GetProperty()->SetEdgeColor(0, 0, 0);// Set the color of element edges
filledActor->GetProperty()->EdgeVisibilityOn();// Edge visible
// <#> Renderer Rendering
vtkSmartPointer<vtkRenderer> prevRenderer =
m_vtkMainWindow->GetRenderers()->GetFirstRenderer();
if (prevRenderer != NULL)
m_vtkMainWindow->RemoveRenderer(prevRenderer);
vtkSmartPointer<vtkRenderer> Renderer =
vtkSmartPointer<vtkRenderer>::New();
Renderer->AddActor(filledActor);// Filled objects
Renderer->SetBackground(0.1, 0.2, 0.3);
m_vtkMainWindow->AddRenderer(Renderer);
// <#> Draw on the screen
m_vtkMainWindow->Render();
// <#> to update m_pPolyData
m_vtkPolyData = fillHolesFilter->GetOutput();
}
catch (...)
{
::MessageBox(NULL, _T("OnBnClickedHoleFilling"), _T("Exception"), MB_OK);
}
}
#pragma endregion
#pragma region // VTK Code
void CappMeshEditorDlg::CreateVTKWindow(void* hWnd)
{
try
{
if (m_vtkMainWindow != NULL)
throw;
// <#> Create an interleaver Create Interactor
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
// <#> Set trackball type Set Trackball type
// stay VTK in , about vtkInteractorStyle Class inherits class , Commonly used 2 in ,vtkInteractorStyleTrackballCamera and
//vtkInteractorStyleTrackballActor. The first class is to change the viewing angle and object size by modifying the camera . The second class is by changing actor To change the position and size of an object .
interactor->SetInteractorStyle(
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New());
// <#> Add an observer to the interleaver Add observer to Interactor
vtkSmartPointer<vtkCallbackCommand> mouseoverCallback =
vtkSmartPointer<vtkCallbackCommand>::New();
mouseoverCallback->SetCallback(Callback_MouseOver_Face);
mouseoverCallback->SetClientData(this);
interactor->AddObserver(vtkCommand::MouseMoveEvent, mouseoverCallback); // Mouse movement events
// <#> Create a renderer Create Renderer
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
// <#> Set the background of the renderer Set Backgrund of Renderer
renderer->SetBackground(0.1, 0.2, 0.3);
// <#> Add renderer to RenderWindow
m_vtkMainWindow = vtkSmartPointer<vtkRenderWindow>::New();
m_vtkMainWindow->SetParentId(hWnd); //(hun) IDC_STATIC_MAINFRAME Set the parent handle .
//RECT rect;
//GetDlgItem(IDC_STATIC_MAINFRAME)->GetWindowRect(&rect);
//int title_height = 0;//32;
//int button_test_height = 0;//30;
//rect = rc;
///m_vtkMainWindow->SetSize(rect.right - rect.left, rect.bottom - rect.top - title_height - button_test_height);
//m_vtkMainWindow->SetPosition(rect.left, rect.top + title_height + button_test_height);
m_vtkMainWindow->SetInteractor(interactor);// Set the rendering window Interactor
m_vtkMainWindow->AddRenderer(renderer);// Add a renderer to the rendering window
//interactor->SetRenderWindow(m_vtkMainWindow);
m_vtkMainWindow->Render(); // Rendering
//iren->SetRenderWindow(m_vtkMainWindow);
//interactor->Initialize();
//interactor->Start();
}
catch (...)
{
::MessageBox(NULL, _T("CreateVTKWindow"), _T("Exception"), MB_OK);
}
}
// Delete rendering window
void CappMeshEditorDlg::DeleteVTKWindow()
{
try
{
if (m_vtkMainWindow == NULL)
throw;
m_vtkMainWindow = NULL; // (hun) SmartPointer Change it to NULL For use , So that the garbage collector can delete it .
}
catch (...)
{
::MessageBox(NULL, _T("DeleteVTKWindow"), _T("Exception"), MB_OK);
}
}
// Resize the rendering window
void CappMeshEditorDlg::ResizeVtkWindow()
{
CRect rc;
GetDlgItem(IDC_STATIC_MAINFRAME)->GetClientRect(rc);
m_vtkMainWindow->SetSize(rc.Width(), rc.Height());// Set window size
}
// Resize the window
void CappMeshEditorDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
this->ResizeVtkWindow();
}
// Generate neighbor list Output the index direction of adjacent faces vecOut, Enter the selected index vector , Triangular patch filter
void CappMeshEditorDlg::GenerateNeighborList(OUT std::vector<vtkIdType>& vecOut,
IN std::vector<vtkIdType>& vecIn, IN vtkSmartPointer<vtkTriangleFilter>& triangleFilter)
{
for (std::vector<vtkIdType>::iterator iter = vecIn.begin(); iter != vecIn.end(); ++iter)// Traverse the face index of all neighbors to be found
{
vtkIdType cellId = *(iter);// Get a face cell
vtkSmartPointer<vtkIdList> cellPointIds =
vtkSmartPointer<vtkIdList>::New();//
// Gets the vertex index of the face Get Vertex Ids From Face Id
triangleFilter->GetOutput()->GetCellPoints(cellId, cellPointIds);// Get vertex of face cell ID
for (vtkIdType i = 0; i < cellPointIds->GetNumberOfIds(); i++)// Traverse the vertices of a face
{
vtkSmartPointer<vtkIdList> idList =
vtkSmartPointer<vtkIdList>::New();
vtkIdType temp = cellPointIds->GetId(i); // Vertex Index Vertex Id
idList->InsertNextId(temp);// Add to vertex list
// Get the neighbors of the unit get the neighbors of the cell
vtkSmartPointer<vtkIdList> neighborCellIds =
vtkSmartPointer<vtkIdList>::New();// Neighbor index list
triangleFilter->GetOutput()->GetCellNeighbors(cellId, idList,
neighborCellIds);// According to the face id, The vertices id, Calculate adjacent faces id
for (vtkIdType j = 0; j < neighborCellIds->GetNumberOfIds(); j++)
vecOut.push_back(neighborCellIds->GetId(j));// Will face id Add to vecOut
}
}
}
// Delete duplicate data Patch index vector
void CappMeshEditorDlg::Deduplication(std::vector<vtkIdType>& vec)
{
std::sort(vec.begin(), vec.end());
std::vector<vtkIdType>::iterator iter = std::unique(vec.begin(), vec.end());
vec.erase(iter, vec.end());
}
// Get neighbor ring
void CappMeshEditorDlg::GenerateNeighborRing(OUT std::vector<vtkIdType>& vecOut,// Output
IN std::vector<vtkIdType>& vecMax,// The neighbor index of the outermost layer
IN std::vector<vtkIdType>& vecMin,// The neighbor index calculated by the penultimate layer
IN std::vector<vtkIdType>& vecPickFace)// Selected surface
{
std::vector<vtkIdType> vecRef = vecMin;
vecRef.push_back(vecPickFace.at(0));
for (std::vector<vtkIdType>::iterator iterMax = vecMax.begin(); iterMax != vecMax.end(); ++iterMax)
{
bool bIsSame = false;
for (std::vector<vtkIdType>::iterator iterMin = vecRef.begin(); iterMin != vecRef.end(); ++iterMin)
{
if ((*iterMax) == (*iterMin))
{
bIsSame = true;// The neighbors in the outermost layer of computing are There are also neighbors in the penultimate layer , Get rid of
break;
}
}
if (bIsSame == false)
vecOut.push_back((*iterMax));
}
}
// Neighbor area : Output vecOut, Enter neighbor index , Enter the index of the triangle patch where the selected point is located
void CappMeshEditorDlg::GenerateNeighborArea(OUT std::vector<vtkIdType>& vecOut,
IN std::vector<vtkIdType>& vecMax,
IN std::vector<vtkIdType>& vecPickFace)
{
for (std::vector<vtkIdType>::iterator iterMax = vecMax.begin(); iterMax != vecMax.end(); ++iterMax)
{
if ((*iterMax) == vecPickFace.at(0))// Selected surface
continue;
vecOut.push_back((*iterMax));// Neighbor face index
}
}
#pragma endregionRefer to the website :
https://vtk.org/ VTK - The Visualization Toolkit
https://blog.csdn.net/ddffmm66/article/details/83577521 VTK introduction _ddffmm66 The blog of -CSDN Blog _vtk introduction
https://www.jianshu.com/p/b32a657b8649 vtk Learning notes - Simple books (jianshu.com)
https://blog.csdn.net/qq_34690929/article/details/78146523 ITK and VTK Compare _Florence_Janie The blog of -CSDN Blog _itk vtk
https://www.zhihu.com/question/48405161 VTK ITK OPENCV, From the perspective of image processing , Which one is used by more people ? - You know (zhihu.com)
边栏推荐
- MySQL开启慢查询
- [HBZ sharing] InnoDB principle of MySQL
- 【文献翻译】Concealed Object Detection(伪装目标检测)
- 地平线开发板配置网段
- Qt学习08 启航!第一个应用实例
- Good news | Haitai Fangyuan has passed the cmmi-3 qualification certification, and its R & D capability has been internationally recognized
- 专访 SUSS NiFT 负责人:Web3 的未来离不开“人人为我,我为人人”的治理
- 深入理解 volatile 关键字
- 检查YAML文件安全配置:kubesec
- Follow Me Study HCIE-Big Data-Data Mining 第一章 数据挖掘介绍 模块一
猜你喜欢

What are the main factors that affect the heat dissipation of LED packaging?

Qt学习15 用户界面与业务逻辑的分离

The use of Fibonacci sequence and bubble sort in C language

Information technology application and innovation professionals (database) intermediate training hot enrollment (July 6-10)

申请uniapp离线打包时的AppKey

软件工程导论——第五章——总体设计

新版CorelDRAW Technical Suite2022最新详细功能介绍

Today in history: musk was born; Microsoft launches office 365; The inventor of Chua's circuit was born

Micro blog comment architecture design

Evaluation of IP location query interface Ⅱ
随机推荐
【HBZ分享】AQS + CAS +LockSupport 实现ReentrantLock的原理
Is it safe to open a stock account online
CICD简介[通俗易懂]
mysql截取字符串去重,mysql 截取字符串 去重 拼接
ES6 数组方法
Oracle expands distributed cloud services to bring comprehensive public cloud services to more customers
毕业5年,我问遍了身边的大佬,总结了他们的学习方法
How to identify the exact length and width of the contour
普通用户使用vscode登录ssh编辑root文件
QT learning 08 set sail! First application instance
PyTorch学习之归一化层(BatchNorm、LayerNorm、InstanceNorm、GroupNorm)[通俗易懂]
Today in history: musk was born; Microsoft launches office 365; The inventor of Chua's circuit was born
基础类型变量声明
Oracle netsuite helps TCM bio understand data changes and make business development more flexible
Rebuild confidence in China's scientific research - the latest nature index 2022 released that China's research output increased the most
记一次 MSI 笔记本 GE63 播放网页视频 闪屏和随机发绿 问题解决
C语言##__VA_ARGS__的用法
Safety innovation practice | Haitai Fangyuan was invited to participate in the technical exchange Seminar on "network information innovation and value co creation in the digital age"
巴比特 | 元宇宙每日必读:HTC 宣布推出首款元宇宙手机,售价约2700元人民币,都有哪些新玩法?...
What are the main factors that affect the heat dissipation of LED packaging?