Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

417 lines
11 KiB

2 years ago
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkInteractorStyleTerrain.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkInteractorStyleTerrain.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkCommand.h"
#include "vtkExtractEdges.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkSphereSource.h"
vtkCxxRevisionMacro(vtkInteractorStyleTerrain, "$Revision: 1.9 $");
vtkStandardNewMacro(vtkInteractorStyleTerrain);
//----------------------------------------------------------------------------
vtkInteractorStyleTerrain::vtkInteractorStyleTerrain()
{
this->LatLongLines = 0;
this->LatLongSphere = NULL;
this->LatLongExtractEdges = NULL;
this->LatLongMapper = NULL;
this->LatLongActor = NULL;
this->MotionFactor = 10.0;
}
//----------------------------------------------------------------------------
vtkInteractorStyleTerrain::~vtkInteractorStyleTerrain()
{
if (this->LatLongSphere != NULL)
{
this->LatLongSphere->Delete();
}
if (this->LatLongMapper != NULL)
{
this->LatLongMapper->Delete();
}
if (this->LatLongActor != NULL)
{
this->LatLongActor->Delete();
}
if (this->LatLongExtractEdges != NULL)
{
this->LatLongExtractEdges->Delete();
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnMouseMove()
{
int x = this->Interactor->GetEventPosition()[0];
int y = this->Interactor->GetEventPosition()[1];
switch (this->State)
{
case VTKIS_ROTATE:
this->FindPokedRenderer(x, y);
this->Rotate();
this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
break;
case VTKIS_PAN:
this->FindPokedRenderer(x, y);
this->Pan();
this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
break;
case VTKIS_DOLLY:
this->FindPokedRenderer(x, y);
this->Dolly();
this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
break;
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnLeftButtonDown ()
{
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1]);
if (this->CurrentRenderer == NULL)
{
return;
}
this->StartRotate();
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnLeftButtonUp ()
{
switch (this->State)
{
case VTKIS_ROTATE:
this->EndRotate();
break;
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnMiddleButtonDown ()
{
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1]);
if (this->CurrentRenderer == NULL)
{
return;
}
this->StartPan();
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnMiddleButtonUp ()
{
switch (this->State)
{
case VTKIS_PAN:
this->EndPan();
break;
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnRightButtonDown ()
{
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1]);
if (this->CurrentRenderer == NULL)
{
return;
}
this->StartDolly();
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnRightButtonUp ()
{
switch (this->State)
{
case VTKIS_DOLLY:
this->EndDolly();
break;
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::Rotate()
{
if (this->CurrentRenderer == NULL)
{
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
int dx = - (rwi->GetEventPosition()[0] - rwi->GetLastEventPosition()[0]);
int dy = - (rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1]);
int *size = this->CurrentRenderer->GetRenderWindow()->GetSize();
double a = (double)dx / (double)size[0] * (double)180.0;
double e = (double)dy / (double)size[1] * (double)180.0;
if (rwi->GetShiftKey())
{
if (fabs((double)dx) >= fabs((double)dy))
{
e = (double)0.0;
}
else
{
a = (double)0.0;
}
}
// Move the camera.
// Make sure that we don't hit the north pole singularity.
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
camera->Azimuth(a);
double dop[3], vup[3];
camera->GetDirectionOfProjection(dop);
vtkMath::Normalize(dop);
camera->GetViewUp(vup);
vtkMath::Normalize(vup);
double angle =
acos(vtkMath::Dot(dop, vup)) / vtkMath::DoubleDegreesToRadians();
if ((angle + e) > (double)179.0 ||
(angle + e) < (double)1.0)
{
e = (double)0.0;
}
camera->Elevation(e);
if (this->AutoAdjustCameraClippingRange)
{
this->CurrentRenderer->ResetCameraClippingRange();
}
rwi->Render();
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::Pan()
{
if (this->CurrentRenderer == NULL)
{
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
// Get the vector of motion
double fp[3], focalPoint[3], pos[3], v[3], p1[4], p2[4];
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
camera->GetPosition(pos);
camera->GetFocalPoint(fp);
this->ComputeWorldToDisplay(fp[0], fp[1], fp[2],
focalPoint);
this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
(double)rwi->GetEventPosition()[1],
focalPoint[2],
p1);
this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
(double)rwi->GetLastEventPosition()[1],
focalPoint[2],
p2);
for (int i=0; i<3; i++)
{
v[i] = p2[i] - p1[i];
pos[i] += v[i];
fp[i] += v[i];
}
camera->SetPosition(pos);
camera->SetFocalPoint(fp);
if (rwi->GetLightFollowCamera())
{
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
}
rwi->Render();
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::Dolly()
{
if (this->CurrentRenderer == NULL)
{
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
double *center = this->CurrentRenderer->GetCenter();
int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
double zoomFactor = pow((double)1.1, dyf);
if (camera->GetParallelProjection())
{
camera->SetParallelScale(camera->GetParallelScale() / zoomFactor);
}
else
{
camera->Dolly(zoomFactor);
if (this->AutoAdjustCameraClippingRange)
{
this->CurrentRenderer->ResetCameraClippingRange();
}
}
if (rwi->GetLightFollowCamera())
{
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
}
rwi->Render();
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::OnChar()
{
vtkRenderWindowInteractor *rwi = this->Interactor;
switch (rwi->GetKeyCode())
{
case 'l':
this->FindPokedRenderer(rwi->GetEventPosition()[0],
rwi->GetEventPosition()[1]);
this->CreateLatLong();
if (this->LatLongLines)
{
this->LatLongLinesOff();
}
else
{
double bounds[6];
this->CurrentRenderer->ComputeVisiblePropBounds(bounds);
double radius = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
(bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
(bounds[5]-bounds[4])*(bounds[5]-bounds[4])) /2.0;
this->LatLongSphere->SetRadius(radius);
this->LatLongSphere->SetCenter((bounds[0]+bounds[1])/2.0,
(bounds[2]+bounds[3])/2.0,
(bounds[4]+bounds[5])/2.0);
this->LatLongLinesOn();
}
this->SelectRepresentation();
rwi->Render();
break;
default:
this->Superclass::OnChar();
break;
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::CreateLatLong()
{
if (this->LatLongSphere == NULL)
{
this->LatLongSphere = vtkSphereSource::New();
this->LatLongSphere->SetPhiResolution(13);
this->LatLongSphere->SetThetaResolution(25);
this->LatLongSphere->LatLongTessellationOn();
}
if (this->LatLongExtractEdges == NULL)
{
this->LatLongExtractEdges = vtkExtractEdges::New();
this->LatLongExtractEdges->SetInput(this->LatLongSphere->GetOutput());
}
if (this->LatLongMapper == NULL)
{
this->LatLongMapper = vtkPolyDataMapper::New();
this->LatLongMapper->SetInput(this->LatLongExtractEdges->GetOutput());
}
if (this->LatLongActor == NULL)
{
this->LatLongActor = vtkActor::New();
this->LatLongActor->SetMapper(this->LatLongMapper);
this->LatLongActor->PickableOff();
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::SelectRepresentation()
{
if (this->CurrentRenderer == NULL)
{
return;
}
this->CurrentRenderer->RemoveActor(this->LatLongActor);
if (this->LatLongLines)
{
this->CurrentRenderer->AddActor(this->LatLongActor);
this->LatLongActor->VisibilityOn();
}
else
{
this->LatLongActor->VisibilityOff();
}
}
//----------------------------------------------------------------------------
void vtkInteractorStyleTerrain::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Latitude/Longitude Lines: "
<< (this->LatLongLines ? "On\n" : "Off\n");
}