Commit 7b3f33ab authored by Will Schroeder's avatar Will Schroeder
Browse files

ENH: Fixed up assembly transformations and interaction with graphics objects

parent c2773d7a
......@@ -61,6 +61,7 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#include "vtkTexture.hh"
#include "vtkMapper.hh"
#include "vtkTransform.hh"
#include "vtkActorCollection.hh"
class vtkRenderer;
class vtkActorDevice;
......@@ -159,10 +160,20 @@ class vtkActor : public vtkObject
vtkGetMacro(Dragable,int);
vtkBooleanMacro(Dragable,int);
// Description:
// Subclasses of vtkActor can be composed of one or more parts. A part is an
// actor or subclass of actor(e.g., assembly). To support this, we return a
// list of all parts that compose this actor. (This differs from the
// vtkAssembly::GetParts() method, which returns a list of the parts that
// form the first level of a hierarchy of actors.)
virtual vtkActorCollection *GetComposingParts();
virtual void AddComposingParts(vtkActorCollection &);
vtkMatrix4x4& GetMatrix();
virtual void GetMatrix(vtkMatrix4x4& m);
float *GetBounds();
virtual float *GetBounds();
void GetBounds(float bounds[6]);
float *GetCenter();
float *GetXRange();
float *GetYRange();
......@@ -196,6 +207,12 @@ protected:
int SelfCreatedProperty;
float Center[3];
vtkActorDevice *Device;
vtkActorCollection ComposingParts;
};
inline vtkActorCollection *vtkActor::GetComposingParts()
{
return &(this->ComposingParts);
};
#endif
......
......@@ -51,7 +51,7 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#define __vtkActorC_hh
#include "vtkCollection.hh"
#include "vtkActor.hh"
class vtkActor;
class vtkActorCollection : public vtkCollection
{
......
......@@ -76,7 +76,6 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#define __vtkAssembly_h
#include "vtkActor.hh"
#include "vtkActorCollection.hh"
class vtkAssembly : public vtkActor
{
......@@ -113,12 +112,16 @@ public:
virtual void ApplyTransformation();
virtual void ApplyProperties();
vtkActorCollection *GetComposingParts();
float *GetBounds();
protected:
vtkActorCollection Parts;
int ApplyTransform;
int ApplyProperty;
vtkTimeStamp RenderTime;
void AddComposingParts(vtkActorCollection &);
};
// Description:
......
......@@ -58,7 +58,7 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#include "vtkMatrix4x4.hh"
#include "vtkLightCollection.hh"
#include "vtkCamera.hh"
#include "vtkActorCollection.hh"
#include "vtkActor.hh"
#include "vtkGeometryPrimitive.hh"
class vtkRenderWindow;
......
......@@ -76,8 +76,14 @@ vtkActor::vtkActor()
this->Pickable = 1;
this->Dragable = 1;
this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = -1.0;
this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1.0;
this->Center[0] = this->Center[1] = this->Center[2] = 0.0;
this->SelfCreatedProperty = 0;
this->Device = NULL;
this->ComposingParts.AddItem(this);
}
vtkActor::~vtkActor()
......@@ -303,6 +309,14 @@ vtkMatrix4x4& vtkActor::GetMatrix()
return result;
}
// Description:
// Get the bounds for this Actor as (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax).
void vtkActor::GetBounds(float bounds[6])
{
this->GetBounds();
for (int i=0; i<6; i++) bounds[i] = this->Bounds[i];
}
// Description:
// Get the bounds for this Actor as (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax).
float *vtkActor::GetBounds()
......@@ -331,9 +345,9 @@ float *vtkActor::GetBounds()
bbox[21] = bounds[0]; bbox[22] = bounds[3]; bbox[23] = bounds[4];
// save the old transform
this->GetMatrix(matrix);
this->Transform.Push();
this->Transform.Identity();
this->GetMatrix(matrix);
this->Transform.Concatenate(matrix);
// and transform into actors coordinates
......@@ -353,8 +367,8 @@ float *vtkActor::GetBounds()
this->Transform.Pop();
// now calc the new bounds
this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = 1.0e30;
this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -1.0e30;
this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = VTK_LARGE_FLOAT;
this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -VTK_LARGE_FLOAT;
for (i = 0; i < 8; i++)
{
for (n = 0; n < 3; n++)
......@@ -403,6 +417,11 @@ float *vtkActor::GetZRange()
return &(this->Bounds[4]);
}
void vtkActor::AddComposingParts(vtkActorCollection &parts)
{
parts.AddItem(this);
}
void vtkActor::PrintSelf(ostream& os, vtkIndent indent)
{
vtkObject::PrintSelf(os,indent);
......
......@@ -132,6 +132,54 @@ void vtkAssembly::ApplyProperties()
}
}
vtkActorCollection* vtkAssembly::GetComposingParts()
{
vtkActor *part;
this->ComposingParts.RemoveAllItems();
this->ComposingParts.AddItem(this);
for (this->Parts.InitTraversal(); part = this->Parts.GetNextItem(); )
{
part->AddComposingParts(this->ComposingParts);
}
return vtkActor::GetComposingParts();
}
void vtkAssembly::AddComposingParts(vtkActorCollection &parts)
{
vtkActor *part;
this->ComposingParts.AddItem(this);
for (this->Parts.InitTraversal(); part = this->Parts.GetNextItem(); )
{
part->AddComposingParts(this->ComposingParts);
}
}
// Description:
// Get the bounds for the assembly as (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax). Side
// effect is to update part transformations and properties.
float *vtkAssembly::GetBounds()
{
if ( this->ApplyTransform && this->RenderTime < this->GetMTime() )
{
this->ApplyTransformation();
}
if ( this->ApplyProperty && this->RenderTime < this->Property->GetMTime() )
{
this->ApplyProperties();
}
this->RenderTime.Modified();
//insures things are up to date
return vtkActor::GetBounds();
}
void vtkAssembly::PrintSelf(ostream& os, vtkIndent indent)
{
vtkActor::PrintSelf(os,indent);
......
......@@ -108,8 +108,8 @@ int vtkPicker::Pick(float selectionX, float selectionY, float selectionZ,
vtkRenderer *renderer)
{
int i;
vtkActorCollection *actors;
vtkActor *actor;
vtkActorCollection *actors, *parts;
vtkActor *actor, *part;
vtkCamera *camera;
vtkMapper *mapper;
float p1World[4], p2World[4], p1Mapper[4], p2Mapper[4];
......@@ -122,7 +122,7 @@ int vtkPicker::Pick(float selectionX, float selectionY, float selectionZ,
float *displayCoords, *worldCoords;
float *clipRange;
float ray[3], rayLength;
float transparency;
float opacity;
int visible, pickable;
float windowLowerLeft[4], windowUpperRight[4];
float *bounds, tol;
......@@ -226,55 +226,60 @@ int vtkPicker::Pick(float selectionX, float selectionY, float selectionZ,
actors = renderer->GetActors();
for ( actors->InitTraversal(); actor=actors->GetNextItem(); )
{
visible = actor->GetVisibility();
pickable = actor->GetPickable();
transparency = actor->GetProperty()->GetOpacity();
parts = actor->GetComposingParts();
for ( parts->InitTraversal(); part=parts->GetNextItem(); )
{
visible = part->GetVisibility();
pickable = part->GetPickable();
opacity = part->GetProperty()->GetOpacity();
//
// If actor can be picked, get its composite matrix, invert it, and
// use the inverted matrix to transform the ray points into mapper
// coordinates.
//
if (visible && pickable && transparency != 0.0)
{
this->Transform.SetMatrix(actor->GetMatrix());
this->Transform.Push();
this->Transform.Inverse();
this->Transform.SetPoint(p1World);
this->Transform.GetPoint(p1Mapper);
this->Transform.SetPoint(p2World);
this->Transform.GetPoint(p2Mapper);
for (i=0; i<3; i++)
{
p1Mapper[i] /= p1Mapper[3];
p2Mapper[i] /= p2Mapper[3];
ray[i] = p2Mapper[i] - p1Mapper[i];
}
this->Transform.Pop();
//
// Have the ray endpoints in mapper space, now need to compare this
// with the mapper bounds to see whether intersection is possible.
//
if ( (mapper = actor->GetMapper()) != NULL )
if ( visible && pickable && (opacity != 0.0) )
{
//
// Get the bounding box of the modeller. Note that the tolerance is
// added to the bounding box to make sure things on the edge of the
// bounding box are picked correctly.
//
bounds = mapper->GetBounds();
if ( cell.HitBBox(bounds, (float *)p1Mapper, ray, hitPosition, t) )
this->Transform.SetMatrix(part->GetMatrix());
this->Transform.Push();
this->Transform.Transpose();
this->Transform.Inverse();
this->Transform.SetPoint(p1World);
this->Transform.GetPoint(p1Mapper);
this->Transform.SetPoint(p2World);
this->Transform.GetPoint(p2Mapper);
for (i=0; i<3; i++)
{
picked = 1;
this->IntersectWithLine((float *)p1Mapper, (float *)p2Mapper,tol,actor,mapper);
this->Actors.AddItem(actor);
p1Mapper[i] /= p1Mapper[3];
p2Mapper[i] /= p2Mapper[3];
ray[i] = p2Mapper[i] - p1Mapper[i];
}
}
}
}
this->Transform.Pop();
//
// Have the ray endpoints in mapper space, now need to compare this
// with the mapper bounds to see whether intersection is possible.
//
if ( (mapper = part->GetMapper()) != NULL )
{
//
// Get the bounding box of the modeller. Note that the tolerance is
// added to the bounding box to make sure things on the edge of the
// bounding box are picked correctly.
//
bounds = mapper->GetBounds();
if ( cell.HitBBox(bounds, (float *)p1Mapper, ray, hitPosition, t) )
{
picked = 1;
this->IntersectWithLine((float *)p1Mapper, (float *)p2Mapper,tol,part,mapper);
this->Actors.AddItem(part);
}
}
}//if visible and pickable
}//for all parts
}//for all actors
return picked;
}
......
......@@ -226,7 +226,8 @@ void vtkRenderer::DoActors()
void vtkRenderer::ResetCamera()
{
vtkVolume *aVolume;
vtkActor *anActor;
vtkActorCollection *pc;
vtkActor *anActor, *aPart;
float *bounds;
float allBounds[6];
int nothingVisible=1;
......@@ -234,22 +235,25 @@ void vtkRenderer::ResetCamera()
allBounds[0] = allBounds[2] = allBounds[4] = VTK_LARGE_FLOAT;
allBounds[1] = allBounds[3] = allBounds[5] = -VTK_LARGE_FLOAT;
// loop through actors
for (this->Actors.InitTraversal();
(anActor = this->Actors.GetNextItem()); )
// loop through actors (and their parts)
for (this->Actors.InitTraversal(); (anActor = this->Actors.GetNextItem());)
{
// if it's invisible, we can skip the rest
if ( anActor->GetVisibility() )
pc = anActor->GetComposingParts();
for ( pc->InitTraversal(); (aPart = pc->GetNextItem()); )
{
nothingVisible = 0;
bounds = anActor->GetBounds();
if (bounds[0] < allBounds[0]) allBounds[0] = bounds[0];
if (bounds[1] > allBounds[1]) allBounds[1] = bounds[1];
if (bounds[2] < allBounds[2]) allBounds[2] = bounds[2];
if (bounds[3] > allBounds[3]) allBounds[3] = bounds[3];
if (bounds[4] < allBounds[4]) allBounds[4] = bounds[4];
if (bounds[5] > allBounds[5]) allBounds[5] = bounds[5];
// if it's invisible, or has no geometry, we can skip the rest
if ( aPart->GetVisibility() && aPart->GetMapper() != NULL )
{
nothingVisible = 0;
bounds = aPart->GetBounds();
if (bounds[0] < allBounds[0]) allBounds[0] = bounds[0];
if (bounds[1] > allBounds[1]) allBounds[1] = bounds[1];
if (bounds[2] < allBounds[2]) allBounds[2] = bounds[2];
if (bounds[3] > allBounds[3]) allBounds[3] = bounds[3];
if (bounds[4] < allBounds[4]) allBounds[4] = bounds[4];
if (bounds[5] > allBounds[5]) allBounds[5] = bounds[5];
}
}
}
......
......@@ -411,15 +411,19 @@ void vtkXRenderWindowInteractorCallback(Widget w,XtPointer client_data,
case XK_w : //change all actors to wireframe
{
vtkActorCollection *ac;
vtkActor *anActor;
vtkActorCollection *ac, *pc;
vtkActor *anActor, *aPart;
me->FindPokedRenderer(((XKeyEvent*)event)->x,
me->Size[1] - ((XKeyEvent*)event)->y);
ac = me->CurrentRenderer->GetActors();
for (ac->InitTraversal(); (anActor = ac->GetNextItem()); )
{
anActor->GetProperty()->SetWireframe();
pc = anActor->GetComposingParts();
for (pc->InitTraversal(); (aPart = pc->GetNextItem()); )
{
aPart->GetProperty()->SetWireframe();
}
}
me->RenderWindow->Render();
......@@ -428,15 +432,19 @@ void vtkXRenderWindowInteractorCallback(Widget w,XtPointer client_data,
case XK_s : //change all actors to "surface" or solid
{
vtkActorCollection *ac;
vtkActor *anActor;
vtkActorCollection *ac, *pc;
vtkActor *anActor, *aPart;
me->FindPokedRenderer(((XKeyEvent*)event)->x,
me->Size[1] - ((XKeyEvent*)event)->y);
ac = me->CurrentRenderer->GetActors();
for (ac->InitTraversal(); (anActor = ac->GetNextItem()); )
{
anActor->GetProperty()->SetSurface();
pc = anActor->GetComposingParts();
for (pc->InitTraversal(); (aPart = pc->GetNextItem()); )
{
aPart->GetProperty()->SetSurface();
}
}
me->RenderWindow->Render();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment