diff --git a/MRML/vtkIGTLToMRMLBase.cxx b/MRML/vtkIGTLToMRMLBase.cxx index 366215b..d350c4b 100644 --- a/MRML/vtkIGTLToMRMLBase.cxx +++ b/MRML/vtkIGTLToMRMLBase.cxx @@ -131,3 +131,18 @@ int vtkIGTLToMRMLBase::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRMLNode return 0; } +bool vtkIGTLToMRMLBase::CheckIfMRMLSupported(const char* nodeTagName) +{ + bool isMRMLSupported = false; + for (int iName = 0; iName < this->GetAllMRMLNames().size(); iName++) + { + if (strcmp(nodeTagName, this->GetAllMRMLNames()[iName].c_str()) == 0) + { + isMRMLSupported = true; + break; + } + } + return isMRMLSupported; +} + + diff --git a/MRML/vtkIGTLToMRMLBase.h b/MRML/vtkIGTLToMRMLBase.h index b38a101..9e3ad65 100644 --- a/MRML/vtkIGTLToMRMLBase.h +++ b/MRML/vtkIGTLToMRMLBase.h @@ -148,6 +148,8 @@ class VTK_SLICER_OPENIGTLINKIF_MODULE_MRML_EXPORT vtkIGTLToMRMLBase : public vtk int CheckCRC; vtkIGTLToMRMLBasePrivate* Private; + + bool CheckIfMRMLSupported(const char* nodeTagName); }; diff --git a/MRML/vtkIGTLToMRMLImage.cxx b/MRML/vtkIGTLToMRMLImage.cxx index c9dc339..9635462 100644 --- a/MRML/vtkIGTLToMRMLImage.cxx +++ b/MRML/vtkIGTLToMRMLImage.cxx @@ -580,9 +580,9 @@ int vtkIGTLToMRMLImage::MRMLToIGTL(unsigned long event, vtkMRMLNode* mrmlNode, i { return 0; } - + bool isMRMLSupported = this->CheckIfMRMLSupported(mrmlNode->GetNodeTagName()); // If mrmlNode is Image node - if (event == vtkMRMLVolumeNode::ImageDataModifiedEvent && strcmp(mrmlNode->GetNodeTagName(), "Volume") == 0) + if (event == vtkMRMLVolumeNode::ImageDataModifiedEvent && isMRMLSupported) { vtkMRMLVolumeNode* volumeNode = vtkMRMLVolumeNode::SafeDownCast(mrmlNode); diff --git a/MRML/vtkIGTLToMRMLPolyData.cxx b/MRML/vtkIGTLToMRMLPolyData.cxx index 300acaf..cacbf88 100644 --- a/MRML/vtkIGTLToMRMLPolyData.cxx +++ b/MRML/vtkIGTLToMRMLPolyData.cxx @@ -50,6 +50,7 @@ #include "vtkSlicerOpenIGTLinkIFLogic.h" + //--------------------------------------------------------------------------- vtkStandardNewMacro(vtkIGTLToMRMLPolyData); //--------------------------------------------------------------------------- @@ -78,8 +79,45 @@ vtkMRMLNode* vtkIGTLToMRMLPolyData::CreateNewNodeWithMessage(vtkMRMLScene* scene vtkErrorMacro("Unable to create MRML node from incoming POLYDATA message: incoming PolyDataMessage is invalid"); return 0; } - - + igtl::PolyDataMessage::Pointer polyMsg = igtl::PolyDataMessage::New(); + // Attribute + polyMsg->Copy(incomingPolyDataMessage); + int c = polyMsg->Unpack(this->CheckCRC); + if ((c & igtl::MessageHeader::UNPACK_BODY) == 0) // if CRC check fails + { + vtkErrorMacro("Unable to create MRML node from incoming IMAGE message. Failed to unpack the message"); + return 0; + } + bool isTensorData = false; + int nAttributes = polyMsg->GetNumberOfAttributes(); + for (int i = 0; i < nAttributes; i ++) + { + igtl::PolyDataAttribute::Pointer attribute; + attribute = polyMsg->GetAttribute(i); + + // NOTE: Data types for POINT (igtl::PolyDataMessage::POINT_*) and CELL + // (igtl::PolyDataMessage::CELL_*) have the same lower 4 bit. + // By masking the values with 0x0F, attribute types (either SCALAR, VECTOR, NORMAL, + // TENSOR, or RGBA) can be obtained. On the other hand, by masking the value + // with 0xF0, data types (POINT or CELL) can be obtained. + // See, igtlPolyDataMessage.h in the OpenIGTLink library. + if ((attribute->GetType() & 0x0F ) == igtl::PolyDataAttribute::POINT_TENSOR) + { + isTensorData = true; + break; + } + } + if (isTensorData) + { + vtkMRMLNode* node = scene->CreateNodeByClass("vtkMRMLFiberBundleNode"); + if (node) + { + vtkMRMLModelNode* fiberNode = vtkMRMLModelNode::SafeDownCast(node); + fiberNode->SetScene(scene); + fiberNode->CreateDefaultDisplayNodes(); + return fiberNode; + } + } // Create a node vtkSmartPointer modelNode = vtkSmartPointer::New(); modelNode->SetName(name); @@ -126,44 +164,46 @@ vtkIntArray* vtkIGTLToMRMLPolyData::GetNodeEvents() return events; } - //--------------------------------------------------------------------------- -int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRMLNode* node) +int vtkIGTLToMRMLPolyData::UnpackIGTLMessage(igtl::MessageBase::Pointer buffer) { - - vtkMRMLModelNode* modelNode = vtkMRMLModelNode::SafeDownCast(node); - - if (modelNode==NULL) + if (this->InPolyDataMessage.IsNull()) { - vtkErrorMacro("vtkIGTLToMRMLPolyData::IGTLToMRML failed: invalid node"); - return 0; + this->InPolyDataMessage = igtl::PolyDataMessage::New(); } - - - // Create a message buffer to receive image data - igtl::PolyDataMessage::Pointer polyDataMsg; - polyDataMsg = igtl::PolyDataMessage::New(); - polyDataMsg->Copy(buffer); // !! TODO: copy makes performance issue. - - // Deserialize the data + this->InPolyDataMessage->Copy(buffer); + + // Deserialize the transform data // If CheckCRC==0, CRC check is skipped. - int c = polyDataMsg->Unpack(this->CheckCRC); - + int c = this->InPolyDataMessage->Unpack(this->CheckCRC); + if ((c & igtl::MessageHeader::UNPACK_BODY) == 0) // if CRC check fails { - vtkErrorMacro("Unable to create MRML node from incoming POLYDATA message. Failed to unpack the message"); + // TODO: error handling return 0; } + return 1; +} + +//--------------------------------------------------------------------------- +int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRMLNode* node) +{ + if(this->InPolyDataMessage.IsNull()) + { + this->UnpackIGTLMessage(buffer); + } + vtkSmartPointer poly = vtkSmartPointer::New(); if (poly.GetPointer()==NULL) { // TODO: Error handling + return 0; } // Points - igtl::PolyDataPointArray::Pointer pointsArray = polyDataMsg->GetPoints(); + igtl::PolyDataPointArray::Pointer pointsArray = this->InPolyDataMessage->GetPoints(); int npoints = pointsArray->GetNumberOfPoints(); if (npoints > 0) { @@ -182,7 +222,7 @@ int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRML } // Vertices - igtl::PolyDataCellArray::Pointer verticesArray = polyDataMsg->GetVertices(); + igtl::PolyDataCellArray::Pointer verticesArray = this->InPolyDataMessage->GetVertices(); int nvertices = verticesArray.IsNotNull() ? verticesArray->GetNumberOfCells() : 0; if (nvertices > 0) { @@ -205,7 +245,7 @@ int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRML } // Lines - igtl::PolyDataCellArray::Pointer linesArray = polyDataMsg->GetLines(); + igtl::PolyDataCellArray::Pointer linesArray = this->InPolyDataMessage->GetLines(); int nlines = linesArray.IsNotNull() ? linesArray->GetNumberOfCells() : 0; if (nlines > 0) { @@ -230,7 +270,7 @@ int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRML } // Polygons - igtl::PolyDataCellArray::Pointer polygonsArray = polyDataMsg->GetPolygons(); + igtl::PolyDataCellArray::Pointer polygonsArray = this->InPolyDataMessage->GetPolygons(); int npolygons = polygonsArray.IsNotNull() ? polygonsArray->GetNumberOfCells() : 0; if (npolygons > 0) { @@ -255,7 +295,7 @@ int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRML } // Triangle Strips - igtl::PolyDataCellArray::Pointer triangleStripsArray = polyDataMsg->GetTriangleStrips(); + igtl::PolyDataCellArray::Pointer triangleStripsArray = this->InPolyDataMessage->GetTriangleStrips(); int ntstrips = triangleStripsArray.IsNotNull() ? triangleStripsArray->GetNumberOfCells() : 0; if (ntstrips > 0) { @@ -278,13 +318,12 @@ int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRML } poly->SetStrips(tstripCells); } - // Attribute - int nAttributes = polyDataMsg->GetNumberOfAttributes(); + int nAttributes = this->InPolyDataMessage->GetNumberOfAttributes(); for (int i = 0; i < nAttributes; i ++) { igtl::PolyDataAttribute::Pointer attribute; - attribute = polyDataMsg->GetAttribute(i); + attribute = this->InPolyDataMessage->GetAttribute(i); vtkSmartPointer data = vtkSmartPointer::New(); @@ -339,13 +378,18 @@ int vtkIGTLToMRMLPolyData::IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRML poly->GetCellData()->AddArray(data); } } - - + + vtkMRMLModelNode* modelNode = vtkMRMLModelNode::SafeDownCast(node); + if (modelNode==NULL) + { + vtkErrorMacro("vtkIGTLToMRMLPolyData::IGTLToMRML failed: invalid node"); + return 0; + } + modelNode->SetAndObservePolyData(poly); - + poly->Modified(); modelNode->Modified(); - return 1; } @@ -358,9 +402,9 @@ int vtkIGTLToMRMLPolyData::MRMLToIGTL(unsigned long event, vtkMRMLNode* mrmlNode { return 0; } - + bool isMRMLSupported = this->CheckIfMRMLSupported(mrmlNode->GetNodeTagName()); // If mrmlNode is PolyData node - if (event == vtkMRMLModelNode::PolyDataModifiedEvent && strcmp(mrmlNode->GetNodeTagName(), "Model") == 0) + if (event == vtkMRMLModelNode::PolyDataModifiedEvent && isMRMLSupported) { vtkMRMLModelNode* modelNode = vtkMRMLModelNode::SafeDownCast(mrmlNode); diff --git a/MRML/vtkIGTLToMRMLPolyData.h b/MRML/vtkIGTLToMRMLPolyData.h index 9493a1b..d181370 100644 --- a/MRML/vtkIGTLToMRMLPolyData.h +++ b/MRML/vtkIGTLToMRMLPolyData.h @@ -40,15 +40,42 @@ class VTK_SLICER_OPENIGTLINKIF_MODULE_MRML_EXPORT vtkIGTLToMRMLPolyData : public void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE; virtual const char* GetIGTLName() VTK_OVERRIDE { return "POLYDATA"; }; - virtual const char* GetMRMLName() VTK_OVERRIDE { return "Model"; }; + virtual const char* GetMRMLName() VTK_OVERRIDE + { + if(this->InPolyDataMessage.IsNotNull()) + { + bool isTensorDataInside = false; + for (int i = 0; i < this->InPolyDataMessage->GetNumberOfAttributes(); i ++) + { + igtl::PolyDataAttribute::Pointer attribute; + attribute = this->InPolyDataMessage->GetAttribute(i); + if ((attribute->GetType() & 0x0F ) == igtl::PolyDataAttribute::POINT_TENSOR) + { + isTensorDataInside = true; + break; + } + } + if(isTensorDataInside) + { + return "FiberBundle"; + } + } + return "Model"; + }; virtual vtkIntArray* GetNodeEvents() VTK_OVERRIDE; virtual vtkMRMLNode* CreateNewNodeWithMessage(vtkMRMLScene* scene, const char* name, igtl::MessageBase::Pointer incomingPolyDataMessage) VTK_OVERRIDE; - + virtual int UnpackIGTLMessage(igtl::MessageBase::Pointer buffer) VTK_OVERRIDE; virtual int IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRMLNode* node) VTK_OVERRIDE; virtual int MRMLToIGTL(unsigned long event, vtkMRMLNode* mrmlNode, int* size, void** igtlMsg) VTK_OVERRIDE; - + virtual std::vector GetAllMRMLNames() VTK_OVERRIDE + { + this->MRMLNames.clear(); + this->MRMLNames.push_back("Model"); + this->MRMLNames.push_back("FiberBundle"); + return this->MRMLNames; + } protected: vtkIGTLToMRMLPolyData(); ~vtkIGTLToMRMLPolyData(); @@ -63,7 +90,7 @@ class VTK_SLICER_OPENIGTLINKIF_MODULE_MRML_EXPORT vtkIGTLToMRMLPolyData : public int VTKToIGTLAttribute(vtkDataSetAttributes* src, int i, igtl::PolyDataAttribute* dest); protected: - + igtl::PolyDataMessage::Pointer InPolyDataMessage; igtl::PolyDataMessage::Pointer OutPolyDataMessage; igtl::GetPolyDataMessage::Pointer GetPolyDataMessage;