1 /*=========================================================================
6 Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
9 ParaView is a free software; you can redistribute it and/or modify it
10 under the terms of the ParaView license version 1.2.
12 See License_v1.2.txt for the full ParaView license.
13 A copy of this license can be obtained by contacting
16 Clifton Park, NY 12065
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 #include "vtkPVAxesWidget.h"
34 #include "vtkActor2D.h"
35 #include "vtkCallbackCommand.h"
36 #include "vtkCamera.h"
37 #include "vtkCoordinate.h"
38 #include "vtkObjectFactory.h"
39 #include "vtkPoints.h"
40 #include "vtkPolyData.h"
41 #include "vtkPolyDataMapper2D.h"
42 #include "vtkProperty.h"
43 #include "vtkProperty2D.h"
44 #include "vtkPVAxesActor.h"
45 #include "vtkRenderer.h"
46 #include "vtkRenderWindow.h"
47 #include "vtkRenderWindowInteractor.h"
49 vtkStandardNewMacro(vtkPVAxesWidget);
51 vtkCxxSetObjectMacro(vtkPVAxesWidget, AxesActor, vtkPVAxesActor);
52 vtkCxxSetObjectMacro(vtkPVAxesWidget, ParentRenderer, vtkRenderer);
54 //----------------------------------------------------------------------------
55 class vtkPVAxesWidgetObserver : public vtkCommand
58 static vtkPVAxesWidgetObserver *New()
59 {return new vtkPVAxesWidgetObserver;};
61 vtkPVAxesWidgetObserver()
66 virtual void Execute(vtkObject* wdg, unsigned long event, void *calldata)
70 this->AxesWidget->ExecuteEvent(wdg, event, calldata);
74 vtkPVAxesWidget *AxesWidget;
77 //----------------------------------------------------------------------------
78 vtkPVAxesWidget::vtkPVAxesWidget()
80 this->StartEventObserverId = 0;
82 this->EventCallbackCommand->SetCallback(vtkPVAxesWidget::ProcessEvents);
84 this->Observer = vtkPVAxesWidgetObserver::New();
85 this->Observer->AxesWidget = this;
86 this->Renderer = vtkRenderer::New();
87 this->Renderer->SetViewport(0.0, 0.0, 0.2, 0.2);
88 this->Renderer->SetLayer(1);
89 this->Renderer->InteractiveOff();
90 this->Priority = 0.55;
91 this->AxesActor = vtkPVAxesActor::New();
92 this->Renderer->AddActor(this->AxesActor);
93 this->AxesActor->AddToRender(this->Renderer); // tmp
95 this->ParentRenderer = NULL;
98 this->MouseCursorState = vtkPVAxesWidget::Outside;
102 this->Interactive = 1;
104 this->Outline = vtkPolyData::New();
105 this->Outline->Allocate();
106 vtkPoints *points = vtkPoints::New();
108 ptIds[4] = ptIds[0] = points->InsertNextPoint(1, 1, 0);
109 ptIds[1] = points->InsertNextPoint(2, 1, 0);
110 ptIds[2] = points->InsertNextPoint(2, 2, 0);
111 ptIds[3] = points->InsertNextPoint(1, 2, 0);
112 this->Outline->SetPoints(points);
113 this->Outline->InsertNextCell(VTK_POLY_LINE, 5, ptIds);
114 vtkCoordinate *tcoord = vtkCoordinate::New();
115 tcoord->SetCoordinateSystemToDisplay();
116 vtkPolyDataMapper2D *mapper = vtkPolyDataMapper2D::New();
117 mapper->SetInputData(this->Outline);
118 mapper->SetTransformCoordinate(tcoord);
119 this->OutlineActor = vtkActor2D::New();
120 this->OutlineActor->SetMapper(mapper);
121 this->OutlineActor->SetPosition(0, 0);
122 this->OutlineActor->SetPosition2(1, 1);
129 //----------------------------------------------------------------------------
130 vtkPVAxesWidget::~vtkPVAxesWidget()
132 this->Observer->Delete();
133 this->AxesActor->Delete();
134 this->OutlineActor->Delete();
135 this->Outline->Delete();
136 this->SetParentRenderer(NULL);
137 this->Renderer->Delete();
140 //----------------------------------------------------------------------------
141 void vtkPVAxesWidget::SetEnabled(int enabling)
143 if (!this->Interactor)
145 vtkErrorMacro("The interactor must be set prior to enabling/disabling widget");
154 if (!this->ParentRenderer)
156 vtkErrorMacro("The parent renderer must be set prior to enabling this widget");
162 if ( this->EventCallbackCommand )
164 vtkRenderWindowInteractor *i = this->Interactor;
165 i->AddObserver(vtkCommand::MouseMoveEvent,
166 this->EventCallbackCommand, this->Priority);
167 i->AddObserver(vtkCommand::LeftButtonPressEvent,
168 this->EventCallbackCommand, this->Priority);
169 i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
170 this->EventCallbackCommand, this->Priority);
173 this->ParentRenderer->GetRenderWindow()->AddRenderer(this->Renderer);
174 if (this->ParentRenderer->GetRenderWindow()->GetNumberOfLayers() < 2)
176 this->ParentRenderer->GetRenderWindow()->SetNumberOfLayers(2);
178 this->AxesActor->SetVisibility(1);
179 // We need to copy the camera before the compositing observer is called.
180 // Compositing temporarily changes the camera to display an image.
181 this->StartEventObserverId =
182 this->ParentRenderer->AddObserver(vtkCommand::StartEvent,this->Observer,1);
183 this->InvokeEvent(vtkCommand::EnableEvent, NULL);
193 this->Interactor->RemoveObserver(this->EventCallbackCommand);
195 this->AxesActor->SetVisibility(0);
196 if (this->ParentRenderer)
198 if (this->ParentRenderer->GetRenderWindow())
200 this->ParentRenderer->GetRenderWindow()->RemoveRenderer(this->Renderer);
201 this->AxesActor->ReleaseGraphicsResources(this->ParentRenderer->GetRenderWindow());
203 if (this->StartEventObserverId != 0)
205 this->ParentRenderer->RemoveObserver(this->StartEventObserverId);
209 this->InvokeEvent(vtkCommand::DisableEvent, NULL);
213 //----------------------------------------------------------------------------
214 void vtkPVAxesWidget::ExecuteEvent(vtkObject *vtkNotUsed(o),
215 unsigned long vtkNotUsed(event),
216 void *vtkNotUsed(calldata))
218 if (!this->ParentRenderer)
223 vtkCamera *cam = this->ParentRenderer->GetActiveCamera();
224 double pos[3], fp[3], viewup[3];
225 cam->GetPosition(pos);
226 cam->GetFocalPoint(fp);
227 cam->GetViewUp(viewup);
229 cam = this->Renderer->GetActiveCamera();
230 cam->SetPosition(pos);
231 cam->SetFocalPoint(fp);
232 cam->SetViewUp(viewup);
233 this->Renderer->ResetCamera();
235 this->SquareRenderer();
238 void vtkPVAxesWidget::UpdateCursorIcon()
242 this->SetMouseCursor(vtkPVAxesWidget::Outside);
251 int *parentSize = this->ParentRenderer->GetSize();
253 int x = this->Interactor->GetEventPosition()[0];
254 int y = this->Interactor->GetEventPosition()[1];
255 double xNorm = x / (double)parentSize[0];
256 double yNorm = y / (double)parentSize[1];
259 this->Renderer->GetViewport(pos);
261 int pState = this->MouseCursorState;
263 if (xNorm > pos[0] && xNorm < pos[2] && yNorm > pos[1] && yNorm < pos[3])
265 this->MouseCursorState = vtkPVAxesWidget::Inside;
267 else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[3]) < .02)
269 this->MouseCursorState = vtkPVAxesWidget::TopLeft;
271 else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[3]) < .02)
273 this->MouseCursorState = vtkPVAxesWidget::TopRight;
275 else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[1]) < .02)
277 this->MouseCursorState = vtkPVAxesWidget::BottomLeft;
279 else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[1]) < .02)
281 this->MouseCursorState = vtkPVAxesWidget::BottomRight;
285 this->MouseCursorState = vtkPVAxesWidget::Outside;
288 if (pState == this->MouseCursorState)
293 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
295 this->Renderer->RemoveActor(this->OutlineActor);
299 this->Renderer->AddActor(this->OutlineActor);
301 this->Interactor->Render();
303 this->SetMouseCursor(this->MouseCursorState);
306 //----------------------------------------------------------------------------
307 void vtkPVAxesWidget::SetMouseCursor(int cursorState)
311 case vtkPVAxesWidget::Outside:
312 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_DEFAULT);
314 case vtkPVAxesWidget::Inside:
315 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZEALL);
317 case vtkPVAxesWidget::TopLeft:
318 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENW);
320 case vtkPVAxesWidget::TopRight:
321 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENE);
323 case vtkPVAxesWidget::BottomLeft:
324 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESW);
326 case vtkPVAxesWidget::BottomRight:
327 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESE);
332 //----------------------------------------------------------------------------
333 void vtkPVAxesWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
336 void* vtkNotUsed(calldata))
338 vtkPVAxesWidget *self =
339 reinterpret_cast<vtkPVAxesWidget*>(clientdata);
341 if (!self->GetInteractive())
348 case vtkCommand::LeftButtonPressEvent:
349 self->OnButtonPress();
351 case vtkCommand::MouseMoveEvent:
354 case vtkCommand::LeftButtonReleaseEvent:
355 self->OnButtonRelease();
360 //----------------------------------------------------------------------------
361 void vtkPVAxesWidget::OnButtonPress()
363 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
368 this->SetMouseCursor(this->MouseCursorState);
370 this->StartPosition[0] = this->Interactor->GetEventPosition()[0];
371 this->StartPosition[1] = this->Interactor->GetEventPosition()[1];
374 this->EventCallbackCommand->SetAbortFlag(1);
375 this->StartInteraction();
376 this->InvokeEvent(vtkCommand::StartInteractionEvent, NULL);
379 //----------------------------------------------------------------------------
380 void vtkPVAxesWidget::OnButtonRelease()
382 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
388 this->EndInteraction();
389 this->InvokeEvent(vtkCommand::EndInteractionEvent, NULL);
392 //----------------------------------------------------------------------------
393 void vtkPVAxesWidget::OnMouseMove()
397 switch (this->MouseCursorState)
399 case vtkPVAxesWidget::Inside:
402 case vtkPVAxesWidget::TopLeft:
403 this->ResizeTopLeft();
405 case vtkPVAxesWidget::TopRight:
406 this->ResizeTopRight();
408 case vtkPVAxesWidget::BottomLeft:
409 this->ResizeBottomLeft();
411 case vtkPVAxesWidget::BottomRight:
412 this->ResizeBottomRight();
416 this->UpdateCursorIcon();
417 this->EventCallbackCommand->SetAbortFlag(1);
418 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
422 this->UpdateCursorIcon();
426 //----------------------------------------------------------------------------
427 void vtkPVAxesWidget::MoveWidget()
429 int x = this->Interactor->GetEventPosition()[0];
430 int y = this->Interactor->GetEventPosition()[1];
432 int dx = x - this->StartPosition[0];
433 int dy = y - this->StartPosition[1];
435 this->StartPosition[0] = x;
436 this->StartPosition[1] = y;
438 int *size = this->ParentRenderer->GetSize();
439 double dxNorm = dx / (double)size[0];
440 double dyNorm = dy / (double)size[1];
442 double *vp = this->Renderer->GetViewport();
445 newPos[0] = vp[0] + dxNorm;
446 newPos[1] = vp[1] + dyNorm;
447 newPos[2] = vp[2] + dxNorm;
448 newPos[3] = vp[3] + dyNorm;
452 this->StartPosition[0] = 0;
454 newPos[2] = vp[2] - vp[0];
458 this->StartPosition[1] = 0;
460 newPos[3] = vp[3] - vp[1];
464 this->StartPosition[0] = (int)(size[0] - size[0] * (vp[2]-vp[0]));
465 newPos[0] = 1 - (vp[2]-vp[0]);
470 this->StartPosition[1] = (int)(size[1] - size[1]*(vp[3]-vp[1]));
471 newPos[1] = 1 - (vp[3]-vp[1]);
475 this->Renderer->SetViewport(newPos);
476 this->Interactor->Render();
479 //----------------------------------------------------------------------------
480 void vtkPVAxesWidget::ResizeTopLeft()
482 int x = this->Interactor->GetEventPosition()[0];
483 int y = this->Interactor->GetEventPosition()[1];
485 int dx = x - this->StartPosition[0];
486 int dy = y - this->StartPosition[1];
488 int *size = this->ParentRenderer->GetSize();
489 double dxNorm = dx / (double)size[0];
490 double dyNorm = dy / (double)size[1];
494 double absDx = fabs(dxNorm);
495 double absDy = fabs(dyNorm);
508 double *vp = this->Renderer->GetViewport();
510 this->StartPosition[0] = x;
511 this->StartPosition[1] = y;
514 newPos[0] = useX ? vp[0] + change : vp[0] - change;
517 newPos[3] = useX ? vp[3] - change : vp[3] + change;
521 this->StartPosition[0] = 0;
524 if (newPos[0] >= newPos[2]-0.01)
526 newPos[0] = newPos[2] - 0.01;
530 this->StartPosition[1] = size[1];
533 if (newPos[3] <= newPos[1]+0.01)
535 newPos[3] = newPos[1] + 0.01;
538 this->Renderer->SetViewport(newPos);
539 this->Interactor->Render();
542 //----------------------------------------------------------------------------
543 void vtkPVAxesWidget::ResizeTopRight()
545 int x = this->Interactor->GetEventPosition()[0];
546 int y = this->Interactor->GetEventPosition()[1];
548 int dx = x - this->StartPosition[0];
549 int dy = y - this->StartPosition[1];
551 int *size = this->ParentRenderer->GetSize();
552 double dxNorm = dx / (double)size[0];
553 double dyNorm = dy / (double)size[1];
556 double absDx = fabs(dxNorm);
557 double absDy = fabs(dyNorm);
568 double *vp = this->Renderer->GetViewport();
570 this->StartPosition[0] = x;
571 this->StartPosition[1] = y;
576 newPos[2] = vp[2] + change;
577 newPos[3] = vp[3] + change;
581 this->StartPosition[0] = size[0];
584 if (newPos[2] <= newPos[0]+0.01)
586 newPos[2] = newPos[0] + 0.01;
590 this->StartPosition[1] = size[1];
593 if (newPos[3] <= newPos[1]+0.01)
595 newPos[3] = newPos[1] + 0.01;
598 this->Renderer->SetViewport(newPos);
599 this->Interactor->Render();
602 //----------------------------------------------------------------------------
603 void vtkPVAxesWidget::ResizeBottomLeft()
605 int x = this->Interactor->GetEventPosition()[0];
606 int y = this->Interactor->GetEventPosition()[1];
608 int dx = x - this->StartPosition[0];
609 int dy = y - this->StartPosition[1];
611 int *size = this->ParentRenderer->GetSize();
612 double dxNorm = dx / (double)size[0];
613 double dyNorm = dy / (double)size[1];
614 double *vp = this->Renderer->GetViewport();
617 double absDx = fabs(dxNorm);
618 double absDy = fabs(dyNorm);
629 this->StartPosition[0] = x;
630 this->StartPosition[1] = y;
633 newPos[0] = vp[0] + change;
634 newPos[1] = vp[1] + change;
640 this->StartPosition[0] = 0;
643 if (newPos[0] >= newPos[2]-0.01)
645 newPos[0] = newPos[2] - 0.01;
649 this->StartPosition[1] = 0;
652 if (newPos[1] >= newPos[3]-0.01)
654 newPos[1] = newPos[3] - 0.01;
657 this->Renderer->SetViewport(newPos);
658 this->Interactor->Render();
661 //----------------------------------------------------------------------------
662 void vtkPVAxesWidget::ResizeBottomRight()
664 int x = this->Interactor->GetEventPosition()[0];
665 int y = this->Interactor->GetEventPosition()[1];
667 int dx = x - this->StartPosition[0];
668 int dy = y - this->StartPosition[1];
670 int *size = this->ParentRenderer->GetSize();
671 double dxNorm = dx / (double)size[0];
672 double dyNorm = dy / (double)size[1];
674 double *vp = this->Renderer->GetViewport();
678 double absDx = fabs(dxNorm);
679 double absDy = fabs(dyNorm);
692 this->StartPosition[0] = x;
693 this->StartPosition[1] = y;
697 newPos[1] = useX ? vp[1] - change : vp[1] + change;
698 newPos[2] = useX ? vp[2] + change : vp[2] - change;
703 this->StartPosition[0] = size[0];
706 if (newPos[2] <= newPos[0]+0.01)
708 newPos[2] = newPos[0] + 0.01;
712 this->StartPosition[1] = 0;
715 if (newPos[1] >= newPos[3]-0.01)
717 newPos[1] = newPos[3]-0.01;
720 this->Renderer->SetViewport(newPos);
721 this->Interactor->Render();
724 //----------------------------------------------------------------------------
725 void vtkPVAxesWidget::SquareRenderer()
727 int *size = this->Renderer->GetSize();
728 if (size[0] == 0 || size[1] == 0)
734 this->Renderer->GetViewport(vp);
736 double deltaX = vp[2] - vp[0];
737 double newDeltaX = size[1] * deltaX / (double)size[0];
738 double deltaY = vp[3] - vp[1];
739 double newDeltaY = size[0] * deltaY / (double)size[1];
745 if (size[0] > size[1])
747 newDeltaX = size[1] / (double)size[0];
753 newDeltaY = size[0] / (double)size[1];
761 vp[3] = vp[1] + newDeltaY;
765 vp[1] = vp[3] - newDeltaY;
771 vp[2] = vp[0] + newDeltaX;
775 vp[0] = vp[2] - newDeltaX;
779 this->Renderer->SetViewport(vp);
781 this->Renderer->NormalizedDisplayToDisplay(vp[0], vp[1]);
782 this->Renderer->NormalizedDisplayToDisplay(vp[2], vp[3]);
784 vtkPoints *points = this->Outline->GetPoints();
785 points->SetPoint(0, vp[0]+1, vp[1]+1, 0);
786 points->SetPoint(1, vp[2]-1, vp[1]+1, 0);
787 points->SetPoint(2, vp[2]-1, vp[3]-1, 0);
788 points->SetPoint(3, vp[0]+1, vp[3]-1, 0);
791 //----------------------------------------------------------------------------
792 void vtkPVAxesWidget::SetInteractive(int state)
794 if (this->Interactive != state)
796 this->Interactive = state;
801 this->OnButtonRelease();
802 this->MouseCursorState = vtkPVAxesWidget::Outside;
803 this->Renderer->RemoveActor(this->OutlineActor);
804 if (this->Interactor)
806 this->SetMouseCursor(this->MouseCursorState);
807 // this->Interactor->Render();
812 //----------------------------------------------------------------------------
813 void vtkPVAxesWidget::SetOutlineColor(double r, double g, double b)
815 this->OutlineActor->GetProperty()->SetColor(r, g, b);
816 if (this->Interactor)
818 // this->Interactor->Render();
822 //----------------------------------------------------------------------------
823 double* vtkPVAxesWidget::GetOutlineColor()
825 return this->OutlineActor->GetProperty()->GetColor();
828 //----------------------------------------------------------------------------
829 void vtkPVAxesWidget::SetAxisLabelColor(double r, double g, double b)
831 this->AxesActor->GetXAxisLabelProperty()->SetColor(r, g, b);
832 this->AxesActor->GetYAxisLabelProperty()->SetColor(r, g, b);
833 this->AxesActor->GetZAxisLabelProperty()->SetColor(r, g, b);
836 //----------------------------------------------------------------------------
837 double* vtkPVAxesWidget::GetAxisLabelColor()
839 return this->AxesActor->GetXAxisLabelProperty()->GetColor();
842 //----------------------------------------------------------------------------
843 vtkRenderer* vtkPVAxesWidget::GetParentRenderer()
845 return this->ParentRenderer;
848 //----------------------------------------------------------------------------
849 void vtkPVAxesWidget::SetViewport(double minX, double minY,
850 double maxX, double maxY)
852 this->Renderer->SetViewport(minX, minY, maxX, maxY);
855 //----------------------------------------------------------------------------
856 double* vtkPVAxesWidget::GetViewport()
858 return this->Renderer->GetViewport();
861 //----------------------------------------------------------------------------
862 void vtkPVAxesWidget::PrintSelf(ostream& os, vtkIndent indent)
864 this->Superclass::PrintSelf(os, indent);
866 os << indent << "AxesActor: " << this->AxesActor << endl;
867 os << indent << "Interactive: " << this->Interactive << endl;