vtkReverseSense can help us to reverse the direction of point and cell normals.
The following code shows a simple example which displays vertexes’ normals by cones in a sphere.
Here is its original geometric state.
C++
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkPolyDataNormals.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkTransform.h>
#include <vtkCamera.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkGlyph3D.h>
#include <vtkReverseSense.h>

int main(int argc, char *argv[])
{
    vtkSmartPointer<vtkSphereSource> sphere =
            vtkSmartPointer<vtkSphereSource>::New();

    vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection( sphere->GetOutputPort() );

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

    vtkSmartPointer<vtkPolyDataNormals> pdNormals =
            vtkSmartPointer<vtkPolyDataNormals>::New();
    pdNormals->SetInputConnection( sphere->GetOutputPort() );
    pdNormals->ComputeCellNormalsOn();
    pdNormals->Update();

    vtkSmartPointer<vtkConeSource> cone =
            vtkSmartPointer<vtkConeSource>::New();
    cone->SetResolution( 6 );
    vtkSmartPointer<vtkTransform> transform =
            vtkSmartPointer<vtkTransform>::New();
    transform->RotateY( 180 ); // make vertex outside
    vtkSmartPointer<vtkTransformPolyDataFilter> transformF =
            vtkSmartPointer<vtkTransformPolyDataFilter>::New();
    transformF->SetInputConnection( cone->GetOutputPort() );
    transformF->SetTransform( transform );

    vtkSmartPointer<vtkGlyph3D> glyph =
            vtkSmartPointer<vtkGlyph3D>::New();

    glyph->SetInputConnection( pdNormals->GetOutputPort() );
    glyph->SetSourceConnection( transformF->GetOutputPort() ); // source => transform => graph3D
    glyph->SetVectorModeToUseNormal();
    glyph->SetScaleModeToScaleByVector();
    glyph->SetScaleFactor( 0.1 );

    vtkSmartPointer<vtkPolyDataMapper> spikeMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    spikeMapper->SetInputConnection( glyph->GetOutputPort() );

    vtkSmartPointer<vtkActor> spikeActor = vtkSmartPointer<vtkActor>::New();
    spikeActor->SetMapper( spikeMapper );
    spikeActor->GetProperty()->SetColor( 0.0, 0.79, 0.34 );

    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(spikeActor);
    renderer->AddActor(surfaceActor);
    renderer->SetBackground( 0, 0, 0 );

    vtkSmartPointer<vtkRenderWindow> renderWindow =
            vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer( renderer );

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

We use vtkReverseSense to handle dataset of pdNormals, make all normals point to the opposite direction.
C++
    vtkSmartPointer<vtkReverseSense> reverseF =
            vtkSmartPointer<vtkReverseSense>::New();
    reverseF->SetInputConnection( pdNormals->GetOutputPort() );
    reverseF->ReverseNormalsOn();

    glyph->SetInputConnection( reverseF->GetOutputPort() );
The final result:


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page