/*========================================================================= Program: Visualization Toolkit Module: vtkEdgeLayout.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /*---------------------------------------------------------------------------- Copyright (c) Sandia Corporation See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. ----------------------------------------------------------------------------*/ #include "vtkEdgeLayout.h" #include "vtkCellArray.h" #include "vtkCellData.h" #include "vtkDataArray.h" #include "vtkEventForwarderCommand.h" #include "vtkFloatArray.h" #include "vtkEdgeLayoutStrategy.h" #include "vtkMath.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPoints.h" vtkStandardNewMacro(vtkEdgeLayout); // ---------------------------------------------------------------------- vtkEdgeLayout::vtkEdgeLayout() { this->LayoutStrategy = nullptr; this->InternalGraph = nullptr; this->ObserverTag = 0; this->EventForwarder = vtkEventForwarderCommand::New(); this->EventForwarder->SetTarget(this); } // ---------------------------------------------------------------------- vtkEdgeLayout::~vtkEdgeLayout() { if (this->LayoutStrategy) { this->LayoutStrategy->Delete(); } if (this->InternalGraph) { this->InternalGraph->Delete(); } this->EventForwarder->Delete(); } // ---------------------------------------------------------------------- void vtkEdgeLayout::SetLayoutStrategy(vtkEdgeLayoutStrategy *strategy) { // This method is a cut and paste of vtkCxxSetObjectMacro // except for the call to SetEdge in the middle :) if (strategy != this->LayoutStrategy) { vtkEdgeLayoutStrategy *tmp = this->LayoutStrategy; this->LayoutStrategy = strategy; if (this->LayoutStrategy != nullptr) { this->LayoutStrategy->Register(this); this->ObserverTag = this->LayoutStrategy->AddObserver(vtkCommand::ProgressEvent, this->EventForwarder); if (this->InternalGraph) { // Set the graph in the layout strategy this->LayoutStrategy->SetGraph(this->InternalGraph); } } if (tmp != nullptr) { tmp->RemoveObserver(this->ObserverTag); tmp->UnRegister(this); } this->Modified(); } } // ---------------------------------------------------------------------- vtkMTimeType vtkEdgeLayout::GetMTime() { vtkMTimeType mTime = this->Superclass::GetMTime(); vtkMTimeType time; if (this->LayoutStrategy != nullptr) { time = this->LayoutStrategy->GetMTime(); mTime = (time > mTime ? time : mTime); } return mTime; } // ---------------------------------------------------------------------- int vtkEdgeLayout::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { if (this->LayoutStrategy == nullptr) { vtkErrorMacro(<< "Layout strategy must be non-null."); return 0; } // get the info objects vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0); // get the input and output vtkGraph *input = vtkGraph::SafeDownCast( inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkGraph *output = vtkGraph::SafeDownCast( outInfo->Get(vtkDataObject::DATA_OBJECT())); if (this->InternalGraph) { this->InternalGraph->Delete(); } this->InternalGraph = input->NewInstance(); // The strategy object is going to modify the Points member so // we'll replace that with a deep copy. For everything else a // shallow copy is sufficient. this->InternalGraph->ShallowCopy(input); // Copy the edge layout points. this->InternalGraph->DeepCopyEdgePoints(input); // Give the layout strategy a pointer to the input. We set it to // nullptr first to force the layout algorithm to re-initialize // itself. This is necessary in case the input is the same data // object with a newer mtime. this->LayoutStrategy->SetGraph(nullptr); this->LayoutStrategy->SetGraph(this->InternalGraph); // No matter whether the input is new or not, the layout strategy // needs to do its thing. It modifies its input // (this->InternalGraph) so we can just use that as the output. this->LayoutStrategy->Layout(); output->ShallowCopy(this->InternalGraph); return 1; } // ---------------------------------------------------------------------- void vtkEdgeLayout::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "LayoutStrategy: " << (this->LayoutStrategy ? "" : "(none)") << endl; if (this->LayoutStrategy) { this->LayoutStrategy->PrintSelf(os, indent.GetNextIndent()); } os << indent << "InternalGraph: " << (this->InternalGraph ? "" : "(none)") << endl; if (this->InternalGraph) { this->InternalGraph->PrintSelf(os, indent.GetNextIndent()); } }