[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