From 1b09bf46253cb6614906dbae885ac7d14c1672b4 Mon Sep 17 00:00:00 2001 From: Andreas Buykx Date: Fri, 11 Feb 2022 11:14:04 +0100 Subject: [PATCH] Object name for reporting Error and warning messages from pipeline execution currently show only the class name and pointer. This is usually insufficient to determine for example which specific algorithm raises the error. This change introduces an object name for vtkObject. The object name is stored as a string member ObjectName with setter and getter. It is not a regular ivar: the MTime is not affected and no ModifiedEvent is invoked. The objectname is not to be copied by ShallowCopy and DeepCopy implementations. A new virtual method on vtkObjectBase, GetObjectDescription, returns the description that is used in error and warning messages and Print output. The vtkObjectBase implementation returns the class name and object pointer. The vtkObject implementation overrides this and prints the object name as well if it is set. The error messages issued by vtkExecutive classes now call the GetObjectDescription method of the algorithm so that if an algorithm has an object name it appears in the error message. Added a python test to demonstrate the behavior and a changelog entry to briefly describe this change. --- Common/Core/Testing/Python/CMakeLists.txt | 1 + Common/Core/Testing/Python/TestObjectName.py | 66 +++++++++++++++++++ Common/Core/vtkObject.cxx | 27 ++++++++ Common/Core/vtkObject.h | 18 +++++ Common/Core/vtkObjectBase.cxx | 9 ++- Common/Core/vtkObjectBase.h | 7 ++ Common/Core/vtkSetGet.h | 6 +- Common/ExecutionModel/vtkAlgorithm.cxx | 10 ++- .../vtkCompositeDataPipeline.cxx | 2 +- .../vtkDemandDrivenPipeline.cxx | 34 +++++----- Common/ExecutionModel/vtkExecutive.cxx | 27 ++++---- .../vtkStreamingDemandDrivenPipeline.cxx | 28 ++++---- .../vtkThreadedCompositeDataPipeline.cxx | 4 +- Documentation/release/dev/objectname.md | 4 ++ 14 files changed, 182 insertions(+), 61 deletions(-) create mode 100644 Common/Core/Testing/Python/TestObjectName.py create mode 100644 Documentation/release/dev/objectname.md diff --git a/Common/Core/Testing/Python/CMakeLists.txt b/Common/Core/Testing/Python/CMakeLists.txt index cad27e3ddbb..ed474bd0e8a 100644 --- a/Common/Core/Testing/Python/CMakeLists.txt +++ b/Common/Core/Testing/Python/CMakeLists.txt @@ -12,6 +12,7 @@ vtk_add_test_python( TestFilePath.py TestGhost.py TestIterateCollection.py + TestObjectName.py TestPassByReference.py TestNumpySupport.py TestNumpyInterface.py diff --git a/Common/Core/Testing/Python/TestObjectName.py b/Common/Core/Testing/Python/TestObjectName.py new file mode 100644 index 00000000000..c64f857c311 --- /dev/null +++ b/Common/Core/Testing/Python/TestObjectName.py @@ -0,0 +1,66 @@ +import unittest +from vtkmodules.vtkCommonCore import (vtkCommand, + vtkDoubleArray, + vtkObject, + VTK_STRING) +from vtkmodules.vtkCommonExecutionModel import (vtkTrivialProducer, + vtkExecutive) +from vtkmodules.vtkRenderingCore import vtkActor +from vtkmodules.vtkFiltersCore import vtkArrayCalculator +from vtkmodules.util.misc import calldata_type +from vtk.test import Testing + +class MessageObserver(Testing.vtkTest): + + def __init__(self): + self.event = None + self.message = str() + + @calldata_type(VTK_STRING) + def observe(self, obj, event, data): + self.event = event + self.message = str(data) + +class TestObjectName(Testing.vtkTest): + + def test_SetObjectNameSetsObjectName(self): + producer = vtkTrivialProducer() + producer.SetObjectName("foo") + self.assertEqual("foo",producer.GetObjectName()) + + + def testObjectDescriptionContainsObjectName(self): + producer = vtkTrivialProducer() + producer.SetObjectName("foo") + description=producer.GetObjectDescription() + self.assertTrue(description.endswith("'foo'")) + + + def testSetObjectNameDoesNotChangeMTime(self): + a = vtkDoubleArray() + mtime = a.GetMTime() + a.SetObjectName("foo") + self.assertEqual(mtime,a.GetMTime()) + + + def testErrorMessageContainsObjectName(self): + algorithm = vtkArrayCalculator() + algorithm.SetObjectName("foo") + observer = MessageObserver() + algorithm.GetExecutive().AddObserver(vtkCommand.ErrorEvent,observer.observe) + algorithm.Update() # this invokes an error event + self.assertEqual("ErrorEvent",observer.event) + self.assertTrue("'foo'" in observer.message, observer.message) + + + def testObjectNameNotCopied(self): + foo = vtkActor() + foo.SetObjectName("foo") + bar = vtkActor() + bar.SetObjectName("bar") + foo.ShallowCopy(bar) + self.assertNotEqual(foo.GetObjectName(),bar.GetObjectName()) + + +if __name__ == "__main__": + Testing.main([(TestObjectName, 'test')]) diff --git a/Common/Core/vtkObject.cxx b/Common/Core/vtkObject.cxx index 6bdc5889222..51769943ebc 100644 --- a/Common/Core/vtkObject.cxx +++ b/Common/Core/vtkObject.cxx @@ -22,6 +22,7 @@ #include "vtkWeakPointer.h" #include +#include #include // Initialize static member that controls warning display @@ -981,3 +982,29 @@ unsigned long vtkObject::AddTemplatedObserver( command->Delete(); return id; } + +//------------------------------------------------------------------------------ +void vtkObject::SetObjectName(const std::string& objectName) +{ + vtkDebugMacro(<< vtkObjectBase::GetObjectDescription() << "set object name to '" << objectName + << "'"); + this->ObjectName = objectName; +} + +//------------------------------------------------------------------------------ +std::string vtkObject::GetObjectName() const +{ + return this->ObjectName; +} + +//------------------------------------------------------------------------------ +std::string vtkObject::GetObjectDescription() const +{ + std::stringstream s; + s << this->Superclass::GetObjectDescription(); + if (!this->ObjectName.empty()) + { + s << " '" << this->ObjectName << "'"; + } + return s.str(); +} diff --git a/Common/Core/vtkObject.h b/Common/Core/vtkObject.h index 5158b5c4063..098efe60d7c 100644 --- a/Common/Core/vtkObject.h +++ b/Common/Core/vtkObject.h @@ -230,6 +230,23 @@ public: int InvokeEvent(unsigned long event) { return this->InvokeEvent(event, nullptr); } int InvokeEvent(const char* event) { return this->InvokeEvent(event, nullptr); } + ///@{ + /** + * Set/get the name of this object for reporting purposes. The name appears in + * warning and debug messages and in the Print output. Setting the object name + * does not change the MTime and does not invoke a ModifiedEvent. Derived + * classes implementing copying methods are expected not to copy the ObjectName. + */ + virtual void SetObjectName(const std::string& objectName); + virtual std::string GetObjectName() const; + ///@} + + /** + * The object description printed in messages and PrintSelf + * output. To be used only for reporting purposes. + */ + std::string GetObjectDescription() const override; + protected: vtkObject(); ~vtkObject() override; @@ -241,6 +258,7 @@ protected: bool Debug; // Enable debug messages vtkTimeStamp MTime; // Keep track of modification time vtkSubjectHelper* SubjectHelper; // List of observers on this object + std::string ObjectName; // Name of this object for reporting ///@{ /** diff --git a/Common/Core/vtkObjectBase.cxx b/Common/Core/vtkObjectBase.cxx index a6833403125..07e92d6749d 100644 --- a/Common/Core/vtkObjectBase.cxx +++ b/Common/Core/vtkObjectBase.cxx @@ -189,6 +189,13 @@ const char* vtkObjectBase::GetClassName() const return this->GetClassNameInternal(); } +std::string vtkObjectBase::GetObjectDescription() const +{ + std::stringstream s; + s << this->GetClassName() << " (" << this << ")"; + return s.str(); +} + vtkTypeBool vtkObjectBase::IsTypeOf(const char* name) { if (!strcmp("vtkObjectBase", name)) @@ -247,7 +254,7 @@ void vtkObjectBase::Print(ostream& os) void vtkObjectBase::PrintHeader(ostream& os, vtkIndent indent) { - os << indent << this->GetClassName() << " (" << this << ")\n"; + os << indent << this->GetObjectDescription() << "\n"; } // Chaining method to print an object's instance variables, as well as diff --git a/Common/Core/vtkObjectBase.h b/Common/Core/vtkObjectBase.h index 1ff6b55e154..461befac19c 100644 --- a/Common/Core/vtkObjectBase.h +++ b/Common/Core/vtkObjectBase.h @@ -55,6 +55,7 @@ #include "vtkType.h" #include // For std::atomic +#include class vtkGarbageCollector; class vtkGarbageCollectorToObjectBaseFriendship; @@ -87,6 +88,12 @@ public: */ const char* GetClassName() const; + /** + * The object description printed in messages and PrintSelf + * output. To be used only for reporting purposes. + */ + virtual std::string GetObjectDescription() const; + #ifdef VTK_WORKAROUND_WINDOWS_MANGLE #undef GetClassNameW #undef GetClassNameA diff --git a/Common/Core/vtkSetGet.h b/Common/Core/vtkSetGet.h index 26f3eab189e..257415ce2de 100644 --- a/Common/Core/vtkSetGet.h +++ b/Common/Core/vtkSetGet.h @@ -832,7 +832,7 @@ extern VTKCOMMONCORE_EXPORT void vtkOutputWindowDisplayDebugText( vtkObject* _object = const_cast(static_cast(self)); \ if (_object) \ { \ - vtkmsg << _object->GetClassName() << " (" << _object << "): "; \ + vtkmsg << _object->GetObjectDescription() << ": "; \ } \ else \ { \ @@ -863,7 +863,7 @@ extern VTKCOMMONCORE_EXPORT void vtkOutputWindowDisplayDebugText( vtkObject* _object = const_cast(static_cast(self)); \ if (_object) \ { \ - vtkmsg << _object->GetClassName() << " (" << _object << "): "; \ + vtkmsg << _object->GetObjectDescription() << ": "; \ } \ else \ { \ @@ -899,7 +899,7 @@ extern VTKCOMMONCORE_EXPORT void vtkOutputWindowDisplayDebugText( vtkOStrStreamWrapper vtkmsg; \ if (_object) \ { \ - vtkmsg << _object->GetClassName() << " (" << _object << "): "; \ + vtkmsg << _object->GetObjectDescription() << ": "; \ } \ else \ { \ diff --git a/Common/ExecutionModel/vtkAlgorithm.cxx b/Common/ExecutionModel/vtkAlgorithm.cxx index 074444a470e..a26e92490ad 100644 --- a/Common/ExecutionModel/vtkAlgorithm.cxx +++ b/Common/ExecutionModel/vtkAlgorithm.cxx @@ -998,8 +998,7 @@ void vtkAlgorithm::SetInputConnection(int port, vtkAlgorithmOutput* input) // 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() : nullptr) << ")."); + << (producer ? producer->GetObjectDescription() : nullptr) << "."); // Add this consumer to the new input's list of consumers. if (newInfo) @@ -1063,7 +1062,7 @@ void vtkAlgorithm::AddInputConnection(int port, vtkAlgorithmOutput* input) // Add the new connection. vtkDebugMacro("Adding connection to input port index " << consumerPort << " from output port index " << producerPort << " on algorithm " - << producer->GetAlgorithm()->GetClassName() << "(" << producer->GetAlgorithm() << ")."); + << producer->GetAlgorithm()->GetObjectDescription() << "."); // Get the information object from the producer of the new input. vtkInformation* newInfo = producer->GetOutputInformation(producerPort); @@ -1155,7 +1154,7 @@ void vtkAlgorithm::RemoveInputConnection(int port, vtkAlgorithmOutput* input) // Remove the connection. vtkDebugMacro("Removing connection to input port index " << consumerPort << " from output port index " << producerPort << " on algorithm " - << producer->GetAlgorithm()->GetClassName() << "(" << producer->GetAlgorithm() << ")."); + << producer->GetAlgorithm()->GetObjectDescription() << "."); // Get the information object from the producer of the old input. vtkInformation* oldInfo = producer->GetOutputInformation(producerPort); @@ -1204,8 +1203,7 @@ void vtkAlgorithm::SetNthInputConnection(int port, int index, vtkAlgorithmOutput vtkDebugMacro("Setting connection index " << index << " to input port index " << consumerPort << " from output port index " << producerPort << " on algorithm " - << (producer ? producer->GetAlgorithm()->GetClassName() : "") << "(" - << (producer ? producer->GetAlgorithm() : nullptr) << ")."); + << (producer ? producer->GetAlgorithm()->GetObjectDescription() : "nullptr") << "."); // Add the consumer to the new input's list of consumers. if (newInfo) diff --git a/Common/ExecutionModel/vtkCompositeDataPipeline.cxx b/Common/ExecutionModel/vtkCompositeDataPipeline.cxx index e9e6325f785..3c358a58ba2 100644 --- a/Common/ExecutionModel/vtkCompositeDataPipeline.cxx +++ b/Common/ExecutionModel/vtkCompositeDataPipeline.cxx @@ -151,7 +151,7 @@ int vtkCompositeDataPipeline::ExecuteData( } else { - vtkErrorMacro("Can not execute simple algorithm " << this->Algorithm->GetClassName() + vtkErrorMacro("Can not execute simple algorithm " << this->Algorithm->GetObjectDescription() << " without output ports"); return 0; } diff --git a/Common/ExecutionModel/vtkDemandDrivenPipeline.cxx b/Common/ExecutionModel/vtkDemandDrivenPipeline.cxx index 0a24088ac99..25ed87dbf1f 100644 --- a/Common/ExecutionModel/vtkDemandDrivenPipeline.cxx +++ b/Common/ExecutionModel/vtkDemandDrivenPipeline.cxx @@ -96,17 +96,16 @@ int vtkDemandDrivenPipeline::ComputePipelineMTime(vtkInformation* request, { if (request) { - vtkErrorMacro("Algorithm " << this->Algorithm->GetClassName() << "(" << this->Algorithm - << ") returned failure for pipeline" + vtkErrorMacro("Algorithm " << this->Algorithm->GetObjectDescription() + << " returned failure for pipeline" << " modified time request from output port " << requestFromOutputPort << ": " << *request); } else { - vtkErrorMacro("Algorithm " << this->Algorithm->GetClassName() << "(" << this->Algorithm - << ") returned failure for pipeline" - << " modified time request from output port " - << requestFromOutputPort << "."); + vtkErrorMacro( + "Algorithm " << this->Algorithm->GetObjectDescription() << " returned failure for pipeline" + << " modified time request from output port " << requestFromOutputPort << "."); } return 0; } @@ -609,8 +608,8 @@ int vtkDemandDrivenPipeline::CheckDataObject(int port, vtkInformationVector* out if (!data) { // The algorithm has a bug and did not create the data object. - vtkErrorMacro("Algorithm " << this->Algorithm->GetClassName() << "(" << this->Algorithm - << ") did not create output for port " << port + vtkErrorMacro("Algorithm " << this->Algorithm->GetObjectDescription() + << " did not create output for port " << port << " when asked by REQUEST_DATA_OBJECT and does not" << " specify a concrete DATA_TYPE_NAME."); return 0; @@ -627,8 +626,8 @@ int vtkDemandDrivenPipeline::CheckDataObject(int port, vtkInformationVector* out { // The algorithm did not specify its output data type and no // object exists. - vtkErrorMacro("Algorithm " << this->Algorithm->GetClassName() << "(" << this->Algorithm - << ") did not create output for port " << port + vtkErrorMacro("Algorithm " << this->Algorithm->GetObjectDescription() + << " did not create output for port " << port << " when asked by REQUEST_DATA_OBJECT and does not" << " specify any DATA_TYPE_NAME."); return 0; @@ -663,8 +662,8 @@ int vtkDemandDrivenPipeline::InputCountIsValid(int port, vtkInformationVector** // If the input port is optional, there may be less than one connection. if (!this->InputIsOptional(port) && (connections < 1)) { - vtkErrorMacro("Input port " << port << " of algorithm " << this->Algorithm->GetClassName() - << "(" << this->Algorithm << ") has " << connections + vtkErrorMacro("Input port " << port << " of algorithm " + << this->Algorithm->GetObjectDescription() << " has " << connections << " connections but is not optional."); return 0; } @@ -672,8 +671,8 @@ int vtkDemandDrivenPipeline::InputCountIsValid(int port, vtkInformationVector** // If the input port is repeatable, there may be more than one connection. if (!this->InputIsRepeatable(port) && (connections > 1)) { - vtkErrorMacro("Input port " << port << " of algorithm " << this->Algorithm->GetClassName() - << "(" << this->Algorithm << ") has " << connections + vtkErrorMacro("Input port " << port << " of algorithm " + << this->Algorithm->GetObjectDescription() << " has " << connections << " connections but is not repeatable."); return 0; } @@ -733,7 +732,7 @@ int vtkDemandDrivenPipeline::InputTypeIsValid(int port, int index, vtkInformatio { vtkErrorMacro("Input for connection index " << index << " on input port index " << port << " for algorithm " - << this->Algorithm->GetClassName() << "(" << this->Algorithm << ") is nullptr, but a " + << this->Algorithm->GetObjectDescription() << " is nullptr, but a " << info->Get(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), 0) << " is required."); return 0; } @@ -755,9 +754,8 @@ int vtkDemandDrivenPipeline::InputTypeIsValid(int port, int index, vtkInformatio { vtkErrorMacro("Input for connection index " << index << " on input port index " << port << " for algorithm " - << this->Algorithm->GetClassName() << "(" << this->Algorithm << ") is of type " - << input->GetClassName() << ", but a " - << info->Get(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), 0) << " is required."); + << this->Algorithm->GetObjectDescription() << " is of type " << input->GetClassName() + << ", but a " << info->Get(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), 0) << " is required."); return 0; } } diff --git a/Common/ExecutionModel/vtkExecutive.cxx b/Common/ExecutionModel/vtkExecutive.cxx index a9ae7c96f91..40d809ea516 100644 --- a/Common/ExecutionModel/vtkExecutive.cxx +++ b/Common/ExecutionModel/vtkExecutive.cxx @@ -259,9 +259,9 @@ vtkExecutive* vtkExecutive::GetInputExecutive(int port, int index) if (index < 0 || index >= this->GetNumberOfInputConnections(port)) { vtkErrorMacro("Attempt to get executive for connection index " - << index << " on input port " << port << " of algorithm " << this->Algorithm->GetClassName() - << "(" << this->Algorithm << "), which has " << this->GetNumberOfInputConnections(port) - << " connections."); + << index << " on input port " << port << " of algorithm " + << this->Algorithm->GetObjectDescription() << ", which has " + << this->GetNumberOfInputConnections(port) << " connections."); return nullptr; } if (vtkAlgorithmOutput* input = this->Algorithm->GetInputConnection(port, index)) @@ -350,9 +350,9 @@ int vtkExecutive::InputPortIndexInRange(int port, const char* action) if (port < 0 || port >= this->Algorithm->GetNumberOfInputPorts()) { vtkErrorMacro("Attempt to " << (action ? action : "access") << " input port index " << port - << " for algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << "), which has " - << this->Algorithm->GetNumberOfInputPorts() << " input ports."); + << " for algorithm " << this->Algorithm->GetObjectDescription() + << ", which has " << this->Algorithm->GetNumberOfInputPorts() + << " input ports."); return 0; } return 1; @@ -373,9 +373,9 @@ int vtkExecutive::OutputPortIndexInRange(int port, const char* action) if (port < 0 || port >= this->Algorithm->GetNumberOfOutputPorts()) { vtkErrorMacro("Attempt to " << (action ? action : "access") << " output port index " << port - << " for algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << "), which has " - << this->Algorithm->GetNumberOfOutputPorts() << " output ports."); + << " for algorithm " << this->Algorithm->GetObjectDescription() + << ", which has " << this->Algorithm->GetNumberOfOutputPorts() + << " output ports."); return 0; } return 1; @@ -737,8 +737,8 @@ int vtkExecutive::CallAlgorithm(vtkInformation* request, int direction, // If the algorithm failed report it now. if (!result) { - vtkErrorMacro("Algorithm " << this->Algorithm->GetClassName() << "(" << this->Algorithm - << ") returned failure for request: " << *request); + vtkErrorMacro("Algorithm " << this->Algorithm->GetObjectDescription() + << " returned failure for request: " << *request); } return result; @@ -756,8 +756,7 @@ int vtkExecutive::CheckAlgorithm(const char* method, vtkInformation* request) vtkErrorMacro(<< method << " invoked during another request. " "Returning failure to algorithm " - << this->Algorithm->GetClassName() << "(" << this->Algorithm - << ") for the recursive request:\n" + << this->Algorithm->GetObjectDescription() << " for the recursive request:\n" << rqmsg.str().c_str()); } else @@ -765,7 +764,7 @@ int vtkExecutive::CheckAlgorithm(const char* method, vtkInformation* request) vtkErrorMacro(<< method << " invoked during another request. " "Returning failure to algorithm " - << this->Algorithm->GetClassName() << "(" << this->Algorithm << ")."); + << this->Algorithm->GetObjectDescription() << "."); } // Tests should fail when this happens because there is a bug in diff --git a/Common/ExecutionModel/vtkStreamingDemandDrivenPipeline.cxx b/Common/ExecutionModel/vtkStreamingDemandDrivenPipeline.cxx index ccdd85e4ce2..cfc655c3919 100644 --- a/Common/ExecutionModel/vtkStreamingDemandDrivenPipeline.cxx +++ b/Common/ExecutionModel/vtkStreamingDemandDrivenPipeline.cxx @@ -632,8 +632,8 @@ void vtkStreamingDemandDrivenPipeline ::CopyDefaultInformation(vtkInformation* r if (!inData) { vtkErrorMacro("Cannot copy default update request from output port " - << outputPort << " on algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << ") to input connection " << j << " on input port " << i + << outputPort << " on algorithm " << this->Algorithm->GetObjectDescription() + << " to input connection " << j << " on input port " << i << " because there is no data object."); continue; } @@ -816,16 +816,14 @@ int vtkStreamingDemandDrivenPipeline ::VerifyOutputInformation( { vtkErrorMacro("No update piece number has been set in the " "information for output port " - << outputPort << " on algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << ")."); + << outputPort << " on algorithm " << this->Algorithm->GetObjectDescription() << "."); return 0; } if (!outInfo->Has(UPDATE_NUMBER_OF_PIECES())) { vtkErrorMacro("No update number of pieces has been set in the " "information for output port " - << outputPort << " on algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << ")."); + << outputPort << " on algorithm " << this->Algorithm->GetObjectDescription() << "."); return 0; } if (!outInfo->Has(UPDATE_NUMBER_OF_GHOST_LEVELS())) @@ -842,16 +840,14 @@ int vtkStreamingDemandDrivenPipeline ::VerifyOutputInformation( { vtkErrorMacro("No whole extent has been set in the " "information for output port " - << outputPort << " on algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << ")."); + << outputPort << " on algorithm " << this->Algorithm->GetObjectDescription() << "."); return 0; } if (!outInfo->Has(UPDATE_EXTENT())) { vtkErrorMacro("No update extent has been set in the " "information for output port " - << outputPort << " on algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << ")."); + << outputPort << " on algorithm " << this->Algorithm->GetObjectDescription() << "."); return 0; } // Make sure the update request is inside the whole extent. @@ -870,12 +866,12 @@ int vtkStreamingDemandDrivenPipeline ::VerifyOutputInformation( // Update extent is outside the whole extent and is not empty. vtkErrorMacro("The update extent specified in the " "information for output port " - << outputPort << " on algorithm " << this->Algorithm->GetClassName() << "(" - << this->Algorithm << ") is " << updateExtent[0] << " " << updateExtent[1] << " " - << updateExtent[2] << " " << updateExtent[3] << " " << updateExtent[4] << " " - << updateExtent[5] << ", which is outside the whole extent " << wholeExtent[0] << " " - << wholeExtent[1] << " " << wholeExtent[2] << " " << wholeExtent[3] << " " - << wholeExtent[4] << " " << wholeExtent[5] << "."); + << outputPort << " on algorithm " << this->Algorithm->GetObjectDescription() << " is " + << updateExtent[0] << " " << updateExtent[1] << " " << updateExtent[2] << " " + << updateExtent[3] << " " << updateExtent[4] << " " << updateExtent[5] + << ", which is outside the whole extent " << wholeExtent[0] << " " << wholeExtent[1] + << " " << wholeExtent[2] << " " << wholeExtent[3] << " " << wholeExtent[4] << " " + << wholeExtent[5] << "."); return 0; } } diff --git a/Common/ExecutionModel/vtkThreadedCompositeDataPipeline.cxx b/Common/ExecutionModel/vtkThreadedCompositeDataPipeline.cxx index 54a1f4f4c1d..8b2da19258b 100644 --- a/Common/ExecutionModel/vtkThreadedCompositeDataPipeline.cxx +++ b/Common/ExecutionModel/vtkThreadedCompositeDataPipeline.cxx @@ -281,8 +281,8 @@ int vtkThreadedCompositeDataPipeline::CallAlgorithm(vtkInformation* request, int // If the algorithm failed report it now. if (!result) { - vtkErrorMacro("Algorithm " << this->Algorithm->GetClassName() << "(" << this->Algorithm - << ") returned failure for request: " << *request); + vtkErrorMacro("Algorithm " << this->Algorithm->GetObjectDescription() + << " returned failure for request: " << *request); } return result; diff --git a/Documentation/release/dev/objectname.md b/Documentation/release/dev/objectname.md new file mode 100644 index 00000000000..43b5ba406fb --- /dev/null +++ b/Documentation/release/dev/objectname.md @@ -0,0 +1,4 @@ +Objects can now be assigned an object name which appears in error and warning +messages and in Print output. Changing the object name does not change the +object's MTime and does not invoke a ModifiedEvent. The object name is not +copied by ShallowCopy and DeepCopy implementations. -- GitLab