/*========================================================================= Program: Visualization Toolkit Module: vtkInteractorStyleTreeMapHover.cxx 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. =========================================================================*/ /*------------------------------------------------------------------------- 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. -------------------------------------------------------------------------*/ #include "vtkInteractorStyleTreeMapHover.h" #include "vtkActor.h" #include "vtkBalloonRepresentation.h" #include "vtkCallbackCommand.h" #include "vtkCellArray.h" #include "vtkIdTypeArray.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPoints.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkProperty.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRendererCollection.h" #include "vtkStdString.h" #include "vtkStringArray.h" #include "vtkTreeMapLayout.h" #include "vtkTreeMapToPolyData.h" #include "vtkVariant.h" #include "vtkWorldPointPicker.h" vtkStandardNewMacro(vtkInteractorStyleTreeMapHover); //------------------------------------------------------------------------------ vtkInteractorStyleTreeMapHover::vtkInteractorStyleTreeMapHover() { this->Picker = vtkWorldPointPicker::New(); this->Balloon = vtkBalloonRepresentation::New(); this->Balloon->SetBalloonText(""); this->Balloon->SetOffset(1, 1); // this->Balloon->SetNeedToRender(true); this->Layout = nullptr; this->LabelField = nullptr; this->CurrentSelectedId = -1; this->TreeMapToPolyData = nullptr; this->Layout = nullptr; // Setup up pipelines for highlighting and selecting vertices this->SelectionPoints = vtkPoints::New(); this->SelectionPoints->SetNumberOfPoints(5); this->HighlightPoints = vtkPoints::New(); this->HighlightPoints->SetNumberOfPoints(5); vtkCellArray* selA = vtkCellArray::New(); selA->InsertNextCell(5); vtkCellArray* highA = vtkCellArray::New(); highA->InsertNextCell(5); int i; for (i = 0; i < 5; ++i) { selA->InsertCellPoint(i); highA->InsertCellPoint(i); } vtkPolyData* selData = vtkPolyData::New(); selData->SetPoints(this->SelectionPoints); selData->SetLines(selA); vtkPolyDataMapper* selMap = vtkPolyDataMapper::New(); selMap->SetInputData(selData); this->SelectionActor = vtkActor::New(); this->SelectionActor->SetMapper(selMap); this->SelectionActor->VisibilityOff(); this->SelectionActor->PickableOff(); this->SelectionActor->GetProperty()->SetLineWidth(2.0); vtkPolyData* highData = vtkPolyData::New(); highData->SetPoints(this->HighlightPoints); highData->SetLines(highA); vtkPolyDataMapper* highMap = vtkPolyDataMapper::New(); highMap->SetInputData(highData); this->HighlightActor = vtkActor::New(); this->HighlightActor->SetMapper(highMap); this->HighlightActor->VisibilityOff(); this->HighlightActor->PickableOff(); this->HighlightActor->GetProperty()->SetColor(1, 1, 1); this->HighlightActor->GetProperty()->SetLineWidth(1.0); selA->Delete(); selData->Delete(); selMap->Delete(); highA->Delete(); highData->Delete(); highMap->Delete(); } //------------------------------------------------------------------------------ vtkInteractorStyleTreeMapHover::~vtkInteractorStyleTreeMapHover() { this->SelectionPoints->Delete(); this->HighlightPoints->Delete(); this->SelectionActor->Delete(); this->HighlightActor->Delete(); this->Picker->Delete(); this->Balloon->Delete(); if (this->Layout != nullptr) { this->Layout->Delete(); this->Layout = nullptr; } if (this->TreeMapToPolyData != nullptr) { this->TreeMapToPolyData->Delete(); this->TreeMapToPolyData = nullptr; } this->SetLabelField(nullptr); } vtkCxxSetObjectMacro(vtkInteractorStyleTreeMapHover, Layout, vtkTreeMapLayout); vtkCxxSetObjectMacro(vtkInteractorStyleTreeMapHover, TreeMapToPolyData, vtkTreeMapToPolyData); void vtkInteractorStyleTreeMapHover::SetInteractor(vtkRenderWindowInteractor* rwi) { // See if we already had one vtkRenderWindowInteractor* mrwi = this->GetInteractor(); vtkRenderer* ren; if (mrwi && mrwi->GetRenderWindow()) { this->FindPokedRenderer(0, 0); ren = this->CurrentRenderer; if (ren) { ren->RemoveActor(SelectionActor); ren->RemoveActor(HighlightActor); } } vtkInteractorStyleImage::SetInteractor(rwi); if (rwi && rwi->GetRenderWindow()) { this->FindPokedRenderer(0, 0); ren = this->CurrentRenderer; if (ren) { ren->AddActor(SelectionActor); ren->AddActor(HighlightActor); } } } //------------------------------------------------------------------------------ void vtkInteractorStyleTreeMapHover::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Layout: " << (this->Layout ? "" : "(none)") << endl; if (this->Layout) { this->Layout->PrintSelf(os, indent.GetNextIndent()); } os << indent << "TreeMapToPolyData: " << (this->TreeMapToPolyData ? "" : "(none)") << endl; if (this->TreeMapToPolyData) { this->TreeMapToPolyData->PrintSelf(os, indent.GetNextIndent()); } os << indent << "LabelField: " << (this->LabelField ? this->LabelField : "(none)") << endl; } vtkIdType vtkInteractorStyleTreeMapHover::GetTreeMapIdAtPos(int x, int y) { vtkIdType id = -1; vtkRenderer* r = this->CurrentRenderer; if (r == nullptr) { return id; } // 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); if (this->Layout != nullptr) { float posFloat[3]; for (int i = 0; i < 3; i++) { posFloat[i] = pos[i]; } id = Layout->FindVertex(posFloat); } return id; } void vtkInteractorStyleTreeMapHover::GetBoundingBoxForTreeMapItem(vtkIdType id, float* binfo) { if (this->Layout) { this->Layout->GetBoundingBox(id, binfo); } } void vtkInteractorStyleTreeMapHover::OnMouseMove() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); vtkRenderer* r = this->CurrentRenderer; if (r == nullptr) { return; } if (!r->HasViewProp(this->Balloon)) { r->AddActor(this->Balloon); this->Balloon->SetRenderer(r); } // Use the hardware picker to find a point in world coordinates. float binfo[4]; vtkIdType id = this->GetTreeMapIdAtPos(x, y); if (id != -1) { this->GetBoundingBoxForTreeMapItem(id, binfo); } double loc[2] = { static_cast(x), static_cast(y) }; this->Balloon->EndWidgetInteraction(loc); if ((this->Layout != nullptr) && (this->Layout->GetOutput() != nullptr)) { vtkAbstractArray* absArray = this->Layout->GetOutput()->GetVertexData()->GetAbstractArray(this->LabelField); if (absArray != nullptr && id > -1) { vtkStdString str; if (vtkArrayDownCast(absArray)) { str = vtkArrayDownCast(absArray)->GetValue(id); } if (vtkArrayDownCast(absArray)) { str = vtkVariant(vtkArrayDownCast(absArray)->GetTuple(id)[0]).ToString(); } this->Balloon->SetBalloonText(str); vtkTree* tree = this->Layout->GetOutput(); double z; if (this->TreeMapToPolyData != nullptr) { z = this->TreeMapToPolyData->GetLevelDeltaZ() * (tree->GetLevel(id) + 1); } else { z = 0.02; } this->HighlightPoints->SetPoint(0, binfo[0], binfo[2], z); this->HighlightPoints->SetPoint(1, binfo[1], binfo[2], z); this->HighlightPoints->SetPoint(2, binfo[1], binfo[3], z); this->HighlightPoints->SetPoint(3, binfo[0], binfo[3], z); this->HighlightPoints->SetPoint(4, binfo[0], binfo[2], z); this->HighlightPoints->Modified(); this->HighlightActor->VisibilityOn(); } else { this->Balloon->SetBalloonText(""); HighlightActor->VisibilityOff(); } this->Balloon->StartWidgetInteraction(loc); this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); this->Superclass::OnMouseMove(); this->GetInteractor()->Render(); } } void vtkInteractorStyleTreeMapHover::SetHighLightColor(double r, double g, double b) { this->HighlightActor->GetProperty()->SetColor(r, g, b); } void vtkInteractorStyleTreeMapHover::SetSelectionLightColor(double r, double g, double b) { this->SelectionActor->GetProperty()->SetColor(r, g, b); } void vtkInteractorStyleTreeMapHover::SetHighLightWidth(double lw) { this->HighlightActor->GetProperty()->SetLineWidth(lw); } double vtkInteractorStyleTreeMapHover::GetHighLightWidth() { return this->HighlightActor->GetProperty()->GetLineWidth(); } void vtkInteractorStyleTreeMapHover::SetSelectionWidth(double lw) { this->SelectionActor->GetProperty()->SetLineWidth(lw); } double vtkInteractorStyleTreeMapHover::GetSelectionWidth() { return this->SelectionActor->GetProperty()->GetLineWidth(); } //------------------------------------------------------------------------------ void vtkInteractorStyleTreeMapHover::OnLeftButtonUp() { // Get the id of the object underneath the mouse int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); #if 0 vtkRenderer* r = this->CurrentRenderer; if (r == nullptr) { return; } if (!r->HasViewProp(this->Balloon)) { r->AddActor(this->Balloon); this->Balloon->SetRenderer(r); } double loc[2] = {x, y}; this->Balloon->EndWidgetInteraction(loc); #endif this->CurrentSelectedId = GetTreeMapIdAtPos(x, y); // Get the pedigree id of this object and // send out an event with that id as data vtkIdType id = this->CurrentSelectedId; vtkAbstractArray* absArray = this->Layout->GetOutput()->GetVertexData()->GetAbstractArray("PedigreeVertexId"); if (absArray) { vtkIdTypeArray* idArray = vtkArrayDownCast(absArray); if (idArray) { id = idArray->GetValue(this->CurrentSelectedId); } } this->InvokeEvent(vtkCommand::UserEvent, &id); this->HighLightCurrentSelectedItem(); Superclass::OnLeftButtonUp(); } void vtkInteractorStyleTreeMapHover::HighLightItem(vtkIdType id) { this->CurrentSelectedId = id; this->HighLightCurrentSelectedItem(); } void vtkInteractorStyleTreeMapHover::HighLightCurrentSelectedItem() { float binfo[4]; if (this->CurrentSelectedId > -1) { this->GetBoundingBoxForTreeMapItem(this->CurrentSelectedId, binfo); vtkTree* tree = this->Layout->GetOutput(); double z; if (this->TreeMapToPolyData != nullptr) { z = this->TreeMapToPolyData->GetLevelDeltaZ() * (tree->GetLevel(this->CurrentSelectedId) + 1); } else { z = 0.01; } this->SelectionPoints->SetPoint(0, binfo[0], binfo[2], z); this->SelectionPoints->SetPoint(1, binfo[1], binfo[2], z); this->SelectionPoints->SetPoint(2, binfo[1], binfo[3], z); this->SelectionPoints->SetPoint(3, binfo[0], binfo[3], z); this->SelectionPoints->SetPoint(4, binfo[0], binfo[2], z); this->SelectionPoints->Modified(); this->SelectionActor->VisibilityOn(); } else { SelectionActor->VisibilityOff(); } if (this->GetInteractor()) { this->GetInteractor()->Render(); } }