Visualizing normal vectors

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

Visualizing normal vectors

mozendi
I have some point cloud files in .xyz format. Each of these files contain
approximately 1million points and corresponding normal vectors for each
point. Each line of .xyz files belongs to one point and each line contains
cartesian coordinates (x,y, and z) and normal vetor (nx,ny, and nz). My
objective is to show points and their normal vectors. I can read .xyz files
successfully and show points successfully. However, I can not show normal
vectors successfully. I tried to solve the problem using vtkGlyph3D class as
shown in some examples of Kitware but every attempt was failure for me. My
code is shown below.
Could you please help me about solving this problem? I am looking forward to
hearing from you. Thanks in advance.

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkDelimitedTextReader.h>
#include <vtkDoubleArray.h>
#include <vtkTable.h>
#include <vtkPointData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkVertexGlyphFilter.h>

int main(int argc, char* argv[])
{
    vtkSmartPointer<vtkDelimitedTextReader> reader =
vtkSmartPointer<vtkDelimitedTextReader>::New();
    reader->SetFileName("points_and_normals.xyz");
    reader->DetectNumericColumnsOn();
    reader->SetFieldDelimiterCharacters(" ");
    reader->Update();

    vtkTable* table = reader->GetOutput();
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkDoubleArray> normals =
vtkSmartPointer<vtkDoubleArray>::New();
    normals->SetNumberOfComponents(3); //3d normals (ie x,y,z)

    std::cout << "Table has " << table->GetNumberOfRows()
            << " rows." << std::endl;
    std::cout << "Table has " << table->GetNumberOfColumns()
            << " columns." << std::endl;

    for (vtkIdType i = 0; i < table->GetNumberOfRows(); i++)
    {

            points->InsertNextPoint((table->GetValue(i, 0)).ToDouble(),
                    (table->GetValue(i, 1)).ToDouble(),
                    (table->GetValue(i, 2)).ToDouble());

            double n[3];
            n[0] = (table->GetValue(i, 3)).ToDouble();
            n[1] = (table->GetValue(i, 4)).ToDouble();
            n[2] = (table->GetValue(i, 5)).ToDouble();
            normals->InsertNextTuple(n);
    }

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

    vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
    polydata->SetPoints(points);
    polydata->GetPointData()->SetNormals(normals);
    vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter =
vtkSmartPointer<vtkVertexGlyphFilter>::New();
#if VTK_MAJOR_VERSION <= 5
        glyphFilter->SetInputConnection(polydata->GetProducerPort());
#else
        glyphFilter->SetInputData(polydata);
#endif
    glyphFilter->Update();
    // Visualize
    vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(glyphFilter->GetOutputPort());
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetPointSize(3);
    actor->GetProperty()->SetColor(0, 0, 1);
    vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);
    renderer->AddActor(actor);
    renderer->SetBackground(.5, .5, .5);
    renderWindow->Render();
    renderWindowInteractor->Start();
    return EXIT_SUCCESS;
}



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Visualizing normal vectors

Andaharoo
I'd recommend using vtkOpenGLGlyph3DMapper instead. Much faster, assuming you
have some gpu. Just make sure the normal array/orientation array is in the
input polyData's point data.

IE:
polyData->GetPointData()->AddArray(your normal array)

Then just specify the array the mapper should use with
SetOrientationArray(your arrays name here). It will then search for the
array in the input polydata. I frequently use this to draw thousands of
oriented arrows with VTK.



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Visualizing normal vectors

mozendi
Dear Andaharoo,
Thank you for your recommendation. I tried to modify my codes according to
your recommendations, my code is getting compiled successfully. However,
when I run it I am getting an error message. The screenshot and my code are
below. Could you please tell me what is wrong with my code?
Thanks in advance
<http://vtk.1045678.n5.nabble.com/file/t341822/vtk_error_message.png>


#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkDelimitedTextReader.h>
#include <vtkDoubleArray.h>
#include <vtkTable.h>
#include <vtkPointData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>
#include <vtkPointSource.h>
# include "vtkGlyph3DMapper.h"
# include "vtkGlyph3DMapper.h"
#include <vtkOpenGLGlyph3DMapper.h>
#include <vector>


int main(int argc, char* argv[])
{
        vtkSmartPointer<vtkDelimitedTextReader> reader =
vtkSmartPointer<vtkDelimitedTextReader>::New();
        reader->SetFileName("points_and_normals.xyz");
        reader->DetectNumericColumnsOn();
        reader->SetFieldDelimiterCharacters(" ");
        reader->Update();

        vtkTable* table = reader->GetOutput();
        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
        vtkSmartPointer<vtkDoubleArray> normals =
vtkSmartPointer<vtkDoubleArray>::New();
        normals->SetNumberOfComponents(3); //3d normals (ie x,y,z)

        std::cout << "Table has " << table->GetNumberOfRows()
                << " rows." << std::endl;
        std::cout << "Table has " << table->GetNumberOfColumns()
                << " columns." << std::endl;

        for (vtkIdType i = 0; i < table->GetNumberOfRows(); i++)
        {

                points->InsertNextPoint((table->GetValue(i, 0)).ToDouble(),
                        (table->GetValue(i, 1)).ToDouble(),
                        (table->GetValue(i, 2)).ToDouble());

                double n[3];
                n[0] = (table->GetValue(i, 3)).ToDouble();
                n[1] = (table->GetValue(i, 4)).ToDouble();
                n[2] = (table->GetValue(i, 5)).ToDouble();
                normals->InsertNextTuple(n);
        }

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

        vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
        polydata->SetPoints(points);
        //polydata->GetPointData()->SetNormals(normals);
        polydata->GetPointData()->AddArray(normals);
       
        vtkSmartPointer<vtkOpenGLGlyph3DMapper> Glyph3D =
vtkSmartPointer<vtkOpenGLGlyph3DMapper>::New();
        Glyph3D->SetInputData(polydata);
        Glyph3D->SetOrientationArray("normals");
        Glyph3D->SetScaleFactor(.5);
        Glyph3D->Update();
               
        vtkSmartPointer<vtkActor> glyph3DActor = vtkSmartPointer<vtkActor>::New();
        glyph3DActor->SetMapper(Glyph3D);
        glyph3DActor->GetProperty()->SetColor(0.8900, 0.8100, 0.3400);

        vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
        vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
        renderWindow->AddRenderer(renderer);
        vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderer->AddActor(glyph3DActor);
        renderer->SetBackground(.5, .5, .5);
        renderWindow->Render();
        renderWindowInteractor->Start();
        return EXIT_SUCCESS;
}





--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Visualizing normal vectors

Andaharoo
Your error said an array index went out of bounds. What line? Also I noticed
you never set the source data for the glyph. Could be unrelated to your
current error message, but a problem.

The glyph mapper takes two inputs. The glyph data (positions, normals,
scalars, etc) and the source (thing to copy). So if you want arrows as the
normals do this:

vtkSmartPointer<vtkOpenGLGlyph3DMapper> glyph3D =
vtkSmartPointer<vtkOpenGLGlyph3DMapper>::New();
glyph3D ->SetInputData(polydata);
vtkSmartPointer<vtkArrowSource> glyphSource =
vtkSmartPointer<vtkArrowSource>::New();
glyphSource->Update();
glyph3D->SetSourceData(glyphSource->GetOutput());
glyph3D ->SetOrientationArray("normals");
glyph3D ->SetScaleFactor(0.5);
glyph3D ->Update();



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Visualizing normal vectors

mozendi
Dear Andaharoo,

Thank you very much for recommendations. My code works successfully and it
runs quite fast.
I have one more question. Is it possible to set width of arrows? I can scale
it using SetScaleFactor(). I tried SetTipLength and SetTipRadius but
dimensions did not change.
Thanks in advance

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkDelimitedTextReader.h>
#include <vtkDoubleArray.h>
#include <vtkTable.h>
#include <vtkPointData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>
#include <vtkPointSource.h>
# include "vtkGlyph3DMapper.h"
#include <vtkOpenGLGlyph3DMapper.h>
#include <vector>


int main(int argc, char* argv[])
{
        vtkSmartPointer<vtkDelimitedTextReader> reader =
vtkSmartPointer<vtkDelimitedTextReader>::New();
        reader->SetFileName("dene_sil.xyz");
        reader->DetectNumericColumnsOn();
        reader->SetFieldDelimiterCharacters(" ");
        reader->Update();

        vtkTable* table = reader->GetOutput();
        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
        vtkSmartPointer<vtkDoubleArray> normals =
vtkSmartPointer<vtkDoubleArray>::New();
        normals->SetName("NORMALS");
        normals->SetNumberOfComponents(3); //3d normals (ie x,y,z)

        std::cout << "Table has " << table->GetNumberOfRows()
                << " rows." << std::endl;
        std::cout << "Table has " << table->GetNumberOfColumns()
                << " columns." << std::endl;

        for (vtkIdType i = 0; i < table->GetNumberOfRows(); i++)
        {

                points->InsertNextPoint((table->GetValue(i, 0)).ToDouble(),
                        (table->GetValue(i, 1)).ToDouble(),
                        (table->GetValue(i, 2)).ToDouble());

                double n[3];
                n[0] = (table->GetValue(i, 3)).ToDouble();
                n[1] = (table->GetValue(i, 4)).ToDouble();
                n[2] = (table->GetValue(i, 5)).ToDouble();
                normals->InsertNextTuple(n);
        }

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

        vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
        polydata->SetPoints(points);
        //polydata->GetPointData()->SetNormals(normals);
        polydata->GetPointData()->AddArray(normals);

        vtkSmartPointer<vtkOpenGLGlyph3DMapper> Glyph3D =
vtkSmartPointer<vtkOpenGLGlyph3DMapper>::New();
        Glyph3D->SetInputData(polydata);

        double pp[3];
        polydata->GetPoint(1, pp);
        std::cout << "deneme = " << 1 << " : (" << pp[0] << " " << pp[1] << " " <<
pp[2] << ")" << std::endl;
       
        std::cout << "There are " << polydata->GetPointData()->GetNumberOfArrays()
<< " arrays." << std::endl;
        std::cout << "name: " << polydata->GetPointData()->GetArrayName(0) <<
std::endl;
       
        vtkSmartPointer<vtkArrowSource> glyphSource =
vtkSmartPointer<vtkArrowSource>::New();
        glyphSource->Update();
        //glyphSource->SetTipResolution(5);
        glyphSource->SetTipLength(0.01);
        glyphSource->SetTipRadius(0.01);
       
        vtkSmartPointer<vtkActor> glyph3DActor = vtkSmartPointer<vtkActor>::New();
        glyph3DActor->SetMapper(Glyph3D);
        glyph3DActor->GetProperty()->SetColor(0.8900, 0.8100, 0.3400);
        glyph3DActor->GetProperty()->SetLineWidth(0.01);

        Glyph3D->SetSourceData(glyphSource->GetOutput());
        Glyph3D->OrientOn();
        Glyph3D->SetOrientationArray("NORMALS");
        Glyph3D->SetScaleFactor(0.03);
        Glyph3D->Update();
       
        vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
        vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
        renderWindow->AddRenderer(renderer);
        vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
        renderWindowInteractor->SetRenderWindow(renderWindow);
        renderer->AddActor(glyph3DActor);
        renderer->SetBackground(.5, .5, .5);
        renderWindow->Render();
        renderWindowInteractor->Start();
        return EXIT_SUCCESS;
}




--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

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