diff --git a/Filters/HyperTree/vtkHyperTreeGridGeometry.cxx b/Filters/HyperTree/vtkHyperTreeGridGeometry.cxx
index 18da341f24167f8bd17b7477cb72a52d081bd3cc..0a60526b67b2c08acbbd053e1e0689ec40f35360 100644
--- a/Filters/HyperTree/vtkHyperTreeGridGeometry.cxx
+++ b/Filters/HyperTree/vtkHyperTreeGridGeometry.cxx
@@ -43,6 +43,23 @@
 #include <set>
 #include <vector>
 
+namespace
+{
+
+bool PassCellId(vtkDataArray* cellIds, vtkIdType inId, vtkIdType outId)
+{
+  auto typedCellIds = vtkIdTypeArray::SafeDownCast(cellIds);
+  if (!typedCellIds)
+  {
+    vtkErrorWithObjectMacro(nullptr, "Pass cell ids array has wrong type.");
+    return false;
+  }
+  typedCellIds->InsertValue(outId, inId);
+  return true;
+}
+
+}
+
 VTK_ABI_NAMESPACE_BEGIN
 static constexpr unsigned int VonNeumannCursors3D[] = { 0, 1, 2, 4, 5, 6 };
 static constexpr unsigned int VonNeumannOrientations3D[] = { 2, 1, 0, 0, 1, 2 };
@@ -292,6 +309,14 @@ int vtkHyperTreeGridGeometry::ProcessTrees(vtkHyperTreeGrid* input, vtkDataObjec
   this->OutData = output->GetCellData();
   this->OutData->CopyAllocate(this->InData);
 
+  if (this->PassThroughCellIds)
+  {
+    vtkNew<vtkIdTypeArray> originalCellIds;
+    originalCellIds->SetName(this->OriginalCellIdArrayName.c_str());
+    originalCellIds->SetNumberOfComponents(1);
+    this->OutData->AddArray(originalCellIds);
+  }
+
   // Retrieve material mask
   this->Mask = input->HasMask() ? input->GetMask() : nullptr;
 
@@ -495,6 +520,10 @@ void vtkHyperTreeGridGeometry::ProcessLeaf1D(vtkHyperTreeGridNonOrientedGeometry
 
   // Copy edge data from that of the cell from which it comes
   this->OutData->CopyData(this->InData, inId, outId);
+  if (this->PassThroughCellIds)
+  {
+    ::PassCellId(this->OutData->GetArray(this->OriginalCellIdArrayName.c_str()), inId, outId);
+  }
 }
 
 //------------------------------------------------------------------------------
@@ -797,6 +826,10 @@ void vtkHyperTreeGridGeometry::ProcessLeaf3D(
 
       // Copy face data from that of the cell from which it comes
       this->OutData->CopyData(this->InData, inId, outId);
+      if (this->PassThroughCellIds)
+      {
+        ::PassCellId(this->OutData->GetArray(this->OriginalCellIdArrayName.c_str()), inId, outId);
+      }
     } // if ( nA > 0 )
 
     // Create face B when its vertices are present
@@ -840,6 +873,10 @@ void vtkHyperTreeGridGeometry::ProcessLeaf3D(
 
       // Copy face data from that of the cell from which it comes
       this->OutData->CopyData(this->InData, inId, outId);
+      if (this->PassThroughCellIds)
+      {
+        ::PassCellId(this->OutData->GetArray(this->OriginalCellIdArrayName.c_str()), inId, outId);
+      }
     } // if ( nB > 0 )
   }   // if ( this->HasInterface )
 }
@@ -942,6 +979,10 @@ void vtkHyperTreeGridGeometry::AddFace(vtkIdType useId, const double* origin, co
 
   // Copy face data from that of the cell from which it comes
   this->OutData->CopyData(this->InData, useId, outId);
+  if (this->PassThroughCellIds)
+  {
+    ::PassCellId(this->OutData->GetArray(this->OriginalCellIdArrayName.c_str()), useId, outId);
+  }
 }
 //------------------------------------------------------------------------------
 void vtkHyperTreeGridGeometry::AddFace2(vtkIdType inId, vtkIdType useId, const double* origin,
@@ -1273,6 +1314,10 @@ void vtkHyperTreeGridGeometry::AddFace2(vtkIdType inId, vtkIdType useId, const d
 
     // Copy face data from that of the cell from which it comes
     this->OutData->CopyData(this->InData, useId, outId);
+    if (this->PassThroughCellIds)
+    {
+      ::PassCellId(this->OutData->GetArray(this->OriginalCellIdArrayName.c_str()), inId, outId);
+    }
   } // if ( create )
 }
 VTK_ABI_NAMESPACE_END
diff --git a/Filters/HyperTree/vtkHyperTreeGridGeometry.h b/Filters/HyperTree/vtkHyperTreeGridGeometry.h
index 89f6242b408f4015bd3a8654c0a5e798aa4ce3d2..698616527cca3130ec3f3fd55d0f83509437c162 100644
--- a/Filters/HyperTree/vtkHyperTreeGridGeometry.h
+++ b/Filters/HyperTree/vtkHyperTreeGridGeometry.h
@@ -64,6 +64,32 @@ public:
   vtkGetMacro(Merging, bool);
   ///@}
 
+  //@{
+  /**
+   * Set/Get for the PassThroughCellIds boolean.
+   *
+   * When set to true this boolean ensures an array named with whatever is
+   * in `OriginalCellIdArrayName` gets created in the output holding the
+   * original cell ids
+   *
+   * default is false
+   */
+  vtkSetMacro(PassThroughCellIds, bool);
+  vtkGetMacro(PassThroughCellIds, bool);
+  vtkBooleanMacro(PassThroughCellIds, bool);
+
+  /**
+   * Set/Get the OriginalCellIdArrayName string.
+   *
+   * When PassThroughCellIds is set to true, the name of the generated
+   * array is whatever is set in this variable.
+   *
+   * default to vtkOriginalCellIds
+   */
+  vtkSetMacro(OriginalCellIdArrayName, std::string);
+  vtkGetMacro(OriginalCellIdArrayName, std::string);
+  //@}
+
 protected:
   vtkHyperTreeGridGeometry();
   ~vtkHyperTreeGridGeometry() override;
@@ -143,6 +169,18 @@ protected:
    */
   vtkCellArray* Cells;
 
+  /**
+   * Boolean for passing cell ids to poly data
+   *
+   * default is false
+   */
+  bool PassThroughCellIds = false;
+
+  /**
+   * Name of the array holding original cell ids in output if PassThroughCellIds is true
+   */
+  std::string OriginalCellIdArrayName = "vtkOriginalCellIds";
+
   /**
    *JB Un locator est utilise afin de produire un maillage avec moins
    *JB de points. Le gain en 3D est de l'ordre d'un facteur 4 !