# How to Receive and Visualize PolyData from IGTLink

**URL:** <https://discourse.slicer.org/t/how-to-receive-and-visualize-polydata-from-igtlink/25736>\
**Category:** Development\
**Tags:** openigtlink\
**Created:** [October 17, 2022, 7:48pm UTC](https://discourse.slicer.org/t/how-to-receive-and-visualize-polydata-from-igtlink/25736 "2022-10-17T19:48:00Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jack\_Zhang](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jack_zhang/32/16328_2.png) [@Jack\_Zhang](https://discourse.slicer.org/u/Jack_Zhang)\
**Post date:** [October 17, 2022, 7:48pm UTC](https://discourse.slicer.org/t/how-to-receive-and-visualize-polydata-from-igtlink/25736/1 "2022-10-17T19:48:00Z")

</div>

Operating system: Windows 10  
Slicer version:5.0.3

I’ve written a program that sends a polydata message over IGTLink to Slicer. As a demo run, I just want to create a line between two points and add it to the 3D widget. I was wondering how to add the line to the scene once the message is sent. The program is able to establish a connection with Slicer using the OpenIGTLinkIF module just fine, and I think it is successfully sending the polydata in each loop. The device name I specified appears in the _Models_ modules but I’m not sure what to do from here.

Here is the code I’m using to send the OpenIGTLink messages:

```auto
// include basic libraries
#include <iostream>
#include <thread>

// include igtlink headers 
#include "igtlOSUtil.h"
#include "igtlMessageHeader.h"
#include "igtlServerSocket.h"
#include "igtlPolyDataMessage.h"

std::atomic_bool StopFlag = false;

int SendPolyData(igtl::Socket::Pointer& socket)
{   
    // Allocate Status Message Class
    igtl::PolyDataMessage::Pointer polyDataMsg;
    polyDataMsg = igtl::PolyDataMessage::New();
    // NOTE: the server should send a message with the same device name
    // as the received query message. 
    polyDataMsg->SetDeviceName("Fake Shapes");

    // Define points connected by line
    static igtlFloat32 pointsData[2][3] = { {0,0,0}, {100,100,100} };

    // Create point array
    igtl::PolyDataPointArray::Pointer pointArray;
    pointArray = igtl::PolyDataPointArray::New();

    // Add point data to point array
    for (unsigned int i = 0; i < 2; i++)
    {
        pointArray->AddPoint(pointsData[i]);
    }

    // Add pointArray to PolyDataMessage
    polyDataMsg->SetPoints(pointArray);

    // Add lines
    static igtlUint32 lineData[2][3] = { {0,0,0}, {100,100,100} };

    // Add PolyDataCellArray and add lines
    igtl::PolyDataCellArray::Pointer cellArray;
    cellArray = igtl::PolyDataCellArray::New();
    for (unsigned int i = 0; i < 2; i++)
    {
        cellArray->AddCell(3, lineData[i]);
    }

    // Add PolyDataCellArray to PolyDataMessage
    polyDataMsg->SetLines(cellArray);

    // Pack polyDataMsg and send via OpenIGTLink socket
    polyDataMsg->Pack();
    socket->Send(polyDataMsg->GetPackPointer(), polyDataMsg->GetPackSize());
    std::cout << "Message sent" << std::endl;
    return 1;
}

int LoopFunction() {
    // Create server socket
    igtl::ServerSocket::Pointer ServerSocket;
    ServerSocket = igtl::ServerSocket::New();
    int r = ServerSocket->CreateServer(18944);

    if (r < 0)
    {
        std::cerr << "Cannot create a server socket" << std::endl;
        exit(0);
    }

    igtl::Socket::Pointer socket;

    // Wait for Connection
    socket = ServerSocket->WaitForConnection(10000); // Wait ten seconds for connection

    if (socket.IsNotNull()) // if client connected
    {
        std::cerr << "Client connected." << std::endl;

        while (!StopFlag)
        {
            //socket->Skip(HeaderMsg->GetPodySizeToRead(),0);
            SendPolyData(socket);
            igtl::Sleep(500);
        }

    }
    else
    {
        std::cerr << "Client could not connect." << std::endl;
    }
    // Close connect
    socket->CloseSocket();
    return 1;
}

int main() {
    // Create thread for loopFunction
    std::thread MessageThread(LoopFunction);

    // main function stops to listen for keyboard input. When input is detected,
    // loop in LoopFunction is broken, and the function quickly returns
    std::cout << "Press any key to stop loop" << std::endl;
    std::cin.get();
    StopFlag = true;
    MessageThread.join();

    // Send message when all threads are joined
    std::cout << "All threads joined" << std::endl;

    return EXIT_SUCCESS;
}

```

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [October 17, 2022, 8:07pm UTC](https://discourse.slicer.org/t/how-to-receive-and-visualize-polydata-from-igtlink/25736/2 "2022-10-17T20:07:36Z")

</div>

If the polydata appears in the Models module then it should work.

Have you recentered the 3D view so that the polydata is in the middle of the view?

Also can check that the data in the “Information” section of the Models module is correct for your polydata?

---

<div class="post-metadata">

**Author:** ![Jack\_Zhang](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jack_zhang/32/16328_2.png) [@Jack\_Zhang](https://discourse.slicer.org/u/Jack_Zhang)\
**Post date:** [October 17, 2022, 8:10pm UTC](https://discourse.slicer.org/t/how-to-receive-and-visualize-polydata-from-igtlink/25736/3 "2022-10-17T20:10:44Z")

</div>

I’m guessing I just formatted my lines incorrectly, since there should only be one line connecting two points. This is what I see with the server active:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/1/c1cce85b6e847c7720facb5e94f7ec52e620df60.png)

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [October 17, 2022, 8:20pm UTC](https://discourse.slicer.org/t/how-to-receive-and-visualize-polydata-from-igtlink/25736/4 "2022-10-17T20:20:40Z")

</div>

I think your line cell is not composed correctly. You should only call AddCell once, and it should contain 2 values, {0, 1}.

---

<div class="post-metadata">

**Author:** ![Jack\_Zhang](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jack_zhang/32/16328_2.png) [@Jack\_Zhang](https://discourse.slicer.org/u/Jack_Zhang)\
**Post date:** [October 17, 2022, 8:35pm UTC](https://discourse.slicer.org/t/how-to-receive-and-visualize-polydata-from-igtlink/25736/5 "2022-10-17T20:35:23Z")

</div>

Got it, thanks! Here is the fixed code for future reference:

```auto
// include basic libraries
#include <iostream>
#include <thread>

// include igtlink headers 
#include "igtlOSUtil.h"
#include "igtlMessageHeader.h"
#include "igtlServerSocket.h"
#include "igtlPolyDataMessage.h"

std::atomic_bool StopFlag = false;

int SendPolyData(igtl::Socket::Pointer& socket)
{   
    // Allocate Status Message Class
    igtl::PolyDataMessage::Pointer polyDataMsg;
    polyDataMsg = igtl::PolyDataMessage::New();
    // NOTE: the server should send a message with the same device name
    // as the received query message. 
    polyDataMsg->SetDeviceName("Fake Shapes");

    // Define points connected by line
    static igtlFloat32 pointsData[2][3] = { {0,0,0}, {100,100,100} };

    // Create point array
    igtl::PolyDataPointArray::Pointer pointArray;
    pointArray = igtl::PolyDataPointArray::New();

    // Add point data to point array
    for (unsigned int i = 0; i < 2; i++)
    {
        pointArray->AddPoint(pointsData[i]);
    }

    // Add pointArray to PolyDataMessage
    polyDataMsg->SetPoints(pointArray);

    // Add lines
    static igtlUint32 lineData[2] = {0,1}; // equivalent to SetId with vtk's PolyLine

    // Create PolyDataCellArray and add lines
    igtl::PolyDataCellArray::Pointer cellArray;
    cellArray = igtl::PolyDataCellArray::New();
    cellArray->AddCell(2, lineData);

    // Add PolyDataCellArray to PolyDataMessage
    polyDataMsg->SetLines(cellArray);

    // Pack polyDataMsg and send via OpenIGTLink socket
    polyDataMsg->Pack();
    socket->Send(polyDataMsg->GetPackPointer(), polyDataMsg->GetPackSize());
    std::cout << "Message sent" << std::endl;
    return 1;
}

int LoopFunction() {
    // Create server socket
    igtl::ServerSocket::Pointer ServerSocket;
    ServerSocket = igtl::ServerSocket::New();
    int r = ServerSocket->CreateServer(18944);

    if (r < 0)
    {
        std::cerr << "Cannot create a server socket" << std::endl;
        exit(0);
    }

    igtl::Socket::Pointer socket;

    // Wait for Connection
    socket = ServerSocket->WaitForConnection(10000); // Wait ten seconds for connection

    if (socket.IsNotNull()) // if client connected
    {
        std::cerr << "Client connected." << std::endl;

        while (!StopFlag)
        {
            //socket->Skip(HeaderMsg->GetPodySizeToRead(),0);
            SendPolyData(socket);
            igtl::Sleep(500);
        }

    }
    else
    {
        std::cerr << "Client could not connect." << std::endl;
    }
    // Close connect
    socket->CloseSocket();
    return 1;
}

int main() {
    // Create thread for loopFunction
    std::thread MessageThread(LoopFunction);

    // main function stops to listen for keyboard input. When input is detected,
    // loop in LoopFunction is broken, and the function quickly returns
    std::cout << "Press any key to stop loop" << std::endl;
    std::cin.get();
    StopFlag = true;
    MessageThread.join();

    // Send message when all threads are joined
    std::cout << "All threads joined" << std::endl;

    return EXIT_SUCCESS;
}

```
