Skip to content

Commit 1ab6287

Browse files
committed
Fem: Export mesh elements to Vtk using proper order
1 parent 5b5be48 commit 1ab6287

File tree

1 file changed

+51
-130
lines changed

1 file changed

+51
-130
lines changed

src/Mod/Fem/App/FemVTKTools.cpp

+51-130
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,31 @@ void writeVTKFile(const char* filename, vtkSmartPointer<vtkUnstructuredGrid> dat
9797
writer->Write();
9898
}
9999

100+
namespace
101+
{
102+
103+
// Helper function to fill vtkCellArray from SMDS_Mesh using vtk cell order
104+
template<typename T, typename E>
105+
void fillVtkArray(vtkSmartPointer<vtkCellArray>& elemArray, std::vector<int>& types, const E* elem)
106+
{
107+
vtkSmartPointer<T> cell = vtkSmartPointer<T>::New();
108+
const std::vector<int>& order = SMDS_MeshCell::toVtkOrder(elem->GetEntityType());
109+
if (!order.empty()) {
110+
for (int i = 0; i < elem->NbNodes(); ++i) {
111+
cell->GetPointIds()->SetId(i, elem->GetNode(order[i])->GetID() - 1);
112+
}
113+
}
114+
else {
115+
for (int i = 0; i < elem->NbNodes(); ++i) {
116+
cell->GetPointIds()->SetId(i, elem->GetNode(i)->GetID() - 1);
117+
}
118+
}
119+
elemArray->InsertNextCell(cell);
120+
types.push_back(SMDS_MeshCell::toVtkType(elem->GetEntityType()));
121+
}
122+
123+
} // namespace
124+
100125

101126
void FemVTKTools::importVTKMesh(vtkSmartPointer<vtkDataSet> dataset, FemMesh* mesh, float scale)
102127
{
@@ -314,58 +339,23 @@ void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
314339
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
315340
std::vector<int> types;
316341

317-
for (; aFaceIter->more();) {
342+
while (aFaceIter->more()) {
318343
const SMDS_MeshFace* aFace = aFaceIter->next();
319-
320344
// triangle
321-
if (aFace->NbNodes() == 3) {
322-
vtkSmartPointer<vtkTriangle> tria = vtkSmartPointer<vtkTriangle>::New();
323-
tria->GetPointIds()->SetId(0, aFace->GetNode(0)->GetID() - 1);
324-
tria->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID() - 1);
325-
tria->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID() - 1);
326-
327-
elemArray->InsertNextCell(tria);
328-
types.push_back(VTK_TRIANGLE);
345+
if (aFace->GetEntityType() == SMDSEntity_Triangle) {
346+
fillVtkArray<vtkTriangle>(elemArray, types, aFace);
329347
}
330348
// quad
331-
else if (aFace->NbNodes() == 4) {
332-
vtkSmartPointer<vtkQuad> quad = vtkSmartPointer<vtkQuad>::New();
333-
quad->GetPointIds()->SetId(0, aFace->GetNode(0)->GetID() - 1);
334-
quad->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID() - 1);
335-
quad->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID() - 1);
336-
quad->GetPointIds()->SetId(3, aFace->GetNode(3)->GetID() - 1);
337-
338-
elemArray->InsertNextCell(quad);
339-
types.push_back(VTK_QUAD);
349+
else if (aFace->GetEntityType() == SMDSEntity_Quadrangle) {
350+
fillVtkArray<vtkQuad>(elemArray, types, aFace);
340351
}
341352
// quadratic triangle
342-
else if (aFace->NbNodes() == 6) {
343-
vtkSmartPointer<vtkQuadraticTriangle> tria =
344-
vtkSmartPointer<vtkQuadraticTriangle>::New();
345-
tria->GetPointIds()->SetId(0, aFace->GetNode(0)->GetID() - 1);
346-
tria->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID() - 1);
347-
tria->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID() - 1);
348-
tria->GetPointIds()->SetId(3, aFace->GetNode(3)->GetID() - 1);
349-
tria->GetPointIds()->SetId(4, aFace->GetNode(4)->GetID() - 1);
350-
tria->GetPointIds()->SetId(5, aFace->GetNode(5)->GetID() - 1);
351-
352-
elemArray->InsertNextCell(tria);
353-
types.push_back(VTK_QUADRATIC_TRIANGLE);
353+
else if (aFace->GetEntityType() == SMDSEntity_Quad_Triangle) {
354+
fillVtkArray<vtkQuadraticTriangle>(elemArray, types, aFace);
354355
}
355356
// quadratic quad
356-
else if (aFace->NbNodes() == 8) {
357-
vtkSmartPointer<vtkQuadraticQuad> quad = vtkSmartPointer<vtkQuadraticQuad>::New();
358-
quad->GetPointIds()->SetId(0, aFace->GetNode(0)->GetID() - 1);
359-
quad->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID() - 1);
360-
quad->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID() - 1);
361-
quad->GetPointIds()->SetId(3, aFace->GetNode(3)->GetID() - 1);
362-
quad->GetPointIds()->SetId(4, aFace->GetNode(4)->GetID() - 1);
363-
quad->GetPointIds()->SetId(5, aFace->GetNode(5)->GetID() - 1);
364-
quad->GetPointIds()->SetId(6, aFace->GetNode(6)->GetID() - 1);
365-
quad->GetPointIds()->SetId(7, aFace->GetNode(7)->GetID() - 1);
366-
367-
elemArray->InsertNextCell(quad);
368-
types.push_back(VTK_QUADRATIC_QUAD);
357+
else if (aFace->GetEntityType() == SMDSEntity_Quad_Quadrangle) {
358+
fillVtkArray<vtkQuadraticQuad>(elemArray, types, aFace);
369359
}
370360
else {
371361
throw Base::TypeError("Face not yet supported by FreeCAD's VTK mesh builder\n");
@@ -387,101 +377,32 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
387377
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
388378
std::vector<int> types;
389379

390-
for (; aVolIter->more();) {
380+
while (aVolIter->more()) {
391381
const SMDS_MeshVolume* aVol = aVolIter->next();
392382

393-
if (aVol->NbNodes() == 4) { // tetra4
394-
Base::Console().Log(" Volume tetra4\n");
395-
vtkSmartPointer<vtkTetra> cell = vtkSmartPointer<vtkTetra>::New();
396-
cell->GetPointIds()->SetId(0, aVol->GetNode(0)->GetID() - 1);
397-
cell->GetPointIds()->SetId(1, aVol->GetNode(1)->GetID() - 1);
398-
cell->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID() - 1);
399-
cell->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID() - 1);
400-
401-
elemArray->InsertNextCell(cell);
402-
types.push_back(VTK_TETRA);
383+
if (aVol->GetEntityType() == SMDSEntity_Tetra) { // tetra4
384+
fillVtkArray<vtkTetra>(elemArray, types, aVol);
403385
}
404-
else if (aVol->NbNodes() == 5) { // pyra5
405-
Base::Console().Log(" Volume pyra5\n");
406-
vtkSmartPointer<vtkPyramid> cell = vtkSmartPointer<vtkPyramid>::New();
407-
cell->GetPointIds()->SetId(0, aVol->GetNode(0)->GetID() - 1);
408-
cell->GetPointIds()->SetId(1, aVol->GetNode(1)->GetID() - 1);
409-
cell->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID() - 1);
410-
cell->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID() - 1);
411-
cell->GetPointIds()->SetId(4, aVol->GetNode(4)->GetID() - 1);
412-
413-
elemArray->InsertNextCell(cell);
414-
types.push_back(VTK_PYRAMID);
386+
else if (aVol->GetEntityType() == SMDSEntity_Pyramid) { // pyra5
387+
fillVtkArray<vtkPyramid>(elemArray, types, aVol);
415388
}
416-
else if (aVol->NbNodes() == 6) { // penta6
417-
Base::Console().Log(" Volume penta6\n");
418-
vtkSmartPointer<vtkWedge> cell = vtkSmartPointer<vtkWedge>::New();
419-
cell->GetPointIds()->SetId(0, aVol->GetNode(0)->GetID() - 1);
420-
cell->GetPointIds()->SetId(1, aVol->GetNode(1)->GetID() - 1);
421-
cell->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID() - 1);
422-
cell->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID() - 1);
423-
cell->GetPointIds()->SetId(4, aVol->GetNode(4)->GetID() - 1);
424-
cell->GetPointIds()->SetId(5, aVol->GetNode(5)->GetID() - 1);
425-
426-
elemArray->InsertNextCell(cell);
427-
types.push_back(VTK_WEDGE);
389+
else if (aVol->GetEntityType() == SMDSEntity_Penta) { // penta6
390+
fillVtkArray<vtkWedge>(elemArray, types, aVol);
428391
}
429-
else if (aVol->NbNodes() == 8) { // hexa8
430-
Base::Console().Log(" Volume hexa8\n");
431-
vtkSmartPointer<vtkHexahedron> cell = vtkSmartPointer<vtkHexahedron>::New();
432-
cell->GetPointIds()->SetId(0, aVol->GetNode(0)->GetID() - 1);
433-
cell->GetPointIds()->SetId(1, aVol->GetNode(1)->GetID() - 1);
434-
cell->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID() - 1);
435-
cell->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID() - 1);
436-
cell->GetPointIds()->SetId(4, aVol->GetNode(4)->GetID() - 1);
437-
cell->GetPointIds()->SetId(5, aVol->GetNode(5)->GetID() - 1);
438-
cell->GetPointIds()->SetId(6, aVol->GetNode(6)->GetID() - 1);
439-
cell->GetPointIds()->SetId(7, aVol->GetNode(7)->GetID() - 1);
440-
441-
elemArray->InsertNextCell(cell);
442-
types.push_back(VTK_HEXAHEDRON);
392+
else if (aVol->GetEntityType() == SMDSEntity_Hexa) { // hexa8
393+
fillVtkArray<vtkHexahedron>(elemArray, types, aVol);
443394
}
444-
else if (aVol->NbNodes() == 10) { // tetra10
445-
Base::Console().Log(" Volume tetra10\n");
446-
vtkSmartPointer<vtkQuadraticTetra> cell = vtkSmartPointer<vtkQuadraticTetra>::New();
447-
for (int i = 0; i < 10; i++) {
448-
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
449-
}
450-
451-
elemArray->InsertNextCell(cell);
452-
types.push_back(VTK_QUADRATIC_TETRA);
395+
else if (aVol->GetEntityType() == SMDSEntity_Quad_Tetra) { // tetra10
396+
fillVtkArray<vtkQuadraticTetra>(elemArray, types, aVol);
453397
}
454-
455-
else if (aVol->NbNodes() == 13) { // pyra13
456-
Base::Console().Log(" Volume pyra13\n");
457-
vtkSmartPointer<vtkQuadraticPyramid> cell = vtkSmartPointer<vtkQuadraticPyramid>::New();
458-
for (int i = 0; i < 13; i++) {
459-
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
460-
}
461-
462-
elemArray->InsertNextCell(cell);
463-
types.push_back(VTK_QUADRATIC_PYRAMID);
398+
else if (aVol->GetEntityType() == SMDSEntity_Quad_Pyramid) { // pyra13
399+
fillVtkArray<vtkQuadraticPyramid>(elemArray, types, aVol);
464400
}
465-
else if (aVol->NbNodes() == 15) { // penta15
466-
Base::Console().Log(" Volume penta15\n");
467-
vtkSmartPointer<vtkQuadraticWedge> cell = vtkSmartPointer<vtkQuadraticWedge>::New();
468-
for (int i = 0; i < 15; i++) {
469-
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
470-
}
471-
472-
elemArray->InsertNextCell(cell);
473-
types.push_back(VTK_QUADRATIC_WEDGE);
401+
else if (aVol->GetEntityType() == SMDSEntity_Quad_Penta) { // penta15
402+
fillVtkArray<vtkQuadraticWedge>(elemArray, types, aVol);
474403
}
475-
else if (aVol->NbNodes() == 20) { // hexa20
476-
Base::Console().Log(" Volume hexa20\n");
477-
vtkSmartPointer<vtkQuadraticHexahedron> cell =
478-
vtkSmartPointer<vtkQuadraticHexahedron>::New();
479-
for (int i = 0; i < 20; i++) {
480-
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
481-
}
482-
483-
elemArray->InsertNextCell(cell);
484-
types.push_back(VTK_QUADRATIC_HEXAHEDRON);
404+
else if (aVol->GetEntityType() == SMDSEntity_Quad_Hexa) { // hexa20
405+
fillVtkArray<vtkQuadraticHexahedron>(elemArray, types, aVol);
485406
}
486407
else {
487408
throw Base::TypeError("Volume not yet supported by FreeCAD's VTK mesh builder\n");

0 commit comments

Comments
 (0)