[vtk-developers] vtkLODProp3D and vtkProp3D:SetUserTransform ? (+ GetActors bug ?)

Lisa Sobierajski Avila lisa.avila at kitware.com
Mon Jul 17 11:25:09 EDT 2000


Hello Sebastien,

At 08:16 PM 7/16/00, Sebastien BARRE wrote:
>I was wondering if the vtkLODProp3D might be seen as a kind of assembly ?

Not really an assembly - it is a collection of props/mappers/properties 
that all represent the same thing with only one being chosen for a render.

>If it's the case, wouldn't it be logical that, being a subclass of 
>vtkProp3D, a vtkLODProp3D should propage the UserTransform as an assembly 
>does ? Modifying the UserTransform would automatically modify the aspect 
>of the objects in the LODProp3D, as it is implemented for an assembly (in 
>the current CVS, doing so on the LODProp3D does not affect anything).

vtkLODProp3D was written before UserTransform existed. Here is how 
vtkLODProp3D works wrt matrices:

A UserMatrix is created for each actor/volume when it is created. It is 
initialized to the current matrix of the LODProp3D, although I am not sure 
that is really necessary.

During a render, the current matrix of the LODProp3D is pushed down onto 
the selected LOD:

   // Push the matrix down into the selected LOD
   vtkProp3D *p = this->LODs[this->SelectedLODIndex].Prop3D;
   if ( p->GetMTime() < this->GetMTime() )
     {
     this->GetMatrix( p->GetUserMatrix() );
     }


>I know that I might use the UserMatrix, the I found the UserTransform more 
>powerful most of the time.

When you call this->GetMatrix() does this include the transform's matrix as 
well?

>Here is the beginning of the implementation :
>
>// The real method for adding an actor LOD.
>int vtkLODProp3D::AddLOD( vtkMapper *m, vtkProperty *p,
>                           vtkTexture *t, float time )
>{
>   int          index;
>   vtkActor     *actor;
>   vtkMatrix4x4 *matrix;
>
>   index = this->GetNextEntryIndex();
>
>   actor = vtkActor::New();
>   matrix = vtkMatrix4x4::New();
>   this->GetMatrix(matrix);
>   actor->SetUserMatrix(matrix);
>   matrix->Delete();
>   actor->SetMapper( m );
>
>The UserMatrix is shared I guess, but it's missing the UserTransform, am I 
>right ? Something like :

No - not shared. It is just that each actor/volume needs a UserMatrix to be 
allocated for future use. It is initialized to the current value of the 
LODProp3D->GetMatrix() value.

>actor->SetUserTransform(this->GetUserTransform());

No - that would actually share them, which would only work if the user 
never changed the transform once LODs were added. (I mean change as in set 
it to a new one, not modify the current one) If you add this line to the 
place in the render where the matrices are synchronized, that would work I 
think.

>Am I missing a point somewhere ?
>
>For the moment, I could correct this by adding some mapper/property 
>combination to the LODProp3D, then browse the collection of prop3D that 
>were internally created by the LODProp3D, and set their UserTransform.
>Sadly, there is no way to get this collection of prop3D. The 
>LODProp3D::GetActors is documented as :
>
>"For some exporters and other other operations we must be able to collect 
>all the actors or volumes. These methods are used in that process."
>
>But this is not what happens. Here is the beginning of the code :
>
>void vtkLODProp3D::GetActors(vtkPropCollection *ac)
>{
>   vtkDebugMacro(<< "vtkLODProp3D::GetActors");
>   int index = 0;
>   if (this->AutomaticPickLODSelection)
>     {
>     if ( this->SelectedLODIndex < 0 ||
>         this->SelectedLODIndex >= this->NumberOfEntries )
>       {
>       index = this->GetAutomaticPickPropIndex();
>       }
>     else
>       {
>       index = this->SelectedLODIndex;
>       }
>     if (! this->LODs[index].Prop3D->IsA("vtkVolume"))
>       {
>       ac->AddItem(this->LODs[index].Prop3D);
>       }
>     }
>
>=> I might be wrong, but GetActors() seems to have been written so that :
>         a) only the prop that shall be used for the given estimated time 
> will be returned
>         b) NO vtkVolume !

GetActors() is intended to return only subclasses of vtkActor - which 
vtkVolume is not. There is a corresponding GetVolumes() method which does 
not seem to be implemented in vtkLODProp3D (but should be). These methods 
only return the currently selected LOD since this is the expected behavior 
- otherwise you would write out every LOD into some exported file (which 
would all be rendered on top of each other when you import it) and you 
might pick LODs that you are not currently viewing.

>My question : is that behaviour OK ? I guess LODProp3D was mainly 
>introduced to handle volume rendering issues, therefore is there any 
>rational for b) ? Should we add a method to get real access to every 
>prop3D that have been created internally ?

I specifically avoided adding any access methods to the internally created 
props so that users could not modify them in any way.

vtkLODProp3D was introduced to handle situations where you cannot simply 
have multiple vtkMappers for the LODs - which include volume rendering 
(where you don't have a vtkMapper, and maybe you want to mix both 
vtkMappers with vtkVolumeMappers to solve your problem) and other 
applications where you may want a LOD to have a different property 
(wireframe vs. surface, shaded vs. unshaded etc).


Lisa







More information about the vtk-developers mailing list