/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkAlgorithm.cxx,v $ 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. =========================================================================*/ #include "vtkAlgorithm.h" #include "vtkAlgorithmOutput.h" #include "vtkCellData.h" #include "vtkCommand.h" #include "vtkDataObject.h" #include "vtkDataSet.h" #include "vtkErrorCode.h" #include "vtkFieldData.h" #include "vtkGarbageCollector.h" #include "vtkInformation.h" #include "vtkInformationInformationVectorKey.h" #include "vtkInformationIntegerKey.h" #include "vtkInformationStringKey.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkSmartPointer.h" #include "vtkStreamingDemandDrivenPipeline.h" #include #include vtkCxxRevisionMacro(vtkAlgorithm, "$Revision: 1.27.4.3 $"); vtkStandardNewMacro(vtkAlgorithm); vtkCxxSetObjectMacro(vtkAlgorithm,Information,vtkInformation); vtkInformationKeyMacro(vtkAlgorithm, INPUT_REQUIRED_DATA_TYPE, String); vtkInformationKeyMacro(vtkAlgorithm, INPUT_IS_OPTIONAL, Integer); vtkInformationKeyMacro(vtkAlgorithm, INPUT_IS_REPEATABLE, Integer); vtkInformationKeyMacro(vtkAlgorithm, INPUT_REQUIRED_FIELDS, InformationVector); vtkInformationKeyMacro(vtkAlgorithm, PORT_REQUIREMENTS_FILLED, Integer); vtkInformationKeyMacro(vtkAlgorithm, INPUT_PORT, Integer); vtkInformationKeyMacro(vtkAlgorithm, INPUT_CONNECTION, Integer); vtkInformationKeyMacro(vtkAlgorithm, INPUT_ARRAYS_TO_PROCESS, InformationVector); vtkExecutive* vtkAlgorithm::DefaultExecutivePrototype = 0; //---------------------------------------------------------------------------- class vtkAlgorithmInternals { public: // Proxy object instances for use in establishing connections from // the output ports to other algorithms. vtkstd::vector< vtkSmartPointer > Outputs; }; //---------------------------------------------------------------------------- class vtkAlgorithmToExecutiveFriendship { public: static void SetAlgorithm(vtkExecutive* executive, vtkAlgorithm* algorithm) { executive->SetAlgorithm(algorithm); } }; //---------------------------------------------------------------------------- vtkAlgorithm::vtkAlgorithm() { this->AbortExecute = 0; this->ErrorCode = 0; this->Progress = 0.0; this->ProgressText = NULL; this->Executive = 0; this->InputPortInformation = vtkInformationVector::New(); this->OutputPortInformation = vtkInformationVector::New(); this->AlgorithmInternal = new vtkAlgorithmInternals; this->Information = vtkInformation::New(); this->Information->Register(this); this->Information->Delete(); } //---------------------------------------------------------------------------- vtkAlgorithm::~vtkAlgorithm() { this->SetInformation(0); if(this->Executive) { this->Executive->UnRegister(this); this->Executive = 0; } this->InputPortInformation->Delete(); this->OutputPortInformation->Delete(); delete this->AlgorithmInternal; delete [] this->ProgressText; this->ProgressText = NULL; } //---------------------------------------------------------------------------- // Update the progress of the process object. If a ProgressMethod exists, // executes it. Then set the Progress ivar to amount. The parameter amount // should range between (0,1). void vtkAlgorithm::UpdateProgress(double amount) { this->Progress = amount; this->InvokeEvent(vtkCommand::ProgressEvent,(void *)&amount); } //---------------------------------------------------------------------------- vtkInformation *vtkAlgorithm ::GetInputArrayFieldInformation(int idx, vtkInformationVector **inputVector) { // first get out association vtkInformation *info = this->GetInputArrayInformation(idx); // then get the actual info object from the pinfo int port = info->Get(INPUT_PORT()); int connection = info->Get(INPUT_CONNECTION()); int fieldAssoc = info->Get(vtkDataObject::FIELD_ASSOCIATION()); vtkInformation *inInfo = inputVector[port]->GetInformationObject(connection); if (info->Has(vtkDataObject::FIELD_NAME())) { const char *name = info->Get(vtkDataObject::FIELD_NAME()); return vtkDataObject::GetNamedFieldInformation(inInfo, fieldAssoc, name); } int fType = info->Get(vtkDataObject::FIELD_ATTRIBUTE_TYPE()); return vtkDataObject::GetActiveFieldInformation(inInfo, fieldAssoc, fType); } //---------------------------------------------------------------------------- vtkInformation *vtkAlgorithm::GetInputArrayInformation(int idx) { // add this info into the algorithms info object vtkInformationVector *inArrayVec = this->Information->Get(INPUT_ARRAYS_TO_PROCESS()); if (!inArrayVec) { inArrayVec = vtkInformationVector::New(); this->Information->Set(INPUT_ARRAYS_TO_PROCESS(),inArrayVec); inArrayVec->Delete(); } vtkInformation *inArrayInfo = inArrayVec->GetInformationObject(idx); if (!inArrayInfo) { inArrayInfo = vtkInformation::New(); inArrayVec->SetInformationObject(idx,inArrayInfo); inArrayInfo->Delete(); } return inArrayInfo; } //---------------------------------------------------------------------------- void vtkAlgorithm::SetInputArrayToProcess(int idx, vtkInformation *inInfo) { vtkInformation *info = this->GetInputArrayInformation(idx); info->Copy(inInfo,1); this->Modified(); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetInputArrayToProcess(int idx, int port, int connection, int fieldAssociation, int attributeType) { vtkInformation *info = this->GetInputArrayInformation(idx); info->Set(INPUT_PORT(), port); info->Set(INPUT_CONNECTION(), connection); info->Set(vtkDataObject::FIELD_ASSOCIATION(),fieldAssociation); info->Set(vtkDataObject::FIELD_ATTRIBUTE_TYPE(), attributeType); // remove name if there is one info->Remove(vtkDataObject::FIELD_NAME()); this->Modified(); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetInputArrayToProcess( int idx, int port, int connection, const char* fieldAssociation, const char* fieldAttributeTypeOrName) { if (!fieldAssociation) { vtkErrorMacro("Association is requied"); return; } if (!fieldAttributeTypeOrName) { vtkErrorMacro("Attribute type or array name is required"); return ; } int i; // Try to convert the string argument to an enum value int association = -1; for (i=0; iSetInputArrayToProcess( idx, port, connection, association, fieldAttributeTypeOrName); return; } // Set by association and attribute type this->SetInputArrayToProcess( idx, port, connection, association, attributeType); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetInputArrayToProcess(int idx, int port, int connection, int fieldAssociation, const char *name) { // ignore empty string if (!name || name[0] == '\0') { return; } vtkInformation *info = this->GetInputArrayInformation(idx); info->Set(INPUT_PORT(), port); info->Set(INPUT_CONNECTION(), connection); info->Set(vtkDataObject::FIELD_ASSOCIATION(),fieldAssociation); info->Set(vtkDataObject::FIELD_NAME(),name); // remove fieldAttr if there is one info->Remove(vtkDataObject::FIELD_ATTRIBUTE_TYPE()); this->Modified(); } //---------------------------------------------------------------------------- vtkDataArray *vtkAlgorithm::GetInputArrayToProcess( int idx, vtkInformationVector **inputVector) { vtkInformationVector *inArrayVec = this->Information->Get(INPUT_ARRAYS_TO_PROCESS()); if (!inArrayVec) { vtkErrorMacro ("Attempt to get an input array for an index that has not been specified"); return NULL; } vtkInformation *inArrayInfo = inArrayVec->GetInformationObject(idx); if (!inArrayInfo) { vtkErrorMacro ("Attempt to get an input array for an index that has not been specified"); return NULL; } int connection = inArrayInfo->Get(INPUT_CONNECTION()); return this->GetInputArrayToProcess(idx, connection, inputVector); } //---------------------------------------------------------------------------- vtkDataArray *vtkAlgorithm::GetInputArrayToProcess( int idx, int connection, vtkInformationVector **inputVector) { vtkInformationVector *inArrayVec = this->Information->Get(INPUT_ARRAYS_TO_PROCESS()); if (!inArrayVec) { vtkErrorMacro ("Attempt to get an input array for an index that has not been specified"); return NULL; } vtkInformation *inArrayInfo = inArrayVec->GetInformationObject(idx); if (!inArrayInfo) { vtkErrorMacro ("Attempt to get an input array for an index that has not been specified"); return NULL; } int port = inArrayInfo->Get(INPUT_PORT()); int fieldAssoc = inArrayInfo->Get(vtkDataObject::FIELD_ASSOCIATION()); vtkInformation *inInfo = inputVector[port]->GetInformationObject(connection); vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT()); if (inArrayInfo->Has(vtkDataObject::FIELD_NAME())) { const char *name = inArrayInfo->Get(vtkDataObject::FIELD_NAME()); if (fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_NONE) { vtkFieldData *fd = input->GetFieldData(); return fd->GetArray(name); } vtkDataSet *inputDS = vtkDataSet::SafeDownCast(input); if (!inputDS) { vtkErrorMacro("Attempt to get point or cell data from a data object"); return NULL; } if (fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_POINTS) { return inputDS->GetPointData()->GetArray(name); } if (fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS && inputDS->GetPointData()->GetArray(name)) { return inputDS->GetPointData()->GetArray(name); } return inputDS->GetCellData()->GetArray(name); } else { int fType = inArrayInfo->Get(vtkDataObject::FIELD_ATTRIBUTE_TYPE()); // must have a data set vtkDataSet *inputDS = vtkDataSet::SafeDownCast(input); if (!inputDS) { vtkErrorMacro("Attempt to get point or cell data from a data object"); return NULL; } if (fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_POINTS) { return inputDS->GetPointData()->GetAttribute(fType); } if (fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS && inputDS->GetPointData()->GetAttribute(fType)) { return inputDS->GetPointData()->GetAttribute(fType); } return inputDS->GetCellData()->GetAttribute(fType); } } //---------------------------------------------------------------------------- void vtkAlgorithm::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); if(this->HasExecutive()) { os << indent << "Executive: " << this->Executive << "\n"; } else { os << indent << "Executive: (none)\n"; } os << indent << "ErrorCode: " << vtkErrorCode::GetStringFromErrorCode(this->ErrorCode) << endl; if ( this->Information ) { os << indent << "Information: " << this->Information << "\n"; } else { os << indent << "Information: (none)\n"; } os << indent << "AbortExecute: " << (this->AbortExecute ? "On\n" : "Off\n"); os << indent << "Progress: " << this->Progress << "\n"; if ( this->ProgressText ) { os << indent << "Progress Text: " << this->ProgressText << "\n"; } else { os << indent << "Progress Text: (None)\n"; } } //---------------------------------------------------------------------------- int vtkAlgorithm::HasExecutive() { return this->Executive ? 1 : 0; } //---------------------------------------------------------------------------- vtkExecutive* vtkAlgorithm::GetExecutive() { // Create the default executive if we do not have one already. if(!this->HasExecutive()) { vtkExecutive* e = this->CreateDefaultExecutive(); this->SetExecutive(e); e->Delete(); } return this->Executive; } //---------------------------------------------------------------------------- void vtkAlgorithm::SetExecutive(vtkExecutive* newExecutive) { vtkExecutive* oldExecutive = this->Executive; if(newExecutive != oldExecutive) { if(newExecutive) { newExecutive->Register(this); vtkAlgorithmToExecutiveFriendship::SetAlgorithm(newExecutive, this); } this->Executive = newExecutive; if(oldExecutive) { vtkAlgorithmToExecutiveFriendship::SetAlgorithm(oldExecutive, 0); oldExecutive->UnRegister(this); } } } //---------------------------------------------------------------------------- int vtkAlgorithm::ProcessRequest(vtkInformation* /* request */, vtkInformationVector**, vtkInformationVector*) { return 1; } //---------------------------------------------------------------------------- int vtkAlgorithm::ComputePipelineMTime(vtkInformation* /* request */, vtkInformationVector**, vtkInformationVector*, int /* requestFromOutputPort */, unsigned long* mtime) { // By default algorithms contribute only their own modified time. *mtime = this->GetMTime(); return 1; } //---------------------------------------------------------------------------- int vtkAlgorithm::ModifyRequest(vtkInformation* /*request*/, int /*when*/) { return 1; } //---------------------------------------------------------------------------- int vtkAlgorithm::GetNumberOfInputPorts() { return this->InputPortInformation->GetNumberOfInformationObjects(); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetNumberOfInputPorts(int n) { // Sanity check. if(n < 0) { vtkErrorMacro("Attempt to set number of input ports to " << n); n = 0; } // We must remove all connections from ports that are removed. for(int i=n; i < this->GetNumberOfInputPorts(); ++i) { this->SetNumberOfInputConnections(i, 0); } // Set the number of input port information objects. this->InputPortInformation->SetNumberOfInformationObjects(n); } //---------------------------------------------------------------------------- int vtkAlgorithm::GetNumberOfOutputPorts() { return this->OutputPortInformation->GetNumberOfInformationObjects(); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetNumberOfOutputPorts(int n) { // Sanity check. if(n < 0) { vtkErrorMacro("Attempt to set number of output ports to " << n); n = 0; } // We must remove all connections from ports that are removed. for(int i=n; i < this->GetNumberOfOutputPorts(); ++i) { // Get the producer and its output information for this port. vtkExecutive* producer = this->GetExecutive(); vtkInformation* info = producer->GetOutputInformation(i); // Remove all consumers' references to this producer on this port. vtkExecutive** consumers = info->GetExecutives(vtkExecutive::CONSUMERS()); int* consumerPorts = info->GetPorts(vtkExecutive::CONSUMERS()); int consumerCount = info->Length(vtkExecutive::CONSUMERS()); for(int j=0; j < consumerCount; ++j) { vtkInformationVector* inputs = consumers[j]->GetInputInformation(consumerPorts[j]); inputs->Remove(info); } // Remove this producer's references to all consumers on this port. info->Remove(vtkExecutive::CONSUMERS()); } // Set the number of output port information objects. this->OutputPortInformation->SetNumberOfInformationObjects(n); // Set the number of connection proxy objects. this->AlgorithmInternal->Outputs.resize(n); } //---------------------------------------------------------------------------- vtkInformation* vtkAlgorithm::GetInputPortInformation(int port) { if(!this->InputPortIndexInRange(port, "get information object for")) { return 0; } // Get the input port information object. vtkInformation* info = this->InputPortInformation->GetInformationObject(port); // Fill it if it has not yet been filled. if(!info->Has(PORT_REQUIREMENTS_FILLED())) { if(this->FillInputPortInformation(port, info)) { info->Set(PORT_REQUIREMENTS_FILLED(), 1); } else { info->Clear(); } } // Return ths information object. return info; } //---------------------------------------------------------------------------- vtkInformation* vtkAlgorithm::GetOutputPortInformation(int port) { if(!this->OutputPortIndexInRange(port, "get information object for")) { return 0; } // Get the output port information object. vtkInformation* info = this->OutputPortInformation->GetInformationObject(port); // Fill it if it has not yet been filled. if(!info->Has(PORT_REQUIREMENTS_FILLED())) { if(this->FillOutputPortInformation(port, info)) { info->Set(PORT_REQUIREMENTS_FILLED(), 1); } else { info->Clear(); } } // Return ths information object. return info; } //---------------------------------------------------------------------------- int vtkAlgorithm::FillInputPortInformation(int, vtkInformation*) { vtkErrorMacro("FillInputPortInformation is not implemented."); return 0; } //---------------------------------------------------------------------------- int vtkAlgorithm::FillOutputPortInformation(int, vtkInformation*) { vtkErrorMacro("FillOutputPortInformation is not implemented."); return 0; } //---------------------------------------------------------------------------- int vtkAlgorithm::InputPortIndexInRange(int index, const char* action) { // Make sure the index of the input port is in range. if(index < 0 || index >= this->GetNumberOfInputPorts()) { vtkErrorMacro("Attempt to " << (action?action:"access") << " input port index " << index << " for an algorithm with " << this->GetNumberOfInputPorts() << " input ports."); return 0; } return 1; } //---------------------------------------------------------------------------- int vtkAlgorithm::OutputPortIndexInRange(int index, const char* action) { // Make sure the index of the output port is in range. if(index < 0 || index >= this->GetNumberOfOutputPorts()) { vtkErrorMacro("Attempt to " << (action?action:"access") << " output port index " << index << " for an algorithm with " << this->GetNumberOfOutputPorts() << " output ports."); return 0; } return 1; } //---------------------------------------------------------------------------- void vtkAlgorithm::SetDefaultExecutivePrototype(vtkExecutive* proto) { if (vtkAlgorithm::DefaultExecutivePrototype == proto) { return; } if (vtkAlgorithm::DefaultExecutivePrototype) { vtkAlgorithm::DefaultExecutivePrototype->UnRegister(0); vtkAlgorithm::DefaultExecutivePrototype = 0; } proto->Register(0); vtkAlgorithm::DefaultExecutivePrototype = proto; } //---------------------------------------------------------------------------- vtkExecutive* vtkAlgorithm::CreateDefaultExecutive() { if (vtkAlgorithm::DefaultExecutivePrototype) { return vtkAlgorithm::DefaultExecutivePrototype->NewInstance(); } return vtkStreamingDemandDrivenPipeline::New(); } //---------------------------------------------------------------------------- void vtkAlgorithm::Register(vtkObjectBase* o) { this->RegisterInternal(o, 1); } //---------------------------------------------------------------------------- void vtkAlgorithm::UnRegister(vtkObjectBase* o) { this->UnRegisterInternal(o, 1); } //---------------------------------------------------------------------------- void vtkAlgorithm::ReportReferences(vtkGarbageCollector* collector) { this->Superclass::ReportReferences(collector); vtkGarbageCollectorReport(collector, this->Executive, "Executive"); } /// These are convenience methods to forward to the executive //---------------------------------------------------------------------------- vtkDataObject* vtkAlgorithm::GetOutputDataObject(int port) { return this->GetExecutive()->GetOutputData(port); } //---------------------------------------------------------------------------- void vtkAlgorithm::RemoveAllInputs() { this->SetInputConnection(0, 0); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetInputConnection(vtkAlgorithmOutput* input) { this->SetInputConnection(0,input); } void vtkAlgorithm::SetInputConnection(int port, vtkAlgorithmOutput* input) { if(!this->InputPortIndexInRange(port, "connect")) { return; } // Get the producer/consumer pair for the connection. vtkExecutive* producer = (input && input->GetProducer())? input->GetProducer()->GetExecutive() : 0; int producerPort = producer? input->GetIndex() : 0; vtkExecutive* consumer = this->GetExecutive(); int consumerPort = port; // Get the vector of connected input information objects. vtkInformationVector* inputs = consumer->GetInputInformation(consumerPort); // Get the information object from the producer of the new input. vtkInformation* newInfo = producer? producer->GetOutputInformation(producerPort) : 0; // Check if the connection is already present. if(!newInfo && inputs->GetNumberOfInformationObjects() == 0) { return; } else if(newInfo == inputs->GetInformationObject(0) && inputs->GetNumberOfInformationObjects() == 1) { return; } // The connection is not present. vtkDebugMacro("Setting connection to input port index " << consumerPort << " from output port index " << producerPort << " on algorithm " << (producer? producer->GetAlgorithm()->GetClassName() : "") << "(" << (producer? producer->GetAlgorithm() : 0) << ")."); // Add this consumer to the new input's list of consumers. if(newInfo) { newInfo->Append(vtkExecutive::CONSUMERS(), consumer, consumerPort); } // Remove this consumer from all old inputs' lists of consumers. for(int i=0; i < inputs->GetNumberOfInformationObjects(); ++i) { if(vtkInformation* oldInfo = inputs->GetInformationObject(i)) { oldInfo->Remove(vtkExecutive::CONSUMERS(), consumer, consumerPort); } } // Make the new input the only connection. if(newInfo) { inputs->SetInformationObject(0, newInfo); inputs->SetNumberOfInformationObjects(1); } else { inputs->SetNumberOfInformationObjects(0); } // This algorithm has been modified. this->Modified(); } //---------------------------------------------------------------------------- void vtkAlgorithm::AddInputConnection(vtkAlgorithmOutput* input) { this->AddInputConnection(0, input); } void vtkAlgorithm::AddInputConnection(int port, vtkAlgorithmOutput* input) { if(!this->InputPortIndexInRange(port, "connect")) { return; } // If there is no input do nothing. if(!input || !input->GetProducer()) { return; } // Get the producer/consumer pair for the connection. vtkExecutive* producer = input->GetProducer()->GetExecutive(); int producerPort = input->GetIndex(); vtkExecutive* consumer = this->GetExecutive(); int consumerPort = port; // Get the vector of connected input information objects. vtkInformationVector* inputs = consumer->GetInputInformation(consumerPort); // Add the new connection. vtkDebugMacro("Adding connection to input port index " << consumerPort << " from output port index " << producerPort << " on algorithm " << (producer? producer->GetAlgorithm()->GetClassName() : "") << "(" << (producer? producer->GetAlgorithm() : 0) << ")."); // Get the information object from the producer of the new input. vtkInformation* newInfo = producer->GetOutputInformation(producerPort); // Add this consumer to the input's list of consumers. newInfo->Append(vtkExecutive::CONSUMERS(), consumer, consumerPort); // Add the information object to the list of inputs. inputs->Append(newInfo); // This algorithm has been modified. this->Modified(); } //---------------------------------------------------------------------------- void vtkAlgorithm::RemoveInputConnection(int port, vtkAlgorithmOutput* input) { if(!this->InputPortIndexInRange(port, "disconnect")) { return; } // If there is no input do nothing. if(!input || !input->GetProducer()) { return; } // Get the producer/consumer pair for the connection. vtkExecutive* producer = input->GetProducer()->GetExecutive(); int producerPort = input->GetIndex(); vtkExecutive* consumer = this->GetExecutive(); int consumerPort = port; // Get the vector of connected input information objects. vtkInformationVector* inputs = consumer->GetInputInformation(consumerPort); // Remove the connection. vtkDebugMacro("Removing connection to input port index " << consumerPort << " from output port index " << producerPort << " on algorithm " << (producer? producer->GetAlgorithm()->GetClassName() : "") << "(" << (producer? producer->GetAlgorithm() : 0) << ")."); // Get the information object from the producer of the old input. vtkInformation* oldInfo = producer->GetOutputInformation(producerPort); // Remove this consumer from the old input's list of consumers. oldInfo->Remove(vtkExecutive::CONSUMERS(), consumer, consumerPort); // Remove the information object from the list of inputs. inputs->Remove(oldInfo); // This algorithm has been modified. this->Modified(); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetNthInputConnection(int port, int index, vtkAlgorithmOutput* input) { if(!this->InputPortIndexInRange(port, "replace connection")) { return; } // Get the producer/consumer pair for the connection. vtkExecutive* producer = (input && input->GetProducer())? input->GetProducer()->GetExecutive() : 0; int producerPort = producer? input->GetIndex() : 0; vtkExecutive* consumer = this->GetExecutive(); int consumerPort = port; // Get the vector of connected input information objects. vtkInformationVector* inputs = consumer->GetInputInformation(consumerPort); // Check for any existing connection with this index. vtkInformation* oldInfo = inputs->GetInformationObject(index); // Get the information object from the producer of the input. vtkInformation* newInfo = producer? producer->GetOutputInformation(producerPort) : 0; // If the connection has not changed, do nothing. if(newInfo == oldInfo) { return; } // Set the connection. vtkDebugMacro("Setting connection index " << index << " to input port index " << consumerPort << " from output port index " << producerPort << " on algorithm " << (producer? producer->GetAlgorithm()->GetClassName() : "") << "(" << (producer? producer->GetAlgorithm() : 0) << ")."); // Add the consumer to the new input's list of consumers. if(newInfo) { newInfo->Append(vtkExecutive::CONSUMERS(), consumer, consumerPort); } // Remove the consumer from the old input's list of consumers. if(oldInfo) { oldInfo->Remove(vtkExecutive::CONSUMERS(), consumer, consumerPort); } // Store the information object in the vector of input connections. inputs->SetInformationObject(index, newInfo); // This algorithm has been modified. this->Modified(); } //---------------------------------------------------------------------------- void vtkAlgorithm::SetNumberOfInputConnections(int port, int n) { // Get the consumer executive and port number. vtkExecutive* consumer = this->GetExecutive(); int consumerPort = port; // Get the vector of connected input information objects. vtkInformationVector* inputs = consumer->GetInputInformation(consumerPort); // If the number of connections has not changed, do nothing. if(n == inputs->GetNumberOfInformationObjects()) { return; } // Remove connections beyond the new number. for(int i=n; i < inputs->GetNumberOfInformationObjects(); ++i) { // Remove each input's reference to this consumer. if(vtkInformation* oldInfo = inputs->GetInformationObject(i)) { oldInfo->Remove(vtkExecutive::CONSUMERS(), consumer, consumerPort); } } // Set the number of connected inputs. Non-existing inputs will be // empty information objects. inputs->SetNumberOfInformationObjects(n); // This algorithm has been modified. this->Modified(); } //---------------------------------------------------------------------------- vtkAlgorithmOutput* vtkAlgorithm::GetOutputPort(int port) { if(!this->OutputPortIndexInRange(port, "get")) { return 0; } // Create the vtkAlgorithmOutput proxy object if there is not one. if(!this->AlgorithmInternal->Outputs[port]) { this->AlgorithmInternal->Outputs[port] = vtkSmartPointer::New(); this->AlgorithmInternal->Outputs[port]->SetProducer(this); this->AlgorithmInternal->Outputs[port]->SetIndex(port); } // Return the proxy object instance. return this->AlgorithmInternal->Outputs[port]; } //---------------------------------------------------------------------------- int vtkAlgorithm::GetNumberOfInputConnections(int port) { if(this->Executive) { return this->Executive->GetNumberOfInputConnections(port); } return 0; } //---------------------------------------------------------------------------- int vtkAlgorithm::GetTotalNumberOfInputConnections() { int i; int total = 0; for (i = 0; i < this->GetNumberOfInputPorts(); ++i) { total += this->GetNumberOfInputConnections(i); } return total; } //---------------------------------------------------------------------------- vtkAlgorithmOutput* vtkAlgorithm::GetInputConnection(int port, int index) { if(index < 0 || index >= this->GetNumberOfInputConnections(port)) { vtkErrorMacro("Attempt to get connection index " << index << " for input port " << port << ", which has " << this->GetNumberOfInputConnections(port) << " connections."); return 0; } if(vtkInformation* info = this->GetExecutive()->GetInputInformation(port, index)) { // Get the executive producing this input. If there is none, then // it is a NULL input. vtkExecutive* producer; int producerPort; info->Get(vtkExecutive::PRODUCER(),producer,producerPort); if(producer) { return producer->GetAlgorithm()->GetOutputPort(producerPort); } } return 0; } //---------------------------------------------------------------------------- void vtkAlgorithm::Update() { this->GetExecutive()->Update(); } //---------------------------------------------------------------------------- void vtkAlgorithm::UpdateInformation() { vtkDemandDrivenPipeline* ddp = vtkDemandDrivenPipeline::SafeDownCast(this->GetExecutive()); if (ddp) { ddp->UpdateInformation(); } } //---------------------------------------------------------------------------- void vtkAlgorithm::UpdateWholeExtent() { vtkStreamingDemandDrivenPipeline* sddp = vtkStreamingDemandDrivenPipeline::SafeDownCast(this->GetExecutive()); if (sddp) { sddp->UpdateWholeExtent(); } else { this->Update(); } } //---------------------------------------------------------------------------- void vtkAlgorithm::ConvertTotalInputToPortConnection( int ind, int &port, int &conn) { port = 0; conn = 0; while (ind && port < this->GetNumberOfInputPorts()) { int pNumCon; pNumCon = this->GetNumberOfInputConnections(port); if (ind >= pNumCon) { port++; ind -= pNumCon; } else { return; } } } //---------------------------------------------------------------------------- void vtkAlgorithm::ReleaseDataFlagOn() { if(vtkDemandDrivenPipeline* ddp = vtkDemandDrivenPipeline::SafeDownCast(this->GetExecutive())) { for(int i=0; i < this->GetNumberOfOutputPorts(); ++i) { ddp->SetReleaseDataFlag(i, 1); } } } //---------------------------------------------------------------------------- void vtkAlgorithm::ReleaseDataFlagOff() { if(vtkDemandDrivenPipeline* ddp = vtkDemandDrivenPipeline::SafeDownCast(this->GetExecutive())) { for(int i=0; i < this->GetNumberOfOutputPorts(); ++i) { ddp->SetReleaseDataFlag(i, 0); } } } //---------------------------------------------------------------------------- void vtkAlgorithm::SetReleaseDataFlag(int val) { if(vtkDemandDrivenPipeline* ddp = vtkDemandDrivenPipeline::SafeDownCast(this->GetExecutive())) { for(int i=0; i < this->GetNumberOfOutputPorts(); ++i) { ddp->SetReleaseDataFlag(i, val); } } } //---------------------------------------------------------------------------- int vtkAlgorithm::GetReleaseDataFlag() { if(vtkDemandDrivenPipeline* ddp = vtkDemandDrivenPipeline::SafeDownCast(this->GetExecutive())) { return ddp->GetReleaseDataFlag(0); } return 0; } //---------------------------------------------------------------------------- int vtkAlgorithm::UpdateExtentIsEmpty(vtkDataObject *output) { if (output == NULL) { return 1; } // get the pinfo object then call the info signature return this->UpdateExtentIsEmpty( output->GetPipelineInformation(), output->GetInformation()->Get(vtkDataObject::DATA_EXTENT_TYPE())); } //---------------------------------------------------------------------------- int vtkAlgorithm::UpdateExtentIsEmpty(vtkInformation *info, int extentType) { if (!info) { return 1; } int *ext; switch (extentType) { case VTK_PIECES_EXTENT: // Special way of asking for no input. if (info->Get( vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()) == 0 ) { return 1; } break; case VTK_3D_EXTENT: ext = info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT()); // Special way of asking for no input. (zero volume) if (!ext || ext[0] == (ext[1] + 1) || ext[2] == (ext[3] + 1) || ext[4] == (ext[5] + 1)) { return 1; } break; // We should never have this case occur default: vtkErrorMacro( << "Internal error - invalid extent type!" ); break; } return 0; }