天天看點

vtk實戰(四十九)——使用vtkCell3D建構三維形體

#include <vtkSmartPointer.h>
#include <vtkVersion.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkUnstructuredGrid.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCamera.h>
#include <vtkTextProperty.h>
#include <vtkTextMapper.h>
#include <vtkActor2D.h>
#include <vtkHexagonalPrism.h>
#include <vtkHexahedron.h>
#include <vtkPentagonalPrism.h>
#include <vtkPolyhedron.h>
#include <vtkPyramid.h>
#include <vtkTetra.h>
#include <vtkVoxel.h>
#include <vtkWedge.h>
#include <vector>
#include <string>
#include <cstdlib>

vtkSmartPointer<vtkUnstructuredGrid> MakeHexagonalPrism();
vtkSmartPointer<vtkUnstructuredGrid> MakeHexahedron();
vtkSmartPointer<vtkUnstructuredGrid> MakePentagonalPrism();
vtkSmartPointer<vtkUnstructuredGrid> MakePolyhedron();
vtkSmartPointer<vtkUnstructuredGrid> MakePyramid();
vtkSmartPointer<vtkUnstructuredGrid> MakeTetrahedron();
vtkSmartPointer<vtkUnstructuredGrid> MakeVoxel();
vtkSmartPointer<vtkUnstructuredGrid> MakeWedge();

int main()
{
    std::vector<std::string> titles;
    std::vector<vtkSmartPointer<vtkTextMapper> > textMappers;
    std::vector<vtkSmartPointer<vtkActor2D> > textActors;

    std::vector<vtkSmartPointer<vtkUnstructuredGrid> > uGrids;
    std::vector<vtkSmartPointer<vtkDataSetMapper> > mappers;
    std::vector<vtkSmartPointer<vtkActor> > actors;
    std::vector<vtkSmartPointer<vtkRenderer> > renderers;

    uGrids.push_back(MakeHexagonalPrism());
    titles.push_back("Hexagonal Prism");
    uGrids.push_back(MakeHexahedron());
    titles.push_back("Hexahedron");
    uGrids.push_back(MakePentagonalPrism());
    titles.push_back("Pentagonal Prism");

    uGrids.push_back(MakePolyhedron());
    titles.push_back("Polyhedron");
    uGrids.push_back(MakePyramid());
    titles.push_back("Pyramid");
    uGrids.push_back(MakeTetrahedron());
    titles.push_back("Tetrahedron");

    uGrids.push_back(MakeVoxel());
    titles.push_back("Voxel");
    uGrids.push_back(MakeWedge());
    titles.push_back("Wedge");

    vtkSmartPointer<vtkRenderWindow> renWin =
        vtkSmartPointer<vtkRenderWindow>::New();
    renWin->SetSize(, );
    renWin->SetWindowName("Cell3D Demonstration");

    vtkSmartPointer<vtkRenderWindowInteractor> iRen =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    iRen->SetRenderWindow(renWin);

    // Create one text property for all
    vtkSmartPointer<vtkTextProperty> textProperty =
        vtkSmartPointer<vtkTextProperty>::New();
    textProperty->SetFontSize();
    textProperty->SetJustificationToCentered();

    // Create and link the mappers actors and renderers together.
    for (unsigned int i = ; i < uGrids.size(); ++i)
    {
        textMappers.push_back(vtkSmartPointer<vtkTextMapper>::New());
        textActors.push_back(vtkSmartPointer<vtkActor2D>::New());

        mappers.push_back(vtkSmartPointer<vtkDataSetMapper>::New());
        actors.push_back(vtkSmartPointer<vtkActor>::New());
        renderers.push_back(vtkSmartPointer<vtkRenderer>::New());

#if VTK_MAJOR_VERSION <= 5
        mappers[i]->SetInputConnection(uGrids[i]->GetProducerPort());
#else
        mappers[i]->SetInputData(uGrids[i]);
#endif
        actors[i]->SetMapper(mappers[i]);
        renderers[i]->AddViewProp(actors[i]);

        textMappers[i]->SetInput(titles[i].c_str());
        textActors[i]->SetMapper(textMappers[i]);
        textActors[i]->SetPosition(, );
        renderers[i]->AddViewProp(textActors[i]);

        renWin->AddRenderer(renderers[i]);
    }

    int gridDimensions = ;
    int rendererSize = ;

    renWin->SetSize(
        rendererSize*gridDimensions, rendererSize*gridDimensions);

    for (int row = ; row < gridDimensions; row++)
    {
        for (int col = ; col < gridDimensions; col++)
        {
            int index = row * gridDimensions + col;

            // (xmin, ymin, xmax, ymax)
            double viewport[] =
            { static_cast<double>(col)* rendererSize /
            (gridDimensions * rendererSize),
            static_cast<double>(gridDimensions - (row + )) * rendererSize /
            (gridDimensions * rendererSize),
            static_cast<double>(col + )*rendererSize /
            (gridDimensions * rendererSize),
            static_cast<double>(gridDimensions - row) * rendererSize /
            (gridDimensions * rendererSize) };

            if (index > int(actors.size()) - )
            {
                // Add a renderer even if there is no actor.
                // This makes the render window background all the same color.
                vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
                ren->SetBackground(, , );
                ren->SetViewport(viewport);
                renWin->AddRenderer(ren);
                continue;
            }

            renderers[index]->SetViewport(viewport);
            renderers[index]->SetBackground(, , );
            renderers[index]->ResetCamera();
            renderers[index]->GetActiveCamera()->Azimuth();
            renderers[index]->GetActiveCamera()->Elevation(-);
            renderers[index]->GetActiveCamera()->Zoom();
            renderers[index]->ResetCameraClippingRange();
        }
    }

    iRen->Initialize();

    renWin->Render();

    iRen->Start();

    return EXIT_SUCCESS;
}

vtkSmartPointer<vtkUnstructuredGrid> MakeHexagonalPrism()
{
    // 3D: hexagonal prism: a wedge with an hexagonal base.
    // Be careful, the base face ordering is different from wedge.

    int numberOfVertices = ;

    vtkSmartPointer<vtkPoints> points =
        vtkSmartPointer<vtkPoints>::New();

    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(-, , );

    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(-, , );

    vtkSmartPointer<vtkHexagonalPrism> hexagonalPrism =
        vtkSmartPointer<vtkHexagonalPrism>::New();
    for (int i = ; i < numberOfVertices; ++i)
    {
        hexagonalPrism->GetPointIds()->SetId(i, i);
    }

    vtkSmartPointer<vtkUnstructuredGrid> ug =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    ug->InsertNextCell(hexagonalPrism->GetCellType(),
        hexagonalPrism->GetPointIds());
    ug->SetPoints(points);

    return ug;
}

vtkSmartPointer<vtkUnstructuredGrid> MakeHexahedron()
{
    // A regular hexagon (cube) with all faces square and three squares around
    // each vertex is created below.

    // Setup the coordinates of eight points
    // (the two faces must be in counter clockwise
    // order as viewed from the outside).

    // As an exercise you can modify the coordinates of the points to create
    // seven topologically distinct convex hexahedras.

    int numberOfVertices = ;

    // Create the points
    vtkSmartPointer<vtkPoints> points =
        vtkSmartPointer<vtkPoints>::New();
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );

    // Create a hexahedron from the points
    vtkSmartPointer<vtkHexahedron> hex =
        vtkSmartPointer<vtkHexahedron>::New();
    for (int i = ; i < numberOfVertices; ++i)
    {
        hex->GetPointIds()->SetId(i, i);
    }

    // Add the points and hexahedron to an unstructured grid
    vtkSmartPointer<vtkUnstructuredGrid> uGrid =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    uGrid->SetPoints(points);
    uGrid->InsertNextCell(hex->GetCellType(), hex->GetPointIds());

    return uGrid;
}

vtkSmartPointer<vtkUnstructuredGrid> b()
{

    int numberOfVertices = ;

    // Create the points
    vtkSmartPointer<vtkPoints> points =
        vtkSmartPointer<vtkPoints>::New();
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );

    // Pentagonal Prism
    vtkSmartPointer<vtkPentagonalPrism> pentagonalPrism =
        vtkSmartPointer<vtkPentagonalPrism>::New();
    for (int i = ; i < numberOfVertices; ++i)
    {
        pentagonalPrism->GetPointIds()->SetId(i, i);
    }

    // Add the points and hexahedron to an unstructured grid
    vtkSmartPointer<vtkUnstructuredGrid> uGrid =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    uGrid->SetPoints(points);
    uGrid->InsertNextCell(pentagonalPrism->GetCellType(),
        pentagonalPrism->GetPointIds());

    return uGrid;
}

vtkSmartPointer<vtkUnstructuredGrid> MakePolyhedron()
{

    // Make a regular dodecahedron. It consists of twelve regular pentagonal
    // faces with three faces meeting at each vertex.
    int numberOfVertices = ;
    int numberOfFaces = ;
    int numberOfFaceVertices = ;

    vtkSmartPointer<vtkPoints> points =
        vtkSmartPointer<vtkPoints>::New();
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(-, , );
    points->InsertNextPoint(-, -, );
    points->InsertNextPoint(, -, );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(-, , );
    points->InsertNextPoint(-, -, );
    points->InsertNextPoint(, -, );
    points->InsertNextPoint(, , -);
    points->InsertNextPoint(-, , -);
    points->InsertNextPoint(-, , -);
    points->InsertNextPoint(-, -, -);
    points->InsertNextPoint(, -, -);
    points->InsertNextPoint(, , -);
    points->InsertNextPoint(-, , -);
    points->InsertNextPoint(-, , -);
    points->InsertNextPoint(-, -, -);
    points->InsertNextPoint(, -, -);

    vtkIdType dodechedronPointsIds[] =
    { , , , , , , , , , ,
    , , , , , , , , ,  };


    vtkIdType dodechedronFace[][] = {
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  },
        { , , , ,  }
    };

    vtkSmartPointer<vtkCellArray> dodechedronFaces =
        vtkSmartPointer<vtkCellArray>::New();
    for (int i = ; i < numberOfFaces; i++)
    {
        dodechedronFaces->InsertNextCell(numberOfFaceVertices, dodechedronFace[i]);
    }

    vtkSmartPointer<vtkUnstructuredGrid> uGrid =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    uGrid->InsertNextCell(VTK_POLYHEDRON,
        numberOfVertices, dodechedronPointsIds,
        numberOfFaces, dodechedronFaces->GetPointer());
    uGrid->SetPoints(points);

    return uGrid;
}

vtkSmartPointer<vtkUnstructuredGrid> MakePyramid()
{
    // Make a regular square pyramid.
    int numberOfVertices = ;

    vtkSmartPointer<vtkPoints> points =
        vtkSmartPointer<vtkPoints>::New();

    float p0[] = { , ,  };
    float p1[] = { -, ,  };
    float p2[] = { -, -,  };
    float p3[] = { , -,  };
    float p4[] = { , ,  };

    points->InsertNextPoint(p0);
    points->InsertNextPoint(p1);
    points->InsertNextPoint(p2);
    points->InsertNextPoint(p3);
    points->InsertNextPoint(p4);

    vtkSmartPointer<vtkPyramid> pyramid =
        vtkSmartPointer<vtkPyramid>::New();
    for (int i = ; i < numberOfVertices; ++i)
    {
        pyramid->GetPointIds()->SetId(i, i);
    }

    vtkSmartPointer<vtkUnstructuredGrid> ug =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    ug->SetPoints(points);
    ug->InsertNextCell(pyramid->GetCellType(), pyramid->GetPointIds());

    return ug;
}

vtkSmartPointer<vtkUnstructuredGrid> MakeTetrahedron()
{
    // Make a tetrahedron.
    int numberOfVertices = ;

    vtkSmartPointer< vtkPoints > points =
        vtkSmartPointer< vtkPoints > ::New();
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );

    vtkSmartPointer<vtkTetra> tetra =
        vtkSmartPointer<vtkTetra>::New();
    for (int i = ; i < numberOfVertices; ++i)
    {
        tetra->GetPointIds()->SetId(i, i);
    }

    vtkSmartPointer<vtkCellArray> cellArray =
        vtkSmartPointer<vtkCellArray>::New();
    cellArray->InsertNextCell(tetra);

    vtkSmartPointer<vtkUnstructuredGrid> unstructuredGrid =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    unstructuredGrid->SetPoints(points);
    unstructuredGrid->SetCells(VTK_TETRA, cellArray);

    return unstructuredGrid;
}

vtkSmartPointer<vtkUnstructuredGrid> MakeVoxel()
{
    // A voxel is a representation of a regular grid in 3-D space.
    int numberOfVertices = ;

    vtkSmartPointer<vtkPoints> points =
        vtkSmartPointer<vtkPoints>::New();
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );

    vtkSmartPointer<vtkVoxel> voxel =
        vtkSmartPointer<vtkVoxel>::New();
    for (int i = ; i < numberOfVertices; ++i)
    {
        voxel->GetPointIds()->SetId(i, i);
    }

    vtkSmartPointer<vtkUnstructuredGrid> ug =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    ug->SetPoints(points);
    ug->InsertNextCell(voxel->GetCellType(), voxel->GetPointIds());

    return ug;
}

vtkSmartPointer<vtkUnstructuredGrid> MakeWedge()
{

    // A wedge consists of two triangular ends and three rectangular faces.

    int numberOfVertices = ;

    vtkSmartPointer<vtkPoints> points =
        vtkSmartPointer<vtkPoints>::New();

    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );
    points->InsertNextPoint(, , );

    vtkSmartPointer<vtkWedge> wedge =
        vtkSmartPointer<vtkWedge>::New();
    for (int i = ; i < numberOfVertices; ++i)
    {
        wedge->GetPointIds()->SetId(i, i);
    }

    vtkSmartPointer<vtkUnstructuredGrid> ug =
        vtkSmartPointer<vtkUnstructuredGrid>::New();
    ug->SetPoints(points);
    ug->InsertNextCell(wedge->GetCellType(), wedge->GetPointIds());
    return ug;
}
           
vtk實戰(四十九)——使用vtkCell3D建構三維形體
VTK