Я следую учебному пособию по OpenMesh Первые шаги — Построение куба с несколькими модификациями я использую TriMesh вместо PolyMesh и строю пирамиду вместо куба.
Почему-то я получаю ошибку PolymeshT::add_face:complex edge
для моего второго и третьего лица. Эти грани должны находиться между точками (0,0,0), (0,1,0) и (0,0,1) и точками (0,0,0), (0,0,1) и (1,0,0).
Два ребра уже существуют, когда каждая грань построена (от 0,0,0) до (0,1,0) и (0,0,0) до (0,0,1), но я должен иметь возможность создавать грани, где некоторые края уже существуют, не так ли?
Решения, которые я пробовал до сих пор
Я не могу найти ничего другого, что я делаю иначе, чем учебник.
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
typedef OpenMesh::TriMesh_ArrayKernelT<> MyTriMesh;
// Make a pyramid
int main()
{
MyTriMesh tin;
// generate vertices
MyTriMesh::VertexHandle vhandle[4];
vhandle[0] = tin.add_vertex(MyTriMesh::Point(0, 0, 0));
vhandle[1] = tin.add_vertex(MyTriMesh::Point(0, 1, 0));
vhandle[2] = tin.add_vertex(MyTriMesh::Point(1, 0, 0));
vhandle[3] = tin.add_vertex(MyTriMesh::Point(0, 0, 1));
// generate (trianglar) faces
std::vector<MyTriMesh::VertexHandle> face_vhandles;
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
tin.add_face(face_vhandles);
printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
tin.n_vertices(), tin.n_edges(), tin.n_faces());
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
tin.add_face(face_vhandles);
printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
tin.n_vertices(), tin.n_edges(), tin.n_faces());
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[2]);
tin.add_face(face_vhandles);
printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
tin.n_vertices(), tin.n_edges(), tin.n_faces());
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[2]);
tin.add_face(face_vhandles);
printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
tin.n_vertices(), tin.n_edges(), tin.n_faces());
}
Эта ошибка возникает из-за того, что некоторые вершины граней добавляются в неправильном порядке.
OpenMesh использует полужесткая конструкция для описания 3d-структуры сетки. Полжунки — это направленные ребра между вершинами. Это позволяет пересекать вершины на лице, следуя за пологами, принадлежащими лицу. Однако по этой причине порядок, в котором вершины добавляются к грани, очень важен.
Как правило, вершины всегда должны добавляться в порядке против часовой стрелки. Это приводит к тому, что половинки соседних граней указывают в противоположных направлениях, как на рисунке внизу слева. Если порядок вершин не является последовательным, существует неоднозначность относительно того, какой край следует за полкругом, нижним краем «A» или нижним краем «B», как на рисунке ниже справа.
В коде вопроса грани 1 и 4 упорядочены против часовой стрелки, а грани 2 и 3 — по часовой стрелке. Простое решение заключается в переключении первой и третьей вершин для этих двух граней.
face_vhandles.clear();
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[0]);
tin.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[0]);
tin.add_face(face_vhandles);