vtkInteractorStyleAreaSelectHover.cxx 10.5 KB
Newer Older
1 2
/*=========================================================================

3 4
  Program:   Visualization Toolkit
  Module:    vtkInteractorStyleAreaSelectHover.cxx
5

6 7 8 9 10 11 12
  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.
13 14 15 16 17 18

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
19
-------------------------------------------------------------------------*/
20

21
#include "vtkInteractorStyleAreaSelectHover.h"
22 23

#include "vtkActor.h"
24 25
#include "vtkAppendPolyData.h"
#include "vtkAreaLayout.h"
26 27 28
#include "vtkBalloonRepresentation.h"
#include "vtkCallbackCommand.h"
#include "vtkCellArray.h"
29
#include "vtkExtractEdges.h"
30 31 32 33 34 35 36 37 38 39
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRendererCollection.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
40
#include "vtkSectorSource.h"
41 42 43
#include "vtkStdString.h"
#include "vtkStringArray.h"
#include "vtkVariant.h"
44
#include "vtkWorldPointPicker.h"
45 46

#include "vtkSmartPointer.h"
47
#define VTK_CREATE(type, name)                                  \
48 49
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

50
vtkStandardNewMacro(vtkInteractorStyleAreaSelectHover);
51

52
vtkCxxSetObjectMacro(vtkInteractorStyleAreaSelectHover, Layout, vtkAreaLayout);
53 54

//----------------------------------------------------------------------------
55
vtkInteractorStyleAreaSelectHover::vtkInteractorStyleAreaSelectHover()
56 57 58 59 60
{
  this->Picker = vtkWorldPointPicker::New();
  this->Balloon = vtkBalloonRepresentation::New();
  this->Balloon->SetBalloonText("");
  this->Balloon->SetOffset(1, 1);
61 62
  this->Layout = nullptr;
  this->LabelField = nullptr;
63
  this->UseRectangularCoordinates = false;
64

65 66
  this->HighlightData = vtkPolyData::New();
  vtkPolyDataMapper *highMap = vtkPolyDataMapper::New();
67
  highMap->SetInputData(this->HighlightData);
68 69 70 71 72 73 74 75 76
  this->HighlightActor = vtkActor::New();
  this->HighlightActor->SetMapper(highMap);
  this->HighlightActor->VisibilityOff();
  this->HighlightActor->PickableOff();
  this->HighlightActor->GetProperty()->SetLineWidth(4.0);
  highMap->Delete();
}

//----------------------------------------------------------------------------
77
vtkInteractorStyleAreaSelectHover::~vtkInteractorStyleAreaSelectHover()
78 79 80 81 82
{
  this->HighlightData->Delete();
  this->HighlightActor->Delete();
  this->Picker->Delete();
  this->Balloon->Delete();
83
  if (this->Layout)
84
  {
85
    this->Layout->Delete();
86
    this->Layout = nullptr;
87
  }
88
  this->SetLabelField(nullptr);
89 90
}

91 92
//----------------------------------------------------------------------------
void vtkInteractorStyleAreaSelectHover::SetInteractor(vtkRenderWindowInteractor *rwi)
93 94 95 96
{
  // See if we already had one
  vtkRenderWindowInteractor *mrwi = this->GetInteractor();
  vtkRenderer *ren;
97
  if (mrwi && mrwi->GetRenderWindow())
98
  {
99 100
    this->FindPokedRenderer(0, 0);
    ren = this->CurrentRenderer;
101
    if (ren)
102
    {
103 104
      ren->RemoveActor(HighlightActor);
    }
105
  }
106 107
  vtkInteractorStyleRubberBand2D::SetInteractor(rwi);
  if (rwi && rwi->GetRenderWindow())
108
  {
109 110
    this->FindPokedRenderer(0, 0);
    ren = this->CurrentRenderer;
111
    if (ren)
112
    {
113 114
      ren->AddActor(HighlightActor);
    }
115
  }
116 117 118
}

//----------------------------------------------------------------------------
119
void vtkInteractorStyleAreaSelectHover::PrintSelf(ostream& os, vtkIndent indent)
120 121 122 123
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Layout: " << (this->Layout ? "" : "(none)") << endl;
  if (this->Layout)
124
  {
125
    this->Layout->PrintSelf(os, indent.GetNextIndent());
126
  }
127 128 129 130
  os << indent << "LabelField: " << (this->LabelField ? this->LabelField : "(none)") << endl;
  os << indent << "UseRectangularCoordinates: " << this->UseRectangularCoordinates << endl;
}

131 132
//----------------------------------------------------------------------------
vtkIdType vtkInteractorStyleAreaSelectHover::GetIdAtPos(int x, int y)
133 134
{
  vtkIdType id=-1;
135

136
  vtkRenderer* r = this->CurrentRenderer;
137
  if (r == nullptr)
138
  {
139
    return id;
140
  }
141

142 143 144 145
  // Use the hardware picker to find a point in world coordinates.
  this->Picker->Pick(x, y, 0, r);
  double pos[3];
  this->Picker->GetPickPosition(pos);
146 147

  if (this->Layout)
148
  {
149 150
    float posFloat[3];
    for (int i = 0; i < 3; i++)
151
    {
152 153
      posFloat[i] = pos[i];
    }
154 155
    id = this->Layout->FindVertex(posFloat);
  }
156

157 158 159
  return id;
}

160 161
//----------------------------------------------------------------------------
void vtkInteractorStyleAreaSelectHover::GetBoundingAreaForItem(vtkIdType id, float *sinfo)
162 163
{
  if (this->Layout)
164
  {
165
    this->Layout->GetBoundingArea(id, sinfo);
166
  }
167 168
}

169 170
//----------------------------------------------------------------------------
void vtkInteractorStyleAreaSelectHover::OnMouseMove()
171
{
172
  if (this->Interaction == vtkInteractorStyleRubberBand2D::SELECTING)
173
  {
174 175 176
    this->Balloon->SetVisibility(false);
    this->Superclass::OnMouseMove();
    return;
177
  }
178 179
  this->Balloon->SetVisibility(true);

180 181 182 183
  int x = this->Interactor->GetEventPosition()[0];
  int y = this->Interactor->GetEventPosition()[1];
  this->FindPokedRenderer(x, y);
  vtkRenderer* r = this->CurrentRenderer;
184
  if (r == nullptr)
185
  {
186
    return;
187
  }
188

189
  if (!r->HasViewProp(this->Balloon))
190
  {
191 192
    r->AddActor(this->Balloon);
    this->Balloon->SetRenderer(r);
193
  }
194

195 196
  // Use the hardware picker to find a point in world coordinates.
  float sinfo[4];
197 198
  vtkIdType id = this->GetIdAtPos(x,y);

199
  if( id != -1 )
200
  {
201
    this->GetBoundingAreaForItem(id,sinfo);
202
  }
203

204
  double loc[2] = {static_cast<double>(x), static_cast<double>(y)};
205
  this->Balloon->EndWidgetInteraction(loc);
206 207

  if (this->Layout && this->Layout->GetOutput())
208
  {
209
    vtkAbstractArray* absArray = this->Layout->GetOutput()->GetVertexData()->GetAbstractArray(this->LabelField);
210 211
    //find the information for the correct sector,
    //  unless there isn't a sector or it is the root node
212
    if (absArray != nullptr && id > -1 )
213
    {
214
      vtkStdString str;
215
      if (vtkArrayDownCast<vtkStringArray>(absArray))
216
      {
217
        str = vtkArrayDownCast<vtkStringArray>(absArray)->GetValue(id);
218
      }
219
      if (vtkArrayDownCast<vtkDataArray>(absArray))
220
      {
221
        str = vtkVariant(vtkArrayDownCast<vtkDataArray>(absArray)->GetTuple(id)[0]).ToString();
222
      }
223 224 225
      this->Balloon->SetBalloonText(str);
      double z = 0.02;
      if( this->UseRectangularCoordinates )
226
      {
227 228
        VTK_CREATE(vtkPoints, highlightPoints);
        highlightPoints->SetNumberOfPoints(5);
229

230 231 232
        VTK_CREATE(vtkCellArray, highA);
        highA->InsertNextCell(5);
        for( int i = 0; i < 5; ++i)
233
        {
234
          highA->InsertCellPoint(i);
235
        }
236 237 238 239 240 241 242
        highlightPoints->SetPoint(0, sinfo[0], sinfo[2], z);
        highlightPoints->SetPoint(1, sinfo[1], sinfo[2], z);
        highlightPoints->SetPoint(2, sinfo[1], sinfo[3], z);
        highlightPoints->SetPoint(3, sinfo[0], sinfo[3], z);
        highlightPoints->SetPoint(4, sinfo[0], sinfo[2], z);
        this->HighlightData->SetPoints(highlightPoints);
        this->HighlightData->SetLines(highA);
243
      }
244
      else
245
      {
246
        if( sinfo[1] - sinfo[0] != 360. )
247
        {
248 249 250 251 252 253
          VTK_CREATE(vtkSectorSource, sector);
          sector->SetInnerRadius(sinfo[2]);
          sector->SetOuterRadius(sinfo[3]);
          sector->SetZCoord(z);
          sector->SetStartAngle(sinfo[0]);
          sector->SetEndAngle(sinfo[1]);
254

255 256
          int resolution = (int)((sinfo[1]-sinfo[0])/1);
          if( resolution < 1 )
257
            resolution = 1;
258 259
          sector->SetCircumferentialResolution(resolution);
          sector->Update();
260

261
          VTK_CREATE(vtkExtractEdges, extract);
262
          extract->SetInputConnection(sector->GetOutputPort());
263

264
          VTK_CREATE(vtkAppendPolyData, append);
265
          append->AddInputConnection(extract->GetOutputPort());
266
          append->Update();
267

268
          this->HighlightData->ShallowCopy(append->GetOutput());
269
        }
270
        else
271
        {
272 273
          VTK_CREATE(vtkPoints, highlightPoints);
          highlightPoints->SetNumberOfPoints(240);
274

275 276
          double conversion = vtkMath::Pi()/180.;
          double current_angle = 0.;
277

278 279
          VTK_CREATE(vtkCellArray, highA);
          for( int i = 0; i < 120; ++i)
280
          {
281 282 283 284
            highA->InsertNextCell(2);
            double current_x = sinfo[2]*cos(conversion*current_angle);
            double current_y = sinfo[2]*sin(conversion*current_angle);
            highlightPoints->SetPoint( i, current_x, current_y, z );
285

286
            current_angle += 3.;
287

288 289
            highA->InsertCellPoint(i);
            highA->InsertCellPoint((i+1)%120);
290
          }
291

292 293
          current_angle = 0.;
          for( int i = 0; i < 120; ++i)
294
          {
295 296 297 298
            highA->InsertNextCell(2);
            double current_x = sinfo[3]*cos(conversion*current_angle);
            double current_y = sinfo[3]*sin(conversion*current_angle);
            highlightPoints->SetPoint( 120+i, current_x, current_y, z );
299

300
            current_angle += 3.;
301

302 303
            highA->InsertCellPoint(120+i);
            highA->InsertCellPoint(120+((i+1)%120));
304
          }
305 306
          this->HighlightData->SetPoints(highlightPoints);
          this->HighlightData->SetLines(highA);
307
        }
308
      }
309 310
      this->HighlightActor->VisibilityOn();
    }
311
    else
312
    {
313 314
      this->Balloon->SetBalloonText("");
      HighlightActor->VisibilityOff();
315
    }
316

317
    this->Balloon->StartWidgetInteraction(loc);
318

319
    this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
320
    this->GetInteractor()->Render();
321
  }
322

323 324 325
  this->Superclass::OnMouseMove();
}

326 327
//----------------------------------------------------------------------------
void vtkInteractorStyleAreaSelectHover::SetHighLightColor(double r, double g, double b)
328 329 330 331
{
  this->HighlightActor->GetProperty()->SetColor(r, g, b);
}

332 333
//----------------------------------------------------------------------------
void vtkInteractorStyleAreaSelectHover::SetHighLightWidth(double lw)
334 335 336 337
{
  this->HighlightActor->GetProperty()->SetLineWidth(lw);
}

338 339
//----------------------------------------------------------------------------
double vtkInteractorStyleAreaSelectHover::GetHighLightWidth()
340 341 342 343
{
  return this->HighlightActor->GetProperty()->GetLineWidth();
}