簡體   English   中英

如何正確使用VTK ConstrainedDelaunay2D?

[英]How to correctly use VTK ConstrainedDelaunay2D?

我從VTK ConstrainedDelaunay2D 示例開始並添加了我自己的觀點:

#include <vtkSmartPointer.h>
#include <vtkDelaunay2D.h>

#include <vtkCellArray.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolygon.h>
#include <vtkMath.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkNamedColors.h>
#include <vtkVersionMacros.h> // For version macros

int main(int, char *[])
{
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  
  int ptsHeight = 400;
  std::vector<std::vector<int>> pts{ {166, 127},{103, 220},{166, 190},{174, 291},{189, 226},{227, 282},{213, 187},{242, 105},{196, 131},{182, 83} };
  for (size_t i = 0; i < pts.size(); i++)
  {
      // !important: flip y
      int x = pts[i][0];
      int y = ptsHeight - pts[i][1];
      points->InsertNextPoint(x, y, 0);
  }

  vtkSmartPointer<vtkPolyData> aPolyData = vtkSmartPointer<vtkPolyData>::New();
  aPolyData->SetPoints(points);

  // Create a cell array to store the polygon in
  vtkSmartPointer<vtkCellArray> aCellArray = vtkSmartPointer<vtkCellArray>::New();

  // Define a polygonal hole with a clockwise polygon
  vtkSmartPointer<vtkPolygon> aPolygon = vtkSmartPointer<vtkPolygon>::New();

  for (unsigned int i = 0; i < pts.size(); i++)
  {
      aPolygon->GetPointIds()->InsertNextId(i); 
  }

  aCellArray->InsertNextCell(aPolygon);

  // Create a polydata to store the boundary. The points must be the
  // same as the points we will triangulate.
  vtkSmartPointer<vtkPolyData> boundary =
   vtkSmartPointer<vtkPolyData>::New();
  boundary->SetPoints(aPolyData->GetPoints());
  boundary->SetPolys(aCellArray);

  // Triangulate the grid points
  vtkSmartPointer<vtkDelaunay2D> delaunay =
   vtkSmartPointer<vtkDelaunay2D>::New();
  delaunay->SetInputData(aPolyData);
  delaunay->SetSourceData(boundary);

  // Visualize
  vtkSmartPointer<vtkPolyDataMapper> meshMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  meshMapper->SetInputConnection(delaunay->GetOutputPort());
  
  vtkSmartPointer<vtkNamedColors> colors =
    vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkActor> meshActor =
    vtkSmartPointer<vtkActor>::New();
  meshActor->SetMapper(meshMapper);
  meshActor->GetProperty()->EdgeVisibilityOn();
  meshActor->GetProperty()->SetEdgeColor(colors->GetColor3d("Peacock").GetData());
  meshActor->GetProperty()->SetInterpolationToFlat();
  meshActor->GetProperty()->SetBackfaceCulling(true);

  // Create a renderer, render window, and interactor
  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);

  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  // Add the actor to the scene
  renderer->AddActor(meshActor);
  //renderer->AddActor(boundaryActor);
  renderer->SetBackground(colors->GetColor3d("Mint").GetData());

  // Render and interact
  renderWindow->SetSize(640, 480);
  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
} 

我遇到兩個問題:

  1. 如果我翻轉 Y 坐標,我會得到不同的結果:這是為什么?
  2. 為什么有些面指向錯誤的方向(翻轉正常/錯誤繞組)?

這是我對第一期的意思:

5 個尖頭不規則 polygan(星形)用幾個翻轉的三角形三角化

5 個尖銳的不規則多邊形(星形)用幾個翻轉的三角形三角化,但在 Y 軸上旋轉 180 度

如果我不翻轉 Y 坐標,我會得到這個:

3 個三角形作為未知三角測量結果(而不是 5 個尖形)

3 個三角形作為未知三角測量結果(而不是 5 個尖形,但在 Y 軸上旋轉 180 度

如果我不翻轉 Y 軸而是以相反的順序插入邊界多邊形,我會得到相同的效果:

for (unsigned int i = 0; i < pts.size(); i++)
  {
      aPolygon->GetPointIds()->InsertNextId(pts.size() - 1 - i); 
  }

我不認為我完全理解邊界/約束是如何工作的。 我認為無論頂點是否垂直翻轉,相同的點都應該產生相同的三角剖分。 (我懷疑指數的順序會改變嗎?)

關於第二個問題(不可預測的翻轉面孔),我不確定最好的方法是什么。 我查看了vtkDelaunay2D class,但找不到任何相關內容。 (我已經嘗試將投影平面模式設置為VTK_DELAUNAY_XY_PLANE ,但它似乎並沒有影響輸出)

我也嘗試過使用vtkPolyDataNormals但沒有得到 output:

vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
normalGenerator->SetInputData(delaunay->GetOutput());
normalGenerator->ComputePointNormalsOff();
normalGenerator->ComputeCellNormalsOn();
normalGenerator->FlipNormalsOn();
normalGenerator->Update();

normalGenerator的 output 有 0 個單元格和點)

有沒有一種方法可以計算二維點列表的約束 delaunay 三角剖分並確保所有面都指向相同的方向? (如果是這樣,怎么做?是否可以單獨使用vtkDelaunay2D class 或是否有必要使用其他過濾器?)

任何提示/技巧都非常受歡迎:)

順便說一下,我正在使用 VTK 8.2。

y 的翻轉有效地反轉了面的方向(順時針方向變成逆時針方向,就像在鏡子中一樣)。 我不確定我能否重現您上面的示例。 python 中的快速測試似乎給出了預期的行為,也許你可以從這個和 map 開始到你的 c++ 版本:

import vedo

pts = [
    [166, 127],
    [103, 220],
    [166, 190],
    [174, 291],
    [189, 226],
    [227, 282],
    [213, 187],
    [242, 105],
    [196, 131],
    [182, 83],
]

ids = [[2,4,6], [0,2,8]]  # faces to erase by pt-index (clockwise)
dly = vedo.delaunay2D(pts, mode='xy', boundaries=ids)
dly.c('grey5').lc('red4').lw(2)

labels = vedo.Points(pts).labels('id').z(1)

vedo.show(labels, dly, axes=1)

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM