简体   繁体   English

如何正确使用VTK ConstrainedDelaunay2D?

[英]How to correctly use VTK ConstrainedDelaunay2D?

I've started from the VTK ConstrainedDelaunay2D example and added my own points:我从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;
} 

I'm experiencing two issues:我遇到两个问题:

  1. I get different results if I flip the Y coordinates: why is that?如果我翻转 Y 坐标,我会得到不同的结果:这是为什么?
  2. Why are there faces pointing in the wrong direction (flipped normal / wrong winding )?为什么有些面指向错误的方向(翻转正常/错误绕组)?

Here's what I mean by the 1st issue:这是我对第一期的意思:

5 个尖头不规则 polygan(星形)用几个翻转的三角形三角化

5 个尖锐的不规则多边形(星形)用几个翻转的三角形三角化,但在 Y 轴上旋转 180 度

If I don't flip the Y coordinates I get this:如果我不翻转 Y 坐标,我会得到这个:

3 个三角形作为未知三角测量结果(而不是 5 个尖形)

3 个三角形作为未知三角测量结果(而不是 5 个尖形,但在 Y 轴上旋转 180 度

I get the same effect if I don't flip the Y axis but insert the boundary polygon in reverse order:如果我不翻转 Y 轴而是以相反的顺序插入边界多边形,我会得到相同的效果:

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

I don't think I fully understand how the boundary/constraint works.我不认为我完全理解边界/约束是如何工作的。 I thoght that the same points should produce the same triangulation wether the vertices are flipped vertically or not.我认为无论顶点是否垂直翻转,相同的点都应该产生相同的三角剖分。 (I suspect the order of indices changes then?) (我怀疑指数的顺序会改变吗?)

Regarding the second issue (unpredictable flipped faces) I'm not sure what the best way forward is.关于第二个问题(不可预测的翻转面孔),我不确定最好的方法是什么。 I had a look at the vtkDelaunay2D class and couldn't find anything related.我查看了vtkDelaunay2D class,但找不到任何相关内容。 (I've tried setting projection plane mode to VTK_DELAUNAY_XY_PLANE , but it didn't seem to affect the output) (我已经尝试将投影平面模式设置为VTK_DELAUNAY_XY_PLANE ,但它似乎并没有影响输出)

I've also tried to use vtkPolyDataNormals but got no output:我也尝试过使用vtkPolyDataNormals但没有得到 output:

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

( normalGenerator 's output has 0 cells and points) normalGenerator的 output 有 0 个单元格和点)

Is there a way to compute constrained delaunay triangulation for a list of 2d points and ensure all the faces point the same way?有没有一种方法可以计算二维点列表的约束 delaunay 三角剖分并确保所有面都指向相同的方向? (If so, how? Would it be possible to do this with the vtkDelaunay2D class alone or is it necessary to use other filters?) (如果是这样,怎么做?是否可以单独使用vtkDelaunay2D class 或是否有必要使用其他过滤器?)

Any hints/tips are more than welcome:)任何提示/技巧都非常受欢迎:)

I'm using VTK 8.2 by the way.顺便说一下,我正在使用 VTK 8.2。

the flipping in y effectively reverses the faces orientation (what is clockwise becomes anti-clockwise, like in a mirror). y 的翻转有效地反转了面的方向(顺时针方向变成逆时针方向,就像在镜子中一样)。 I'm not sure I can reproduce your example above.我不确定我能否重现您上面的示例。 A quick test in python seems to give the expected behavior, maybe you can start from this and map it to your c++ version: 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