繁体   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