[vtkusers] vtkHyperOctree DeepCopy seems to actually be shallow

Trevor Irons trevorirons at gmail.com
Tue Jan 15 18:26:04 EST 2013


Sorry for the multiple posts but I think I found the underlying problem,
but have no idea how to fix it. In vtkHyperOctree.cxx : 1379

//-----------------------------------------------------------------------------
// Description:
// Shallow and Deep copy.
void vtkHyperOctree::ShallowCopy(vtkDataObject *src)
{
  assert("src_same_type" && vtkHyperOctree::SafeDownCast(src)!=0);
  this->Superclass::ShallowCopy(src);
  this->CopyStructure(vtkHyperOctree::SafeDownCast(src));
}

//-----------------------------------------------------------------------------
void vtkHyperOctree::DeepCopy(vtkDataObject *src)
{
  assert("src_same_type" && vtkHyperOctree::SafeDownCast(src)!=0);
  this->Superclass::DeepCopy(src);
  this->CopyStructure(vtkHyperOctree::SafeDownCast(src));
}

So both Shallow and Deep Copy call CopyStructure, which contains the line
this->CellTree=ho->CellTree;

Which, clearly would cause this problem.

I Generated a little better test program that requires no recompilation of
VTK, and clearly shows the behaviour.

#include <iostream>
#include "vtkHyperOctree.h"
#include "vtkHyperOctreeCursor.h"
using namespace std;
int main() {
    vtkHyperOctree* Octree1 = vtkHyperOctree::New();
        Octree1->SetDimension(3);
        Octree1->SetOrigin(0,0,0);

    cout << "Octree1 GetNum Leaves "<< Octree1->GetNumberOfLeaves() <<
std::endl;

    vtkHyperOctree* Octree2 = vtkHyperOctree::New();
        Octree1->SetDimension(3);
        Octree1->SetOrigin(0,0,0);
    cout  << "Octree2 Num Leaves " << Octree2->GetNumberOfLeaves() <<
std::endl;

    Octree2->DeepCopy(Octree1);

    // Now modify one of them
    vtkHyperOctreeCursor* Cursor = Octree1->NewCellCursor();
        Cursor->ToRoot();
        Octree1->SubdivideLeaf(Cursor);

    cout << "After Subdivide Octree1 GetNum Leaves = " <<
Octree1->GetNumberOfLeaves() << std::endl;
    cout << "Octree2 Num Leaves (expect unchanged) = " <<
Octree2->GetNumberOfLeaves() << std::endl;
}

Thanks again.

On 15 January 2013 16:00, Trevor Irons <trevorirons at gmail.com> wrote:

> I went ahead and made a minimal test.
>
> #include <iostream>
> #include "vtkHyperOctree.h"
> using namespace std;
> int main() {
>     vtkHyperOctree* Octree1 = vtkHyperOctree::New();
>     vtkHyperOctree* Octree2 = vtkHyperOctree::New();
>     Octree2->DeepCopy(Octree1);
>     cout << *Octree1 << std::endl;
>     cout << *Octree2 << std::endl;
> }
>
> This will require adding the line (or something similar) to
> vtkHyperOctree.cxx near line 112 in the PrintSelf method.
>
>
>   os << indent << "CellTree Ptr " << this->CellTree << endl;
>
> When I ran this I got (for example)
>
> // From Octree1
> ... normal stuff...
> CellTree Ptr 0x219f350
>
> // From Octree2
> ... stuff ...
> CellTree Ptr 0x219f350
>
>
> Again, I was not expecting this, because now if I modify Octree1 it also
> modified Octree2. Which is not desired.
>
> -- Trevor
>
>
> On 15 January 2013 15:44, Trevor Irons <trevorirons at gmail.com> wrote:
>
>> Hello. I am having a problem with the vtkHyperOctree->DeepCopy method.
>> The underlying CellTree is being shallow copied.
>>
>> I made the following modification to vtkHyperOctree.cxx:112
>>
>>
>> //-----------------------------------------------------------------------------
>> // because the PrintSelf test is not smart, PrintSelf has to be here.
>> void vtkHyperOctree::PrintSelf(ostream& os, vtkIndent indent)
>> {
>>   this->Superclass::PrintSelf(os,indent);
>>
>>   os << indent << "Dimension: "<<this->Dimension<<endl;
>>   os << indent << "Size: "<<this->Size[0]<<","<<this->Size[1]<<",";
>>   os <<this->Size[2]<<endl;
>>   os << indent << "origin: "<<this->Origin[0]<<","<<this->Origin[1]<<",";
>>   os <<this->Origin[2]<<endl;
>>
>>   os << indent << "DualGridFlag: " << this->DualGridFlag << endl;
>>   os << indent << "CellTree Ptr " << this->CellTree << endl;  // stream
>> pointer address
>>   //this->CellTree->PrintSelf(os,indent);
>> }
>>
>> Just to check the address of the underlying tree. Then in a piece of
>> (c++) code
>>
>> vtkHyperOctreeSampleFunction* OctSamp2 =
>> vtkHyperOctreeSampleFunction::New();
>> vtkHyperOctree* Octree = vtkHyperOctree::New();
>> // Do the sampling
>> this->Octree->DeepCopy(OctSamp2->GetOutput())
>> std::cout << *OctSamp2->GetOutput() << std::endl;
>> std::cout << *Octree << std::endl;
>>
>> And the two pointer addresses were the same.
>>
>> OctSamp2-> GetOutput()  ->>>>>   CellTree Ptr 0x237fcf0
>> Octree -                           ->>>>>   CellTree Ptr 0x237fcf0
>>
>> Which I did not expect, and is causing errors in  my application. Is
>> there a way to get a true deep copy?
>>
>> If this is indeed an error I can generate a test file exhibiting the
>> problem. But my method of checking involved mucking with the vtk source
>> file.
>>
>> Thanks for any help or input.
>>
>> -- Trevor
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20130115/ba3dbd82/attachment.htm>


More information about the vtkusers mailing list