Skip to content

Commit b524e26

Browse files
committed
Fem: Use mixed cell types in pipeline unstructured grid - fixes FreeCAD#12581
1 parent 0420f72 commit b524e26

File tree

1 file changed

+46
-72
lines changed

1 file changed

+46
-72
lines changed

src/Mod/Fem/App/FemVTKTools.cpp

+46-72
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <vtkQuadraticWedge.h>
5252
#include <vtkTetra.h>
5353
#include <vtkTriangle.h>
54+
#include <vtkUnsignedCharArray.h>
5455
#include <vtkUnstructuredGrid.h>
5556
#include <vtkWedge.h>
5657
#include <vtkXMLPUnstructuredGridReader.h>
@@ -309,10 +310,8 @@ void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
309310
{
310311
Base::Console().Log(" Start: VTK mesh builder faces.\n");
311312

312-
vtkSmartPointer<vtkCellArray> triangleArray = vtkSmartPointer<vtkCellArray>::New();
313-
vtkSmartPointer<vtkCellArray> quadTriangleArray = vtkSmartPointer<vtkCellArray>::New();
314-
vtkSmartPointer<vtkCellArray> quadArray = vtkSmartPointer<vtkCellArray>::New();
315-
vtkSmartPointer<vtkCellArray> quadQuadArray = vtkSmartPointer<vtkCellArray>::New();
313+
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
314+
std::vector<int> types;
316315

317316
for (; aFaceIter->more();) {
318317
const SMDS_MeshFace* aFace = aFaceIter->next();
@@ -324,7 +323,8 @@ void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
324323
tria->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID() - 1);
325324
tria->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID() - 1);
326325

327-
triangleArray->InsertNextCell(tria);
326+
elemArray->InsertNextCell(tria);
327+
types.push_back(VTK_TRIANGLE);
328328
}
329329
// quad
330330
else if (aFace->NbNodes() == 4) {
@@ -334,7 +334,8 @@ void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
334334
quad->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID() - 1);
335335
quad->GetPointIds()->SetId(3, aFace->GetNode(3)->GetID() - 1);
336336

337-
quadArray->InsertNextCell(quad);
337+
elemArray->InsertNextCell(quad);
338+
types.push_back(VTK_QUAD);
338339
}
339340
// quadratic triangle
340341
else if (aFace->NbNodes() == 6) {
@@ -346,7 +347,9 @@ void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
346347
tria->GetPointIds()->SetId(3, aFace->GetNode(3)->GetID() - 1);
347348
tria->GetPointIds()->SetId(4, aFace->GetNode(4)->GetID() - 1);
348349
tria->GetPointIds()->SetId(5, aFace->GetNode(5)->GetID() - 1);
349-
quadTriangleArray->InsertNextCell(tria);
350+
351+
elemArray->InsertNextCell(tria);
352+
types.push_back(VTK_QUADRATIC_TRIANGLE);
350353
}
351354
// quadratic quad
352355
else if (aFace->NbNodes() == 8) {
@@ -360,26 +363,16 @@ void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
360363
quad->GetPointIds()->SetId(6, aFace->GetNode(6)->GetID() - 1);
361364
quad->GetPointIds()->SetId(7, aFace->GetNode(7)->GetID() - 1);
362365

363-
quadQuadArray->InsertNextCell(quad);
366+
elemArray->InsertNextCell(quad);
367+
types.push_back(VTK_QUADRATIC_QUAD);
364368
}
365369
else {
366-
throw std::runtime_error("Face not yet supported by FreeCAD's VTK mesh builder\n");
370+
throw Base::TypeError("Face not yet supported by FreeCAD's VTK mesh builder\n");
367371
}
368372
}
369-
if (triangleArray->GetNumberOfCells() > 0) {
370-
grid->SetCells(VTK_TRIANGLE, triangleArray);
371-
}
372-
373-
if (quadArray->GetNumberOfCells() > 0) {
374-
grid->SetCells(VTK_QUAD, quadArray);
375-
}
376373

377-
if (quadTriangleArray->GetNumberOfCells() > 0) {
378-
grid->SetCells(VTK_QUADRATIC_TRIANGLE, quadTriangleArray);
379-
}
380-
381-
if (quadQuadArray->GetNumberOfCells() > 0) {
382-
grid->SetCells(VTK_QUADRATIC_QUAD, quadQuadArray);
374+
if (elemArray->GetNumberOfCells() > 0) {
375+
grid->SetCells(types.data(), elemArray);
383376
}
384377

385378
Base::Console().Log(" End: VTK mesh builder faces.\n");
@@ -390,14 +383,8 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
390383
{
391384
Base::Console().Log(" Start: VTK mesh builder volumes.\n");
392385

393-
vtkSmartPointer<vtkCellArray> tetraArray = vtkSmartPointer<vtkCellArray>::New();
394-
vtkSmartPointer<vtkCellArray> pyramidArray = vtkSmartPointer<vtkCellArray>::New();
395-
vtkSmartPointer<vtkCellArray> wedgeArray = vtkSmartPointer<vtkCellArray>::New();
396-
vtkSmartPointer<vtkCellArray> hexaArray = vtkSmartPointer<vtkCellArray>::New();
397-
vtkSmartPointer<vtkCellArray> quadTetraArray = vtkSmartPointer<vtkCellArray>::New();
398-
vtkSmartPointer<vtkCellArray> quadPyramidArray = vtkSmartPointer<vtkCellArray>::New();
399-
vtkSmartPointer<vtkCellArray> quadWedgeArray = vtkSmartPointer<vtkCellArray>::New();
400-
vtkSmartPointer<vtkCellArray> quadHexaArray = vtkSmartPointer<vtkCellArray>::New();
386+
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
387+
std::vector<int> types;
401388

402389
for (; aVolIter->more();) {
403390
const SMDS_MeshVolume* aVol = aVolIter->next();
@@ -409,7 +396,9 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
409396
cell->GetPointIds()->SetId(1, aVol->GetNode(1)->GetID() - 1);
410397
cell->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID() - 1);
411398
cell->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID() - 1);
412-
tetraArray->InsertNextCell(cell);
399+
400+
elemArray->InsertNextCell(cell);
401+
types.push_back(VTK_TETRA);
413402
}
414403
else if (aVol->NbNodes() == 5) { // pyra5
415404
Base::Console().Log(" Volume pyra5\n");
@@ -419,7 +408,9 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
419408
cell->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID() - 1);
420409
cell->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID() - 1);
421410
cell->GetPointIds()->SetId(4, aVol->GetNode(4)->GetID() - 1);
422-
pyramidArray->InsertNextCell(cell);
411+
412+
elemArray->InsertNextCell(cell);
413+
types.push_back(VTK_PYRAMID);
423414
}
424415
else if (aVol->NbNodes() == 6) { // penta6
425416
Base::Console().Log(" Volume penta6\n");
@@ -430,7 +421,9 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
430421
cell->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID() - 1);
431422
cell->GetPointIds()->SetId(4, aVol->GetNode(4)->GetID() - 1);
432423
cell->GetPointIds()->SetId(5, aVol->GetNode(5)->GetID() - 1);
433-
wedgeArray->InsertNextCell(cell);
424+
425+
elemArray->InsertNextCell(cell);
426+
types.push_back(VTK_WEDGE);
434427
}
435428
else if (aVol->NbNodes() == 8) { // hexa8
436429
Base::Console().Log(" Volume hexa8\n");
@@ -443,33 +436,40 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
443436
cell->GetPointIds()->SetId(5, aVol->GetNode(5)->GetID() - 1);
444437
cell->GetPointIds()->SetId(6, aVol->GetNode(6)->GetID() - 1);
445438
cell->GetPointIds()->SetId(7, aVol->GetNode(7)->GetID() - 1);
446-
hexaArray->InsertNextCell(cell);
439+
440+
elemArray->InsertNextCell(cell);
441+
types.push_back(VTK_HEXAHEDRON);
447442
}
448443
else if (aVol->NbNodes() == 10) { // tetra10
449444
Base::Console().Log(" Volume tetra10\n");
450-
vtkSmartPointer<vtkQuadraticTetra> tetra = vtkSmartPointer<vtkQuadraticTetra>::New();
445+
vtkSmartPointer<vtkQuadraticTetra> cell = vtkSmartPointer<vtkQuadraticTetra>::New();
451446
for (int i = 0; i < 10; i++) {
452-
tetra->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
447+
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
453448
}
454-
quadTetraArray->InsertNextCell(tetra);
449+
450+
elemArray->InsertNextCell(cell);
451+
types.push_back(VTK_QUADRATIC_TETRA);
455452
}
456453

457454
else if (aVol->NbNodes() == 13) { // pyra13
458455
Base::Console().Log(" Volume pyra13\n");
459456
vtkSmartPointer<vtkQuadraticPyramid> cell = vtkSmartPointer<vtkQuadraticPyramid>::New();
460457
for (int i = 0; i < 13; i++) {
461458
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
462-
// Base::Console().Log("node ids: %i\n", aVol->GetNode(i)->GetID()-1);
463459
}
464-
quadPyramidArray->InsertNextCell(cell);
460+
461+
elemArray->InsertNextCell(cell);
462+
types.push_back(VTK_QUADRATIC_PYRAMID);
465463
}
466464
else if (aVol->NbNodes() == 15) { // penta15
467465
Base::Console().Log(" Volume penta15\n");
468466
vtkSmartPointer<vtkQuadraticWedge> cell = vtkSmartPointer<vtkQuadraticWedge>::New();
469467
for (int i = 0; i < 15; i++) {
470468
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
471469
}
472-
quadWedgeArray->InsertNextCell(cell);
470+
471+
elemArray->InsertNextCell(cell);
472+
types.push_back(VTK_QUADRATIC_WEDGE);
473473
}
474474
else if (aVol->NbNodes() == 20) { // hexa20
475475
Base::Console().Log(" Volume hexa20\n");
@@ -478,43 +478,17 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
478478
for (int i = 0; i < 20; i++) {
479479
cell->GetPointIds()->SetId(i, aVol->GetNode(i)->GetID() - 1);
480480
}
481-
quadHexaArray->InsertNextCell(cell);
481+
482+
elemArray->InsertNextCell(cell);
483+
types.push_back(VTK_QUADRATIC_HEXAHEDRON);
482484
}
483485
else {
484-
throw std::runtime_error("Volume not yet supported by FreeCAD's VTK mesh builder\n");
486+
throw Base::TypeError("Volume not yet supported by FreeCAD's VTK mesh builder\n");
485487
}
486488
}
487489

488-
if (tetraArray->GetNumberOfCells() > 0) {
489-
grid->SetCells(VTK_TETRA, tetraArray);
490-
}
491-
492-
if (pyramidArray->GetNumberOfCells() > 0) {
493-
grid->SetCells(VTK_PYRAMID, pyramidArray);
494-
}
495-
496-
if (wedgeArray->GetNumberOfCells() > 0) {
497-
grid->SetCells(VTK_WEDGE, wedgeArray);
498-
}
499-
500-
if (hexaArray->GetNumberOfCells() > 0) {
501-
grid->SetCells(VTK_HEXAHEDRON, hexaArray);
502-
}
503-
504-
if (quadTetraArray->GetNumberOfCells() > 0) {
505-
grid->SetCells(VTK_QUADRATIC_TETRA, quadTetraArray);
506-
}
507-
508-
if (quadPyramidArray->GetNumberOfCells() > 0) {
509-
grid->SetCells(VTK_QUADRATIC_PYRAMID, quadPyramidArray);
510-
}
511-
512-
if (quadWedgeArray->GetNumberOfCells() > 0) {
513-
grid->SetCells(VTK_QUADRATIC_WEDGE, quadWedgeArray);
514-
}
515-
516-
if (quadHexaArray->GetNumberOfCells() > 0) {
517-
grid->SetCells(VTK_QUADRATIC_HEXAHEDRON, quadHexaArray);
490+
if (elemArray->GetNumberOfCells() > 0) {
491+
grid->SetCells(types.data(), elemArray);
518492
}
519493

520494
Base::Console().Log(" End: VTK mesh builder volumes.\n");

0 commit comments

Comments
 (0)