Search code examples
c++visual-studio-2008vtk

Why is vtkClipPolyData is rendering very slowly in surface rendered output in vtk


I have the following codes to clip a model, but when I update the Plane to generate the new clipped surface it is very slow. Is there a way to make this faster? or is there another vtk class to perform faster?

vtkSmartPointer<vtkPlane> clipPlane =  vtkSmartPointer<vtkPlane>::New();
clipPlane->SetNormal(1, 1, 0);
clipPlane->SetOrigin(0.0, -10.0, 0.0 );

vtkSmartPointer<vtkClipPolyData> clipper = 
vtkSmartPointer<vtkClipPolyData>::New();
clipper->SetInputData( reader->GetOutput() );
clipper->SetClipFunction( clipPlane );
clipper->Update();

But I found no answer for this question.Any help would be appriciated I have found that my problem is same as in the link that is given below.For reference use the below link

http://vtk.1045678.n5.nabble.com/is-vtkClipPolyData-slow-td5727625.html1


Solution

  • Depends what you wish to achieve: vtkClipPolyData calculates a new geometry clipped with the vtkImplicitFunction provided. I guess you can write a "StrictlyPlaneClipPolyData" filter faster than the current one.

    However, if rendering is the case, then you can (and should) let the shader do it. Simply as follows:

    //vtkActor * actor;
    actor->GetMapper()->AddClippingPlane( clipPlane );
    

    After interaction then, perhaps, you apply the geometry filter only once.

    * EDIT *

    Sample code to demonstrate the performance: blender.org Monkey

    #include "vtkInteractorStyleTrackballCamera.h"
    #include "vtkRenderer.h"
    #include "vtkRenderWindow.h"
    #include "vtkRenderer.h"
    #include "vtkClipPolyData.h"
    #include "vtkPolyDataMapper.h"
    #include "vtkActor.h"
    #include <Windows.h>
    #include "vtkPlane.h"
    #include "vtkTransform.h"
    #include "vtkMath.h"
    #include "vtkProperty.h"
    // performance counter in ms units
    double ticks(void)
    {
        LARGE_INTEGER lg,f;
        if ( QueryPerformanceCounter( &lg ) && QueryPerformanceFrequency( &f ) )
            return 1000.0 * (double)lg.QuadPart/(double)f.QuadPart;
        else
            return (double)GetTickCount();
    }
    void ClipSample( void )
    {
        vtkPolyData * monkey;
        // monkey is the Blender monkey courtesy of Blender.org 
        // @126 k vertices
        // make sure to transform the monkey into origin 
    
        // create render window
        vtkSmartPointer< vtkRenderer > ren = vtkSmartPointer< vtkRenderer >::New();
        vtkSmartPointer< vtkRenderWindow > rw = vtkSmartPointer< vtkRenderWindow >::New();
        rw->AddRenderer( ren );
        rw->SetSize( 1024,1024 );
        // create interactor used later
        vtkSmartPointer< vtkRenderWindowInteractor > ia = vtkSmartPointer<vtkRenderWindowInteractor>::New();
        ia->SetRenderWindow( rw );
        ia->SetInteractorStyle(  vtkSmartPointer< vtkInteractorStyleTrackballCamera >::New() );
        ia->Initialize();
    
        // create clipper
        vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane> ::New();
        plane->SetNormal(0,0,1);
        plane->SetOrigin(0,0,0);
    
    //#define SOFTWARE_CLIPPER
    
        // create mapper
        vtkSmartPointer< vtkPolyDataMapper > mapper = vtkSmartPointer< vtkPolyDataMapper >::New();
    #ifdef SOFTWARE_CLIPPER
        vtkSmartPointer< vtkClipPolyData > clipper = vtkSmartPointer< vtkClipPolyData >::New();
        clipper->SetInputData( monkey );
        clipper->SetClipFunction( plane );
        mapper->SetInputConnection( clipper->GetOutputPort() );
    #else
        mapper->SetInputData( monkey );
        mapper->AddClippingPlane( plane );
    #endif
    
        // create actor
        vtkSmartPointer< vtkActor > actor = vtkSmartPointer< vtkActor >::New();
        actor->SetMapper( mapper );
        actor->GetProperty()->SetColor( 0.3, 1.0, 0.7 );
    
        // color back face to emphasize clipping
        vtkSmartPointer< vtkProperty > backface = vtkSmartPointer< vtkProperty > ::New();
        backface->SetColor(1,0,0);
        actor->SetBackfaceProperty( backface );
    
        ren->AddActor( actor );
        double delta = 20.0;
    
        double timeTotal=0.0;
        double count=0.0;
        for ( int i=0;i<10;++i)
        {
            // make rotation axis
            vtkSmartPointer<vtkTransform> trf0=vtkSmartPointer<vtkTransform>::New();
            trf0->RotateZ( vtkMath::Random(-90,90) );
            trf0->RotateX( vtkMath::Random(-90,90) );
            trf0->RotateY( vtkMath::Random(-90,90) );
            const double * axis = trf0->TransformNormal(0,0,1);
    
            for ( double z=-180; z<180; z+=delta ) 
            {
                double time = ticks();
                // rotate the clipper around its axis
                double normal[3];
                vtkSmartPointer<vtkTransform> trf=vtkSmartPointer<vtkTransform>::New();
                trf->RotateWXYZ( z, axis );
                plane->SetNormal( trf->TransformNormal(0,0,1) );
                ia->Render();
                time = ticks()-time;
                timeTotal+=time;
                count+=1.0;
                Sleep( 30 ); // too fast otherwise
            }
        }
    #ifdef SOFTWARE_CLIPPER
        std::cout << "Software clipper: ";
    #else
        std::cout << "Hardware clipper: ";
    #endif
        std::cout << "time per iteration " << timeTotal/count << " ms" << std::endl;
        ia->Start(); // start interactor finally: use 'C','A' etc. for changing interaction modes
    }
    

    Comparison of hardware and software clipper ( Windows 10, Intel i5 8th gen, VTK8.1):

    Software clipper: time per iteration 76.5701 ms
    
    Hardware clipper: time per iteration 1.63613 ms