vtkButterflySubdivisionFilter displays incorrect shape.

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

vtkButterflySubdivisionFilter displays incorrect shape.

madz
I have a 3D contour plot which I'm plotting with several point values. To give the image a more smoother interpolated look I applied the vtkButterflySubdivisionFilter. However, after applying the filter, the shape of the grid looks altered. I noticed that it renders a butterfly shape (hence the name?) to the grid. The following is an example to highlight the problem.

#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkDelaunay2D.h>
#include <vtkLookupTable.h>
#include <vtkMath.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkCubeAxesActor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>
#include <vtkButterflySubdivisionFilter.h>

int main(int, char *[])
{
        // Create a grid of points (height/terrian map)
        vtkSmartPointer<vtkPoints> points =
                vtkSmartPointer<vtkPoints>::New();

        unsigned int GridSize = 5;
        double xx, yy, zz;

        points->InsertNextPoint(0, 0, 0.5);
        points->InsertNextPoint(0, 1, 0.5);
        points->InsertNextPoint(0, 2, 0.5);
        points->InsertNextPoint(1, 0, 0.5);
        points->InsertNextPoint(1, 1, 0.5);
        points->InsertNextPoint(1, 2, 0.5);
        points->InsertNextPoint(2, 0, 0.5);
        points->InsertNextPoint(2, 1, 0.5);
        points->InsertNextPoint(2, 2, 0.5);
        points->InsertNextPoint(3, 0, 0.5);
        points->InsertNextPoint(3, 1, 0.5);
        points->InsertNextPoint(3, 2, 0.5);
       

        // Add the grid points to a polydata object
        vtkSmartPointer<vtkPolyData> inputPolyData = vtkSmartPointer<vtkPolyData>::New();
        inputPolyData->SetPoints(points);

        // Triangulate the grid points
        vtkSmartPointer<vtkDelaunay2D> delaunay = vtkSmartPointer<vtkDelaunay2D>::New();
#if VTK_MAJOR_VERSION <= 5
        delaunay->SetInput(inputPolyData);
#else
        delaunay->SetInputData(inputPolyData);
#endif
        delaunay->Update();
        vtkPolyData* outputPolyData = delaunay->GetOutput();

        double bounds[6];
        outputPolyData->GetBounds(bounds);

        // Find min and max z
        double minz = bounds[4];
        double maxz = bounds[5];

        // Create the color map
        vtkSmartPointer<vtkLookupTable> colorLookupTable =
                vtkSmartPointer<vtkLookupTable>::New();
        colorLookupTable->SetTableRange(minz, maxz);
        colorLookupTable->Build();

        // Generate the colors for each point based on the color map
        vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
        colors->SetNumberOfComponents(3);
        colors->SetName("Colors");

        std::cout << "There are " << outputPolyData->GetNumberOfPoints()
                << " points." << std::endl;

        for(int i = 0; i < outputPolyData->GetNumberOfPoints(); i++)
        {
                double p[3];
                outputPolyData->GetPoint(i,p);

                double dcolor[3];
                colorLookupTable->GetColor(p[2], dcolor);
                unsigned char color[3];
                for(unsigned int j = 0; j < 3; j++)
                {
                        color[j] = static_cast<unsigned char>(255.0 * dcolor[j]);
                }

                colors->InsertNextTupleValue(color);
        }

        outputPolyData->GetPointData()->SetScalars(colors);

        vtkSmartPointer<vtkCubeAxesActor> axes = vtkSmartPointer<vtkCubeAxesActor>::New();
        axes->SetBounds(delaunay->GetOutput()->GetBounds());
        axes->SetFlyModeToOuterEdges();

        axes->XAxisMinorTickVisibilityOff();
        axes->YAxisMinorTickVisibilityOff();
        axes->ZAxisMinorTickVisibilityOff();
        axes->SetXLabelFormat("%6.1f");


 vtkSmartPointer<vtkButterflySubdivisionFilter> subdivide = vtkSmartPointer<vtkButterflySubdivisionFilter>::New();
  subdivide->SetNumberOfSubdivisions(3);
#if VTK_MAJOR_VERSION <= 5
  subdivide->SetInputConnection(outputPolyData->GetProducerPort());
#else
  subdivide->SetInputData(outputPolyData);
#endif

  // Create a mapper and actor
  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(subdivide->GetOutputPort());

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
        actor->SetMapper(mapper);

        // 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);

        //prevents the pointer option from going haywire
        vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
        renderWindowInteractor->SetInteractorStyle(style);

        // Add the actor to the scene
        renderer->AddActor(actor);
        renderer->SetBackground(.1, .2, .3);

        // Render and interact
        renderWindow->Render();

        renderer->GetActiveCamera()->Elevation(290);
        renderer->AddViewProp(axes);
        axes->SetCamera(renderer->GetActiveCamera());

        renderWindowInteractor->Start();

        return EXIT_SUCCESS;
}

As you can see in the following image the maximum point values of the shape is altered, I don't want those values altered in my plot. How do I avoid it.


Normal image without subdivision and with ButterflySubdivision.

    


Thank you.
Reply | Threaded
Open this post in threaded view
|

Re: vtkButterflySubdivisionFilter displays incorrect shape.

Bill Lorensen
Although the the surface will pass through the original points,
evaluated positions between the points might overshoot. This is the
nature of smooth interpolation.

You can use LinearSubdivisionFilter, which  wiki produce more
triangles, the the resulting surface will not be smooth.

On Mon, Dec 2, 2013 at 3:49 AM, madz <[hidden email]> wrote:

> I have a 3D contour plot which I'm plotting with several point values. To
> give the image a more smoother interpolated look I applied the
> vtkButterflySubdivisionFilter. However, after applying the filter, the shape
> of the grid looks altered. I noticed that it renders a butterfly shape
> (hence the name?) to the grid. The following is an example to highlight the
> problem.
>
> #include <vtkSmartPointer.h>
> #include <vtkActor.h>
> #include <vtkDelaunay2D.h>
> #include <vtkLookupTable.h>
> #include <vtkMath.h>
> #include <vtkPoints.h>
> #include <vtkPolyData.h>
> #include <vtkPolyDataMapper.h>
> #include <vtkRenderWindow.h>
> #include <vtkRenderWindowInteractor.h>
> #include <vtkRenderer.h>
> #include <vtkCubeAxesActor.h>
> #include <vtkInteractorStyleTrackballCamera.h>
> #include <vtkCamera.h>
> #include <vtkButterflySubdivisionFilter.h>
>
> int main(int, char *[])
> {
>         // Create a grid of points (height/terrian map)
>         vtkSmartPointer<vtkPoints> points =
>                 vtkSmartPointer<vtkPoints>::New();
>
>         unsigned int GridSize = 5;
>         double xx, yy, zz;
>
>         points->InsertNextPoint(0, 0, 0.5);
>         points->InsertNextPoint(0, 1, 0.5);
>         points->InsertNextPoint(0, 2, 0.5);
>         points->InsertNextPoint(1, 0, 0.5);
>         points->InsertNextPoint(1, 1, 0.5);
>         points->InsertNextPoint(1, 2, 0.5);
>         points->InsertNextPoint(2, 0, 0.5);
>         points->InsertNextPoint(2, 1, 0.5);
>         points->InsertNextPoint(2, 2, 0.5);
>         points->InsertNextPoint(3, 0, 0.5);
>         points->InsertNextPoint(3, 1, 0.5);
>         points->InsertNextPoint(3, 2, 0.5);
>
>
>         // Add the grid points to a polydata object
>         vtkSmartPointer<vtkPolyData> inputPolyData =
> vtkSmartPointer<vtkPolyData>::New();
>         inputPolyData->SetPoints(points);
>
>         // Triangulate the grid points
>         vtkSmartPointer<vtkDelaunay2D> delaunay =
> vtkSmartPointer<vtkDelaunay2D>::New();
> #if VTK_MAJOR_VERSION <= 5
>         delaunay->SetInput(inputPolyData);
> #else
>         delaunay->SetInputData(inputPolyData);
> #endif
>         delaunay->Update();
>         vtkPolyData* outputPolyData = delaunay->GetOutput();
>
>         double bounds[6];
>         outputPolyData->GetBounds(bounds);
>
>         // Find min and max z
>         double minz = bounds[4];
>         double maxz = bounds[5];
>
>         // Create the color map
>         vtkSmartPointer<vtkLookupTable> colorLookupTable =
>                 vtkSmartPointer<vtkLookupTable>::New();
>         colorLookupTable->SetTableRange(minz, maxz);
>         colorLookupTable->Build();
>
>         // Generate the colors for each point based on the color map
>         vtkSmartPointer<vtkUnsignedCharArray> colors =
> vtkSmartPointer<vtkUnsignedCharArray>::New();
>         colors->SetNumberOfComponents(3);
>         colors->SetName("Colors");
>
>         std::cout << "There are " << outputPolyData->GetNumberOfPoints()
>                 << " points." << std::endl;
>
>         for(int i = 0; i < outputPolyData->GetNumberOfPoints(); i++)
>         {
>                 double p[3];
>                 outputPolyData->GetPoint(i,p);
>
>                 double dcolor[3];
>                 colorLookupTable->GetColor(p[2], dcolor);
>                 unsigned char color[3];
>                 for(unsigned int j = 0; j < 3; j++)
>                 {
>                         color[j] = static_cast<unsigned char>(255.0 *
> dcolor[j]);
>                 }
>
>                 colors->InsertNextTupleValue(color);
>         }
>
>         outputPolyData->GetPointData()->SetScalars(colors);
>
>         vtkSmartPointer<vtkCubeAxesActor> axes =
> vtkSmartPointer<vtkCubeAxesActor>::New();
>         axes->SetBounds(delaunay->GetOutput()->GetBounds());
>         axes->SetFlyModeToOuterEdges();
>
>         axes->XAxisMinorTickVisibilityOff();
>         axes->YAxisMinorTickVisibilityOff();
>         axes->ZAxisMinorTickVisibilityOff();
>         axes->SetXLabelFormat("%6.1f");
>
>
>  vtkSmartPointer<vtkButterflySubdivisionFilter> subdivide =
> vtkSmartPointer<vtkButterflySubdivisionFilter>::New();
>   subdivide->SetNumberOfSubdivisions(3);
> #if VTK_MAJOR_VERSION <= 5
>   subdivide->SetInputConnection(outputPolyData->GetProducerPort());
> #else
>   subdivide->SetInputData(outputPolyData);
> #endif
>
>   // Create a mapper and actor
>   vtkSmartPointer<vtkPolyDataMapper> mapper =
> vtkSmartPointer<vtkPolyDataMapper>::New();
>   mapper->SetInputConnection(subdivide->GetOutputPort());
>
>   vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
>         actor->SetMapper(mapper);
>
>         // 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);
>
>         //prevents the pointer option from going haywire
>         vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
> vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
>         renderWindowInteractor->SetInteractorStyle(style);
>
>         // Add the actor to the scene
>         renderer->AddActor(actor);
>         renderer->SetBackground(.1, .2, .3);
>
>         // Render and interact
>         renderWindow->Render();
>
>         renderer->GetActiveCamera()->Elevation(290);
>         renderer->AddViewProp(axes);
>         axes->SetCamera(renderer->GetActiveCamera());
>
>         renderWindowInteractor->Start();
>
>         return EXIT_SUCCESS;
> }
>
> As you can see in the following image the maximum point values of the shape
> is altered, I don't want those values altered in my plot. How do I avoid it.
>
>
> Normal image without subdivision and with ButterflySubdivision.
>
> <http://vtk.1045678.n5.nabble.com/file/n5724768/rect.png>
> <http://vtk.1045678.n5.nabble.com/file/n5724768/butter_rect.png>
>
>
> Thank you.
>
>
>
> --
> View this message in context: http://vtk.1045678.n5.nabble.com/vtkButterflySubdivisionFilter-displays-incorrect-shape-tp5724768.html
> Sent from the VTK - Users mailing list archive at Nabble.com.
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers



--
Unpaid intern in BillsBasement at noware dot com
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.vtk.org/mailman/listinfo/vtkusers