/*========================================================================= medInria Copyright (c) INRIA 2013 - 2018. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "vtkXMLFiberDataSetReader.h" #include "vtkCompositeDataPipeline.h" #include "vtkDataSet.h" #include "vtkInformation.h" #include "vtkFiberDataSet.h" #include "vtkPolyData.h" #include "vtkPointData.h" #include "vtkObjectFactory.h" #include "vtkSmartPointer.h" #include "vtkXMLDataElement.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include #include #include vtkStandardNewMacro(vtkXMLFiberDataSetReader); //---------------------------------------------------------------------------- vtkXMLFiberDataSetReader::vtkXMLFiberDataSetReader() { } //---------------------------------------------------------------------------- vtkXMLFiberDataSetReader::~vtkXMLFiberDataSetReader() { } //---------------------------------------------------------------------------- void vtkXMLFiberDataSetReader::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } //---------------------------------------------------------------------------- int vtkXMLFiberDataSetReader::FillOutputPortInformation( int vtkNotUsed(port), vtkInformation* info) { info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkFiberDataSet"); return 1; } //---------------------------------------------------------------------------- const char* vtkXMLFiberDataSetReader::GetDataSetName() { return "vtkFiberDataSet"; } //---------------------------------------------------------------------------- vtkFiberDataSet *vtkXMLFiberDataSetReader::GetOutput() { return this->GetOutput (0); } //---------------------------------------------------------------------------- vtkFiberDataSet *vtkXMLFiberDataSetReader::GetOutput(int port) { return vtkFiberDataSet::SafeDownCast(this->GetOutputDataObject(port)); } //---------------------------------------------------------------------------- void vtkXMLFiberDataSetReader::ReadComposite(vtkXMLDataElement* element, vtkCompositeDataSet* composite, const char* filePath, unsigned int &dataSetIndex) { vtkFiberDataSet* fiberDataSet = vtkFiberDataSet::SafeDownCast(composite); if (!fiberDataSet) { vtkErrorMacro("Unsuported composite dataset."); return; } if (this->GetFileMajorVersion() < 1) { vtkErrorMacro("Deprecated file format, unsupported."); return; } unsigned int maxElems = element->GetNumberOfNestedElements(); for (unsigned int cc=0; cc < maxElems; ++cc) { vtkXMLDataElement* childXML = element->GetNestedElement(cc); if (!childXML || !childXML->GetName()) { continue; } int index = 0; if (!childXML->GetScalarAttribute("index", index)) // if index not in the structure file, then // set up to add at the end { index = fiberDataSet->GetNumberOfBlocks(); } // child is a leaf node, read and insert. const char* tagName = childXML->GetName(); if (strcmp(tagName, "Fibers") == 0) { vtkSmartPointer childDS; // if (this->ShouldReadDataSet(dataSetIndex)) // CountLeaves return erroneous values { // Read childDS.TakeReference(this->ReadDataset(childXML, filePath)); } // Check vtk data and re-add local and global colors if not there vtkPolyData *childData = vtkPolyData::SafeDownCast (childDS); if (!childData->GetPointData()->GetScalars()) this->GenerateLocalColors(childData); if (!childData->GetCellData()->GetScalars()) this->GenerateGlobalColors(childData); // insert fiberDataSet->SetFibers(childData); } else if (strcmp(tagName, "Bundle") == 0) { vtkSmartPointer childDS; const char *bundleName = childXML->GetAttribute ("name"); double color[3] = {0.0, 0.0, 0.0}; childXML->GetScalarAttribute ("red", color[0]); childXML->GetScalarAttribute ("green", color[1]); childXML->GetScalarAttribute ("blue", color[2]); // if (this->ShouldReadDataSet(dataSetIndex)) // CountLeaves return erroneous values { // Read childDS.TakeReference(this->ReadDataset(childXML, filePath)); } // insert vtkPolyData *bundle = vtkPolyData::SafeDownCast (childDS); if (fiberDataSet->GetFibers()) { bundle->SetPoints(fiberDataSet->GetFibers()->GetPoints()); bundle->GetPointData()->SetScalars(fiberDataSet->GetFibers()->GetPointData()->GetScalars()); for( int i=0; iGetFibers()->GetPointData()->GetNumberOfArrays(); i++) { bundle->GetPointData()->AddArray ( fiberDataSet->GetFibers()->GetPointData()->GetArray (i) ); } } fiberDataSet->AddBundle(bundleName, bundle, color); } else { vtkErrorMacro("Syntax error in file."); return; } } } void vtkXMLFiberDataSetReader::GenerateLocalColors(vtkPolyData *data) { // Regenerate colors by local direction vtkSmartPointer myColors = vtkUnsignedCharArray::New(); vtkIdType nbTotalPts = data->GetNumberOfPoints(); myColors->SetNumberOfComponents (3); myColors->SetNumberOfValues(3*nbTotalPts); vtkIdType nbCells = data->GetNumberOfCells(); vtkVector diff; for (int j = 0;j < nbCells;++j) { vtkCell* cell = data->GetCell(j); vtkPoints* cellPts = cell->GetPoints(); vtkIdType nbPts = cellPts->GetNumberOfPoints(); if (nbPts > 0) { double endPtVals[3]; double firstPtVals[3]; if (nbPts > 1) cellPts->GetPoint(1,endPtVals); else cellPts->GetPoint(0,endPtVals); cellPts->GetPoint(0,firstPtVals); int ptId = cell->GetPointId(0); for( unsigned int i=0; i<3; i++) diff[i] = endPtVals[i] - firstPtVals[i]; if (diff.Norm() != 0) diff.Normalize(); for( unsigned int i=0; i<3; i++) { double c = fabs (diff[i])*255.0; myColors->SetValue(3*ptId + i, (unsigned char)( c>255.0?255.0:c ) ); } for( int i=1; iGetPoint(i+1,endPtVals); cellPts->GetPoint(i-1,firstPtVals); ptId = cell->GetPointId(i); for( unsigned int a=0; a<3; a++) diff[a] = endPtVals[a] - firstPtVals[a]; if (diff.Norm() != 0) diff.Normalize(); for( unsigned int a=0; a<3; a++) { double c = fabs (diff[a])*255.0; myColors->SetValue(3*ptId + a, (unsigned char)( c>255.0?255.0:c ) ); } } cellPts->GetPoint(nbPts-1,endPtVals); cellPts->GetPoint(nbPts-2,firstPtVals); ptId = cell->GetPointId(nbPts - 1); for( unsigned int a=0; a<3; a++) diff[a] = endPtVals[a] - firstPtVals[a]; if (diff.Norm() != 0) diff.Normalize(); for( unsigned int a=0; a<3; a++) { double c = fabs (diff[a])*255.0; myColors->SetValue(3*ptId + a, (unsigned char)( c>255.0?255.0:c ) ); } } } data->GetPointData()->SetScalars(myColors); } void vtkXMLFiberDataSetReader::GenerateGlobalColors(vtkPolyData *data) { // Regenerate colors by global tract direction vtkSmartPointer myCellColors = vtkUnsignedCharArray::New(); myCellColors->SetNumberOfComponents (3); vtkIdType nbCells = data->GetNumberOfCells(); vtkVector diff; for (int j = 0;j < nbCells;++j) { vtkCell* cell = data->GetCell(j); vtkPoints* cellPts = cell->GetPoints(); vtkIdType nbPts = cellPts->GetNumberOfPoints(); if (nbPts > 0) { double endPtVals[3]; double firstPtVals[3]; cellPts->GetPoint(nbPts-1,endPtVals); cellPts->GetPoint(0,firstPtVals); for( unsigned int i=0; i<3; i++) diff[i] = endPtVals[i] - firstPtVals[i]; if (diff.Norm() != 0) diff.Normalize(); for( unsigned int i=0; i<3; i++) { double c = fabs (diff[i])*255.0; myCellColors->InsertNextValue( (unsigned char)( c>255.0?255.0:c ) ); } } } data->GetCellData()->SetScalars(myCellColors); } //---------------------------------------------------------------------------- int vtkXMLFiberDataSetReader::RequestDataObject(vtkInformation* vtkNotUsed(request), vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector ) { //RequestDataObject (RDO) is an earlier pipeline pass. //During RDO, each filter is supposed to produce an empty data object of the proper type vtkInformation* outInfo = outputVector->GetInformationObject(0); vtkFiberDataSet* output = vtkFiberDataSet::SafeDownCast( outInfo->Get( vtkDataObject::DATA_OBJECT() ) ); if ( ! output ) { output = vtkFiberDataSet::New(); outInfo->Set( vtkDataObject::DATA_OBJECT(), output ); output->FastDelete(); this->GetOutputPortInformation(0)->Set( vtkDataObject::DATA_EXTENT_TYPE(), output->GetExtentType() ); } return 1; }