From e26f19106fb536c34b8d910e75a345f776988361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20P=2E=20P=C3=A9ba=C3=BF?= <philippe.pebay@ng-analytics.com> Date: Thu, 21 Sep 2017 19:42:10 +0200 Subject: [PATCH] Rewrite HTG cell centers filter as a HTG algorithm sub-class The motivation for this refactoring was quite simple: amongst all ancient (but renovated) and new hypetree grid filters, which were part of the recently merged "HyperTreeGrid Version 2" branch, the HTG CellCenters filter stood out as the only one which was not deriving from vtkHyperTreeGridAlgorithm, which had also been reworked entirely for this new version of HTG support. This was because vtkHyperTreeGridCellCenters was, initially, deriving from the vtkCellCenters class in Filters/General. As VTK does not support multiple inheritance, it was left that way but that was not consistent with our overall approach of making all HTG algorithms derive from a single base class, in the double goal of facilitating both the writing of new HTG filters and their maintenance in the long run. The current commit thus provides a re-writing of the HTG cell center creating algorithm as subclass of vtkHyperTreeGridAlgorithm while preserving the outside appearance of a vtkCellCenter-derived filter in its API, specifically by introducing a VertexCells instance variable in order to mimic that which is provided in vtkCellCenters. Note that no new unit tests are provided as part of this commit, for the 4 existing ones for the previous incarnation of the HTG cell center filter are still passing with unchanged results (as they should indeed). --- .../HyperTree/vtkHyperTreeGridCellCenters.cxx | 116 ++++++------------ .../HyperTree/vtkHyperTreeGridCellCenters.h | 46 ++++--- 2 files changed, 66 insertions(+), 96 deletions(-) diff --git a/Filters/HyperTree/vtkHyperTreeGridCellCenters.cxx b/Filters/HyperTree/vtkHyperTreeGridCellCenters.cxx index 46222b5aaeb..2562981f4f6 100644 --- a/Filters/HyperTree/vtkHyperTreeGridCellCenters.cxx +++ b/Filters/HyperTree/vtkHyperTreeGridCellCenters.cxx @@ -16,6 +16,8 @@ #include "vtkBitArray.h" #include "vtkCellArray.h" +#include "vtkCellData.h" +#include "vtkDataSetAttributes.h" #include "vtkHyperTree.h" #include "vtkHyperTreeCursor.h" #include "vtkHyperTreeGrid.h" @@ -25,31 +27,25 @@ #include "vtkObjectFactory.h" #include "vtkPoints.h" #include "vtkPointData.h" +#include "vtkPolyData.h" vtkStandardNewMacro(vtkHyperTreeGridCellCenters); //----------------------------------------------------------------------------- vtkHyperTreeGridCellCenters::vtkHyperTreeGridCellCenters() { - this->Input = nullptr; - this->Output = nullptr; - - this->InData = nullptr; - this->OutData = nullptr; - - this->Points = nullptr; + // Create storage for centers of leaf cells + this->Points = vtkPoints::New(); } //----------------------------------------------------------------------------- vtkHyperTreeGridCellCenters::~vtkHyperTreeGridCellCenters() { -} - -//----------------------------------------------------------------------------- -int vtkHyperTreeGridCellCenters::FillInputPortInformation( int, vtkInformation *info ) -{ - info->Set( vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkHyperTreeGrid" ); - return 1; + if ( this->Points ) + { + this->Points->Delete(); + this->Points = nullptr; + } } //---------------------------------------------------------------------------- @@ -57,26 +53,6 @@ void vtkHyperTreeGridCellCenters::PrintSelf( ostream& os, vtkIndent indent ) { this->Superclass::PrintSelf( os, indent ); - if( this->Input ) - { - os << indent << "Input:\n"; - this->Input->PrintSelf( os, indent.GetNextIndent() ); - } - else - { - os << indent << "Input: ( none )\n"; - } - - if( this->Output ) - { - os << indent << "Output:\n"; - this->Output->PrintSelf( os, indent.GetNextIndent() ); - } - else - { - os << indent << "Output: ( none )\n"; - } - if( this->Points ) { os << indent << "Points:\n"; @@ -89,60 +65,43 @@ void vtkHyperTreeGridCellCenters::PrintSelf( ostream& os, vtkIndent indent ) } //---------------------------------------------------------------------------- -int vtkHyperTreeGridCellCenters::RequestData( vtkInformation*, - vtkInformationVector** inputVector, - vtkInformationVector* outputVector ) +int vtkHyperTreeGridCellCenters::FillOutputPortInformation( int, + vtkInformation* info ) { - // Get the information objects - vtkInformation* inInfo = inputVector[0]->GetInformationObject( 0 ); - vtkInformation* outInfo = outputVector->GetInformationObject( 0 ); - - // Retrieve input and output - this->Input - = vtkHyperTreeGrid::SafeDownCast( inInfo->Get( vtkDataObject::DATA_OBJECT() ) ); - this->Output - = vtkPolyData::SafeDownCast( outInfo->Get( vtkDataObject::DATA_OBJECT() ) ); - - // Initialize output cell data - this->InData = this->Input->GetPointData(); - this->OutData = this->Output->GetPointData(); - this->OutData->CopyAllocate( this->InData ); - - // General cell centers of hyper tree grid - this->ProcessTrees(); - - // Squeeze output data - this->OutData->Squeeze(); - - // Clean up - this->Input = nullptr; - this->Output = nullptr; - this->InData = nullptr; - this->OutData = nullptr; - - this->UpdateProgress ( 1. ); - + info->Set( vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData" ); return 1; } //---------------------------------------------------------------------------- -void vtkHyperTreeGridCellCenters::ProcessTrees() +int vtkHyperTreeGridCellCenters::ProcessTrees( vtkHyperTreeGrid* input, + vtkDataObject* outputDO ) { - // Create storage for corners of leaf cells - this->Points = vtkPoints::New(); + // Downcast output data object to polygonal data set + vtkPolyData* output = vtkPolyData::SafeDownCast( outputDO ); + if ( ! output ) + { + vtkErrorMacro( "Incorrect type of output: " + << outputDO->GetClassName() ); + return 0; + } + + // Initialize output cell data + this->InData = input->GetPointData(); + this->OutData = output->GetPointData(); + this->OutData->CopyAllocate( this->InData ); // Retrieve material mask vtkBitArray* mask - = this->Input->HasMaterialMask() ? this->Input->GetMaterialMask() : 0; + = input->HasMaterialMask() ? input->GetMaterialMask() : nullptr; // Iterate over all hyper trees vtkIdType index; vtkHyperTreeGrid::vtkHyperTreeGridIterator it; - this->Input->InitializeTreeIterator( it ); + input->InitializeTreeIterator( it ); while ( it.GetNextTree( index ) ) { // Initialize new geometric cursor at root of current tree - vtkHyperTreeGridCursor* cursor = this->Input->NewGeometricCursor( index ); + vtkHyperTreeGridCursor* cursor = input->NewGeometricCursor( index ); // Generate leaf cell centers recursively this->RecursivelyProcessTree( cursor, mask ); @@ -152,7 +111,7 @@ void vtkHyperTreeGridCellCenters::ProcessTrees() } // it // Set output geometry and topology if required - this->Output->SetPoints( this->Points ); + output->SetPoints( this->Points ); if ( this->VertexCells ) { vtkIdType np = this->Points->GetNumberOfPoints(); @@ -162,19 +121,20 @@ void vtkHyperTreeGridCellCenters::ProcessTrees() { vertices->InsertNextCell( 1, &i ); } // i - this->Output->SetVerts( vertices ); + output->SetVerts( vertices ); vertices->Delete(); } // this->VertexCells - // Clean up - this->Points->Delete(); - this->Points = nullptr; + return 1; } //---------------------------------------------------------------------------- void vtkHyperTreeGridCellCenters::RecursivelyProcessTree( vtkHyperTreeGridCursor* cursor, vtkBitArray* mask ) { + // Retrieve input grid + vtkHyperTreeGrid* input = cursor->GetGrid(); + // Create cell center if cursor is at leaf if ( cursor->IsLeaf() ) { @@ -203,7 +163,7 @@ void vtkHyperTreeGridCellCenters::RecursivelyProcessTree( vtkHyperTreeGridCursor else { // Cursor is not at leaf, recurse to all children - int numChildren = this->Input->GetNumberOfChildren(); + int numChildren = input->GetNumberOfChildren(); for ( int child = 0; child < numChildren; ++ child ) { // Create child cursor from parent diff --git a/Filters/HyperTree/vtkHyperTreeGridCellCenters.h b/Filters/HyperTree/vtkHyperTreeGridCellCenters.h index b912a064b43..55d4cf11a26 100644 --- a/Filters/HyperTree/vtkHyperTreeGridCellCenters.h +++ b/Filters/HyperTree/vtkHyperTreeGridCellCenters.h @@ -31,11 +31,11 @@ * VertexCells to generate cells. * * @sa - * vtkCellCenters vtkHyperTreeGrid vtkGlyph3D + * vtkCellCenters vtkHyperTreeGrid vtkHyperTreeGridAlgorithm * * @par Thanks: * This class was written by Guenole Harel and Jacques-Bernard Lekien 2014 - * This class was modified by Philippe Pebay, 2016 + * This class was rewritten by Philippe Pebay, NexGen Analytics 2017 * This work was supported by Commissariat a l'Energie Atomique (CEA/DIF) */ @@ -43,48 +43,58 @@ #define vtkHyperTreeGridCellCenters_h #include "vtkFiltersHyperTreeModule.h" // For export macro -#include "vtkCellCenters.h" +#include "vtkHyperTreeGridAlgorithm.h" class vtkBitArray; -class vtkDataSetAttributes; class vtkHyperTreeGrid; class vtkHyperTreeGridCursor; -class vtkPolyData; +class vtkPoints; -class VTKFILTERSHYPERTREE_EXPORT vtkHyperTreeGridCellCenters : public vtkCellCenters +class VTKFILTERSHYPERTREE_EXPORT vtkHyperTreeGridCellCenters : public vtkHyperTreeGridAlgorithm { public: static vtkHyperTreeGridCellCenters* New(); - vtkTypeMacro( vtkHyperTreeGridCellCenters, vtkCellCenters ); + vtkTypeMacro( vtkHyperTreeGridCellCenters, vtkHyperTreeGridAlgorithm ); void PrintSelf( ostream&, vtkIndent ) override; + //@{ + /** + * Enable/disable the generation of vertex cells. The default + * is Off. + */ + vtkSetMacro(VertexCells,int); + vtkGetMacro(VertexCells,int); + vtkBooleanMacro(VertexCells,int); + //@} + protected: vtkHyperTreeGridCellCenters(); ~vtkHyperTreeGridCellCenters() override; - int RequestData( vtkInformation*, vtkInformationVector**, vtkInformationVector* ) override; + /** + * For this algorithm the output is a vtkPolyData instance + */ int FillInputPortInformation( int, vtkInformation* ) override; /** - * Main routine to process individual trees in the grid + * Main routine to generate cell centers */ - virtual void ProcessTrees(); + int ProcessTrees( vtkHyperTreeGrid*, vtkDataObject* ) override; /** * Recursively descend into tree down to leaves */ void RecursivelyProcessTree( vtkHyperTreeGridCursor*, vtkBitArray* ); - vtkHyperTreeGrid* Input; - vtkPolyData* Output; - - vtkDataSetAttributes* InData; - vtkDataSetAttributes* OutData; - + /** + * Storage for points of output unstructured mesh + */ vtkPoints* Points; - vtkPointData* InPointData; - vtkPointData* OutPointData; + /** + * Keep track as to whether vertex cells shall be generated. + */ + int VertexCells; private: vtkHyperTreeGridCellCenters(const vtkHyperTreeGridCellCenters&) = delete; -- GitLab