// nUtil - An utility Library for gnurbs
// Copyright (C) 2008-2026 Eric Bechet
//
// See the LICENSE file for contributions and license information.
// Please report all bugs and problems to <bechet@cadxfem.org>.
//

#include "vtkdisplay.h"
#include "keyboardCallback.h"
#include "mousewheelforwardCallback.h"
#include "mousewheelbackwardCallback.h"

#include <vtkCellArray.h>
#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkPoints.h>
#include <vtkVertex.h>
#include <vtkLine.h>
#include <vtkTriangle.h>
#include <vtkQuad.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
#include <vtkVectorText.h>
#include <vtkFollower.h>


#include "vtkLinearExtrusionFilter.h"
#include "vtkTextActor3D.h"
#include "vtkTextActor.h"
#include "vtkTextProperty.h"

void vtkdisplay::test(void)
{

double world_coord[3]={0.,0.,0.};
renderer->SetWorldPoint(world_coord[0], world_coord[1], world_coord[2], 1.0);
renderer->WorldToDisplay();
double *screen_coord = renderer->GetDisplayPoint();
  vtkTextActor* text = vtkTextActor::New();
  text->SetInput ( "VTK tutorial\nvtkTextActor!" );
  vtkTextProperty* tprop = text->GetTextProperty();
  tprop->SetFontFamilyToArial ();
//  tprop->BoldOn();
//  tprop->ShadowOn();
  tprop->SetLineSpacing ( 1.0 );
  tprop->SetFontSize ( 12 );
  tprop->SetColor ( 1.0,0.0,0.0 );
//  tprop->SetShadowOffset ( 2,2 );
  text->SetDisplayPosition (screen_coord[0], screen_coord[1] );
  renderer->AddActor2D ( text );
/* 3D text
  // Create a vector text
  vtkVectorText* vecText = vtkVectorText::New();
  vecText->SetText ( "vtkVectorText" );

  vtkLinearExtrusionFilter* extrude = vtkLinearExtrusionFilter::New();
  extrude->SetInputConnection ( vecText->GetOutputPort() );
  extrude->SetExtrusionTypeToNormalExtrusion();
  extrude->SetVector ( 0, 0, 1 );
  extrude->SetScaleFactor ( 0.5 );

  vtkPolyDataMapper* txtMapper = vtkPolyDataMapper::New();
  txtMapper->SetInputConnection ( extrude->GetOutputPort() );
  vtkActor* txtActor = vtkActor::New();
  txtActor->SetMapper ( txtMapper );
  ren->AddActor ( txtActor );

*/
}


vtkdisplay::vtkdisplay(color c,char *nom):line(true),quad(true),triangle(true),vertice(true)
{
  numero[0]=true;
  numero[1]=true;
  numero[2]=true;
  renderer = vtkSmartPointer<vtkRenderer>::New();
  renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindowInteractor =  vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactorObserver = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();

  renderWindow->AddRenderer(renderer);
  if (nom!=NULL) renderWindow->SetWindowName(nom);
  renderWindowInteractor->SetRenderWindow(renderWindow);
  renderWindowInteractor->SetInteractorStyle(interactorObserver);
  renderWindow->SetSize(600, 600);
//  renderWindow->SetAAFrames(5); // soft antialiasing
//  renderWindow->SetMultiSamples(5); // hardware antialiasing
  double r=c.R/255.;
  double g=c.G/255.;
  double b=c.B/255.;
  renderer->SetBackground(r, g, b);
}


void vtkdisplay::display(bool perspectiveon)
{
  renderer->ResetCamera();
  if (perspectiveon==true) renderer->GetActiveCamera()->ParallelProjectionOn();
  renderWindow->Render();
  keyboardCallback *keybcall = keyboardCallback::New(this);
  renderWindowInteractor->AddObserver(vtkCommand::KeyPressEvent, keybcall);
  mousewheelforwardCallback *mousewheelforwardcall=mousewheelforwardCallback::New(this);
  renderWindowInteractor->AddObserver(vtkCommand::MouseWheelForwardEvent, mousewheelforwardcall);
  mousewheelbackwardCallback *mousewheelbackwardcall=mousewheelbackwardCallback::New(this);
  renderWindowInteractor->AddObserver(vtkCommand::MouseWheelBackwardEvent, mousewheelbackwardcall);
  
  saveCameraDefault();
  scaleactif=renderer->GetActiveCamera()->GetParallelScale();
  renderWindowInteractor->Start();
}

void vtkdisplay::init_data_vertices(data_container & data)
{
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
   
   for (int blk=0;blk<data.getnumproppoints();++blk)
  {
    color c=data.getcolorpoints(blk);
    int last=(blk+1<data.getnumproppoints()) ? data.getindexpoints(blk+1) : data.nb_points();
//    std::cout << blk << " " << data.getindexpoints(blk) << " " << last << std::endl ;
   vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
   for (int i=data.getindexpoints(blk);i!=last;++i)
    {
      points->InsertNextPoint(data.get_point(i).pts.array());
      vtkSmartPointer<vtkVertex> vertex = vtkSmartPointer<vtkVertex>::New();
      vertex->GetPointIds()->InsertId(0,i);
      vertices->InsertNextCell(vertex);
    }
    //Create a polydata to store everything in
    vtkSmartPointer<vtkPolyData> verticesPolyData = vtkSmartPointer<vtkPolyData>::New();
    //add the points to the dataset
    verticesPolyData->SetPoints(points);
    //add the lines to the dataset
    verticesPolyData->SetVerts(vertices);
    //setup actor and mapper
    vtkSmartPointer<vtkPolyDataMapper> mapper_vertices = vtkSmartPointer<vtkPolyDataMapper>::New();
#if (VTK_MAJOR_VERSION>=6)
    mapper_vertices->SetInputData(verticesPolyData);
#else
    mapper_vertices->SetInput(verticesPolyData);
#endif
    vtkSmartPointer<vtkActor> actor_vertices = vtkSmartPointer<vtkActor>::New();
    double r=data.getcolorpoints(blk).R/255.;
    double g=data.getcolorpoints(blk).G/255.;
    double b=data.getcolorpoints(blk).B/255.;
    actor_vertices->GetProperty()->SetColor(r,g,b);
    actor_vertices->GetProperty()->SetOpacity(data.getcolorpoints(blk).A/255.);
    actor_vertices->GetProperty()->SetPointSize(data.getproppoints(blk).pointsize);
    actor_vertices->SetMapper(mapper_vertices);
    renderer->AddActor(actor_vertices);
    list_vertice.push_back(actor_vertices);
  }
 
 
 
}
void vtkdisplay::init_data_textes(data_container & data)
{
if (data.nb_texts(0)+data.nb_texts(1)+data.nb_texts(2)==0) return;
double xmin=1e308,ymin=1e308,zmin=1e308;
double xmax=-1e308,ymax=-1e308,zmax=-1e308;
for (int dim=0;dim<3;dim++)
  {
  int nb=data.nb_texts(dim);
  for (int i=0;i<nb;i++)
    {
    if (data.get_text(dim,i).pts.x()<xmin) xmin=data.get_text(dim,i).pts.x();
    if (data.get_text(dim,i).pts.y()<ymin) ymin=data.get_text(dim,i).pts.y();
    if (data.get_text(dim,i).pts.z()<zmin) zmin=data.get_text(dim,i).pts.z();
    if (data.get_text(dim,i).pts.x()>xmax) xmax=data.get_text(dim,i).pts.x();
    if (data.get_text(dim,i).pts.y()>ymax) ymax=data.get_text(dim,i).pts.y();
    if (data.get_text(dim,i).pts.z()>zmax) zmax=data.get_text(dim,i).pts.z();
    }  
  }
  int nb2=data.nb_points();
  for (int i=0;i<nb2;i++)
    {
    if (data.get_point(i).pts.x()<xmin) xmin=data.get_point(i).pts.x();
    if (data.get_point(i).pts.y()<xmin) ymin=data.get_point(i).pts.y();
    if (data.get_point(i).pts.z()<xmin) zmin=data.get_point(i).pts.z();
    if (data.get_point(i).pts.x()>xmax) xmax=data.get_point(i).pts.x();
    if (data.get_point(i).pts.y()>ymax) ymax=data.get_point(i).pts.y();
    if (data.get_point(i).pts.z()>zmax) zmax=data.get_point(i).pts.z();
    }
  int nb3=data.nb_lines();
  for (int i=0;i<nb3;i++)
    {
    for (int dim=0;dim<2;dim++)
      { 
      if (data.get_line(i).pts[dim].x()<xmin) xmin=data.get_line(i).pts[dim].x();
      if (data.get_line(i).pts[dim].y()<ymin) ymin=data.get_line(i).pts[dim].y();
      if (data.get_line(i).pts[dim].z()<zmin) zmin=data.get_line(i).pts[dim].z();
      if (data.get_line(i).pts[dim].x()>xmax) xmax=data.get_line(i).pts[dim].x();
      if (data.get_line(i).pts[dim].y()>ymax) ymax=data.get_line(i).pts[dim].y();
      if (data.get_line(i).pts[dim].z()>zmax) zmax=data.get_line(i).pts[dim].z();
      }
    }
  int nb4=data.nb_triangles();
  for (int i=0;i<nb4;i++)
    {
    for (int dim=0;dim<3;dim++)
      { 
      if (data.get_triangle(i).pts[dim].x()<xmin) xmin=data.get_triangle(i).pts[dim].x();
      if (data.get_triangle(i).pts[dim].y()<ymin) ymin=data.get_triangle(i).pts[dim].y();
      if (data.get_triangle(i).pts[dim].z()<zmin) zmin=data.get_triangle(i).pts[dim].z();
      if (data.get_triangle(i).pts[dim].x()>xmax) xmax=data.get_triangle(i).pts[dim].x();
      if (data.get_triangle(i).pts[dim].y()>ymax) ymax=data.get_triangle(i).pts[dim].y();
      if (data.get_triangle(i).pts[dim].z()>zmax) zmax=data.get_triangle(i).pts[dim].z();
      }
    }
  int nb5=data.nb_quads();
  for (int i=0;i<nb5;i++)
    {
    for (int dim=0;dim<4;dim++)
      { 
      if (data.get_quad(i).pts[dim].x()<xmin) xmin=data.get_quad(i).pts[dim].x();
      if (data.get_quad(i).pts[dim].y()<ymin) ymin=data.get_quad(i).pts[dim].y();
      if (data.get_quad(i).pts[dim].z()<zmin) zmin=data.get_quad(i).pts[dim].z();
      if (data.get_quad(i).pts[dim].x()>xmax) xmax=data.get_quad(i).pts[dim].x();
      if (data.get_quad(i).pts[dim].y()>ymax) ymax=data.get_quad(i).pts[dim].y();
      if (data.get_quad(i).pts[dim].z()>zmax) zmax=data.get_quad(i).pts[dim].z();
      }
    }
  double xec=xmax-xmin;
  double yec=ymax-ymin;
  double zec=zmax-zmin;
  double scale=xec;
  
  if (yec>scale) scale=yec;
  if (zec>scale) scale=zec;

for (int dim=0;dim<3;dim++)
{
  int nb=data.nb_texts(dim);
  for (int i=0;i<nb;i++)
    {
    vtkSmartPointer<vtkVectorText> textSource = 
    vtkSmartPointer<vtkVectorText>::New();
    textSource->SetText( data.get_text(dim,i).info.c_str() );
  
  
  // Create a mapper
    vtkSmartPointer<vtkPolyDataMapper> mapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection( textSource->GetOutputPort() );
  
 
 
  // Create a subclass of vtkActor: a vtkFollower that remains facing the camera
    vtkSmartPointer<vtkFollower> follower = 
    vtkSmartPointer<vtkFollower>::New();
    follower->SetMapper( mapper );
    follower->GetProperty()->SetColor( data.get_text_color(dim,i).R/255.,data.get_text_color(dim,i).G/255.,data.get_text_color(dim,i).B/255.); // red 
    follower->SetPosition(data.get_text(dim,i).pts.x(),data.get_text(dim,i).pts.y(),data.get_text(dim,i).pts.z()); // red 
    follower->SetScale(0.008333333*3.*scale); // red 
    renderer->AddActor( follower );
    follower->SetCamera( renderer->GetActiveCamera() );
    list_numero[dim].push_back(follower);
    }
  }
}

void vtkdisplay::init_data_lines(data_container & data)
{
  vtkSmartPointer<vtkPoints> linespoints = vtkSmartPointer<vtkPoints>::New();
  for (int blk=0;blk<data.getnumproplines();++blk)
  {
    color c=data.getcolorlines(blk);
    int last=(blk+1<data.getnumproplines()) ? data.getindexlines(blk+1) : data.nb_lines();
//    std::cout << blk << " " << data.getindexlines(blk) << " " << last << std::endl ;
    vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
    for (int i=data.getindexlines(blk);i!=last;++i)
    {
      linespoints->InsertNextPoint(data.get_line(i).pts[0].array());
      linespoints->InsertNextPoint(data.get_line(i).pts[1].array());
      vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();
      line->GetPointIds()->InsertId(0,i*2);
      line->GetPointIds()->InsertId(1,i*2+1);
      lines->InsertNextCell(line);
    }
    //Create a polydata to store everything in
    vtkSmartPointer<vtkPolyData> linesPolyData = vtkSmartPointer<vtkPolyData>::New();
    //add the points to the dataset
    linesPolyData->SetPoints(linespoints);
    //add the lines to the dataset
    linesPolyData->SetLines(lines);
    //setup actor and mapper
    vtkSmartPointer<vtkPolyDataMapper> mapper_lines = vtkSmartPointer<vtkPolyDataMapper>::New();
#if (VTK_MAJOR_VERSION>=6)
    mapper_lines->SetInputData(linesPolyData);
#else
    mapper_lines->SetInput(linesPolyData);
#endif
    vtkSmartPointer<vtkActor> actor_lines = vtkSmartPointer<vtkActor>::New();
    double r=data.getcolorlines(blk).R/255.;
    double g=data.getcolorlines(blk).G/255.;
    double b=data.getcolorlines(blk).B/255.;
    double a=data.getcolorlines(blk).A/255.;
    actor_lines->GetProperty()->SetColor(r,g,b);
    actor_lines->GetProperty()->SetOpacity(a);
    actor_lines->GetProperty()->SetLineWidth(data.getproplines(blk).thickness);
    actor_lines->SetMapper(mapper_lines);
    renderer->AddActor(actor_lines);
    list_line.push_back(actor_lines);
//    renderer->ResetCamera();
  }
}

void vtkdisplay::init_data_triangles(data_container & data)
{
  vtkSmartPointer<vtkPoints> trianglespoints = vtkSmartPointer<vtkPoints>::New();
  for (int blk=0;blk<data.getnumproptriangles();++blk)
  {
    color c=data.getcolortriangles(blk);
    int last=(blk+1<data.getnumproptriangles()) ? data.getindextriangles(blk+1) : data.nb_triangles();
//    std::cout << blk << " " << data.getindextriangles(blk) << " " << last << std::endl ;
    vtkSmartPointer<vtkCellArray> triangles = vtkSmartPointer<vtkCellArray>::New();
    for (int i=data.getindextriangles(blk);i!=last;++i)
    {
      trianglespoints->InsertNextPoint(data.get_triangle(i).pts[0].array());
      trianglespoints->InsertNextPoint(data.get_triangle(i).pts[1].array());
      trianglespoints->InsertNextPoint(data.get_triangle(i).pts[2].array());
      vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();
      triangle->GetPointIds()->InsertId(0,i*3);
      triangle->GetPointIds()->InsertId(1,i*3+1);
      triangle->GetPointIds()->InsertId(2,i*3+2);
      triangles->InsertNextCell(triangle);
    }
    //Create a polydata to store everything in
    vtkSmartPointer<vtkPolyData> trianglesPolyData = vtkSmartPointer<vtkPolyData>::New();
    //add the points to the dataset
    trianglesPolyData->SetPoints(trianglespoints);
    //add the triangles to the dataset
    trianglesPolyData->SetPolys(triangles);
    //setup actor and mapper
    vtkSmartPointer<vtkPolyDataMapper> mapper_triangles = vtkSmartPointer<vtkPolyDataMapper>::New();
    vtkSmartPointer<vtkActor> actor_triangles = vtkSmartPointer<vtkActor>::New();
    double r=data.getcolortriangles(blk).R/255.;
    double g=data.getcolortriangles(blk).G/255.;
    double b=data.getcolortriangles(blk).B/255.;
    double a=data.getcolortriangles(blk).A/255.;
    actor_triangles->GetProperty()->SetColor(r,g,b);
    actor_triangles->GetProperty()->SetOpacity(a);
#if (VTK_MAJOR_VERSION>=6)
    mapper_triangles->SetInputData(trianglesPolyData);
#else
    mapper_triangles->SetInput(trianglesPolyData);
#endif
    
    actor_triangles->SetMapper(mapper_triangles);
    if (data.getproptriangles(blk).edgeon)
    {
      actor_triangles->GetProperty()->EdgeVisibilityOn();
      actor_triangles->GetProperty()->SetEdgeColor(data.getproptriangles(blk).edgecolor.R/255.,data.getproptriangles(blk).edgecolor.G/255.,data.getproptriangles(blk).edgecolor.B/255.);
      actor_triangles->GetProperty()->SetLineWidth(data.getproptriangles(blk).edgethickness);
    }
    renderer->AddActor(actor_triangles);
    list_triangle.push_back(actor_triangles);
  }
}

void vtkdisplay::init_data_quads(data_container & data)
{
  vtkSmartPointer<vtkPoints> quadspoints = vtkSmartPointer<vtkPoints>::New();
  for (int blk=0;blk<data.getnumpropquads();++blk)
  {
    color c=data.getcolorquads(blk);
    int last=(blk+1<data.getnumpropquads()) ? data.getindexquads(blk+1) : data.nb_quads();
//    std::cout << blk << " " << data.getindexquads(blk) << " " << last << std::endl ;
    vtkSmartPointer<vtkCellArray> quads = vtkSmartPointer<vtkCellArray>::New();
    for (int i=data.getindexquads(blk);i!=last;++i)
    {
      quadspoints->InsertNextPoint(data.get_quad(i).pts[0].array());
      quadspoints->InsertNextPoint(data.get_quad(i).pts[1].array());
      quadspoints->InsertNextPoint(data.get_quad(i).pts[2].array());
      quadspoints->InsertNextPoint(data.get_quad(i).pts[3].array());
      vtkSmartPointer<vtkQuad> quad = vtkSmartPointer<vtkQuad>::New();
      quad->GetPointIds()->InsertId(0,i*4);
      quad->GetPointIds()->InsertId(1,i*4+1);
      quad->GetPointIds()->InsertId(2,i*4+2);
      quad->GetPointIds()->InsertId(3,i*4+3);
      quads->InsertNextCell(quad);
    }
    //Create a polydata to store everything in
    vtkSmartPointer<vtkPolyData> quadsPolyData = vtkSmartPointer<vtkPolyData>::New();
    //add the points to the dataset
    quadsPolyData->SetPoints(quadspoints);
    //add the quads to the dataset
    quadsPolyData->SetPolys(quads);
    //setup actor and mapper
    vtkSmartPointer<vtkPolyDataMapper> mapper_quads = vtkSmartPointer<vtkPolyDataMapper>::New();
    vtkSmartPointer<vtkActor> actor_quads = vtkSmartPointer<vtkActor>::New();
    double r=data.getcolorquads(blk).R/255.;
    double g=data.getcolorquads(blk).G/255.;
    double b=data.getcolorquads(blk).B/255.;
    double a=data.getcolorquads(blk).A/255.;
    actor_quads->GetProperty()->SetColor(r,g,b);
    actor_quads->GetProperty()->SetOpacity(a);
    
#if (VTK_MAJOR_VERSION>=6)
    mapper_quads->SetInputData(quadsPolyData);
#else
    mapper_quads->SetInput(quadsPolyData);
#endif
    actor_quads->SetMapper(mapper_quads);
    if (data.getpropquads(blk).edgeon)
    {
      actor_quads->GetProperty()->EdgeVisibilityOn();
      actor_quads->GetProperty()->SetEdgeColor(data.getpropquads(blk).edgecolor.R/255.,data.getpropquads(blk).edgecolor.G/255.,data.getpropquads(blk).edgecolor.B/255.);
      actor_quads->GetProperty()->SetLineWidth(data.getpropquads(blk).edgethickness);
    }
    
    renderer->AddActor(actor_quads);
    list_quad.push_back(actor_quads);
  }
}

void vtkdisplay::init_data(data_container & data)
{
  init_data_vertices(data);
  init_data_lines(data);
  init_data_triangles(data);
  init_data_quads(data);
  init_data_textes(data);
}

void vtkdisplay::mousewheelforwardCall(int x,int y)
{
double scale=renderer->GetActiveCamera()->GetParallelScale();  
double facteur=scaleactif/scale;
scaleactif=scale;
for (int dim=0;dim<3;dim++)
  {
  for (int i=0;i<list_numero[dim].size();i++)  
    {
      double *scaleactor=list_numero[dim][i]->GetScale();
      list_numero[dim][i]->SetScale(*scaleactor/facteur);
    }
    
  }
renderWindow->Render();
}

void vtkdisplay::mousewheelbackwardCall(int x,int y)
{
double scale=renderer->GetActiveCamera()->GetParallelScale();  
double facteur=scaleactif/scale;
scaleactif=scale;
for (int dim=0;dim<3;dim++)
  {
  for (int i=0;i<list_numero[dim].size();i++)  
    {
      double *scaleactor=list_numero[dim][i]->GetScale();
      list_numero[dim][i]->SetScale(*scaleactor/facteur);
    }
    
  }
renderWindow->Render();
}


void vtkdisplay::kbCallback(int key)
{
  switch (key)
  {
    case 114: //r
    {
      resetCamera();
      break;
    }
    case 43:
    {
    for (int dim=0;dim<3;dim++)
      {
      for (int i=0;i<list_numero[dim].size();i++)  
        {
        double *scaleactor=list_numero[dim][i]->GetScale();
        list_numero[dim][i]->SetScale(*scaleactor*1.1);
        }
    
      }
    renderWindow->Render();break;  
    }
    case 45:
    {
    for (int dim=0;dim<3;dim++)
      {
      for (int i=0;i<list_numero[dim].size();i++)  
        {
        double *scaleactor=list_numero[dim][i]->GetScale();
        list_numero[dim][i]->SetScale(*scaleactor/1.1);
        }
    
      }
    renderWindow->Render();break;  
    }
   case 49:
    {
      for (int i=0;i<list_numero[0].size();i++)
	{
	  if (numero[0]==true)
	  renderer->RemoveActor(list_numero[0][i]);
	  else 
	  renderer->AddActor(list_numero[0][i]);
	  
	}
      if (numero[0]==true) numero[0]=false; else numero[0]=true;
      renderWindow->Render();
      break;
    }
   case 52:
    {
      for (int i=0;i<list_numero[1].size();i++)
	{
	  if (numero[1]==true)
	  renderer->RemoveActor(list_numero[1][i]);
	  else 
	  renderer->AddActor(list_numero[1][i]);
	  
	}
      if (numero[1]==true) numero[1]=false; else numero[1]=true;
      renderWindow->Render();
      break;
    }
   case 55:
    {
      for (int i=0;i<list_numero[2].size();i++)
	{
	  if (numero[2]==true)
	  renderer->RemoveActor(list_numero[2][i]);
	  else 
	  renderer->AddActor(list_numero[2][i]);
	  
	}
      if (numero[2]==true) numero[2]=false; else numero[2]=true;
      renderWindow->Render();
      break;
    }
    case 118:
    {
      for (int i=0;i<list_vertice.size();i++)
	{
	  if (vertice==true)
	  renderer->RemoveActor(list_vertice[i]);
	  else 
	  renderer->AddActor(list_vertice[i]);
	  
	}
      if (vertice==true) vertice=false; else vertice=true;
      renderWindow->Render();
      break;
    }
    case 116:
    {
      for (int i=0;i<list_triangle.size();i++)
	{
	  if (triangle==true)
	  renderer->RemoveActor(list_triangle[i]);
	  else 
	  renderer->AddActor(list_triangle[i]);
	  
	}
      if (triangle==true) triangle=false; else triangle=true;
      renderWindow->Render();
      break;
    } 
    case 108:
    {
      for (int i=0;i<list_line.size();i++)
	{
	  if (line==true)
	  renderer->RemoveActor(list_line[i]);
	  else 
	  renderer->AddActor(list_line[i]);
	  
	}
      if (line==true) line=false; else line=true;
      renderWindow->Render();
      break;
    }
    case 113:
    {
      for (int i=0;i<list_quad.size();i++)
	{
	  if (quad==true)
	  renderer->RemoveActor(list_quad[i]);
	  else 
	  renderer->AddActor(list_quad[i]);
	  
	}
      if (quad==true) quad=false; else quad=true;
      renderWindow->Render();
      break;
    }
    case 106:
    {
      double pos[3],focal[3],view[3];
      vtkCamera * cam = renderer->GetActiveCamera();
      cam->GetPosition(pos);
      cam->GetFocalPoint(focal);
      cam->GetViewUp(view);
      double scale=cam->GetParallelScale();
      FILE* out=fopen(".vtkdisplay","wt");
      if (out==NULL) break;
      fprintf(out,"%lf %lf %lf\n",pos[0],pos[1],pos[2]);
      fprintf(out,"%lf %lf %lf\n",focal[0],focal[1],focal[2]);
      fprintf(out,"%lf %lf %lf\n",view[0],view[1],view[2]);
      fprintf(out,"%lf\n",scale);
      fclose(out);
      break;
    }
    case 107:
    {
      double pos[3],focal[3],view[3],scale;
      FILE* in=fopen(".vtkdisplay","rt");
      if (in==NULL) break;
      char mess[255];
      if (fgets(mess,255,in)==NULL) break;
      if (sscanf(mess,"%lf %lf %lf",pos,pos+1,pos+2)!=3) break;
      if (fgets(mess,255,in)==NULL) break;
      if (sscanf(mess,"%lf %lf %lf",focal,focal+1,focal+2)!=3) break;
      if (fgets(mess,255,in)==NULL) break;
      if (sscanf(mess,"%lf %lf %lf",view,view+1,view+2)!=3) break;
      if (fgets(mess,255,in)==NULL) break;
      if (sscanf(mess,"%lf",&scale)!=1) break;
      fclose(in);
      vtkCamera * cam = renderer->GetActiveCamera();
      cam->SetPosition(pos);
      cam->SetFocalPoint(focal);
      cam->SetViewUp(view);
      cam->SetParallelScale(scale);
      renderWindow->Render();
      break;
      
    }
  }
}

void vtkdisplay::saveCameraDefault()
{
  vtkCamera * cam = renderer->GetActiveCamera();
  cam->GetPosition(cameraDefPosition);
  cam->GetFocalPoint(cameraDefFocalPoint);
  cam->GetViewUp(cameraDefViewUp);
}
void vtkdisplay::resetCamera()
{
  vtkCamera * cam = renderer->GetActiveCamera();
  cam->SetPosition(cameraDefPosition);
  cam->SetFocalPoint(cameraDefFocalPoint);
  cam->SetViewUp(cameraDefViewUp);
}

