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 // VSR 03/12/2014: the original file vtkPVAxesWidget.cxx has been renamed to salomevtkPVAxesWidget.cxx
33 // to avoid collisions with native VTK/ParaView classes
35 #include "salomevtkPVAxesWidget.h" // changed by SALOME
36 #include "salomevtkPVAxesActor.h" // changed by SALOME
38 #include "vtkActor2D.h"
39 #include "vtkCallbackCommand.h"
40 #include "vtkCamera.h"
41 #include "vtkCoordinate.h"
42 #include "vtkObjectFactory.h"
43 #include "vtkPoints.h"
44 #include "vtkPolyData.h"
45 #include "vtkPolyDataMapper2D.h"
46 #include "vtkProperty.h"
47 #include "vtkProperty2D.h"
48 #include "vtkRenderer.h"
49 #include "vtkRenderWindow.h"
50 #include "vtkRenderWindowInteractor.h"
52 // VSR 03/12/2014: we put classes copied from VTK/ParaView to the specific namespace
53 // to avoid collisions with native VTK/ParaView classes
57 vtkStandardNewMacro(vtkPVAxesWidget);
59 vtkCxxSetObjectMacro(vtkPVAxesWidget, AxesActor, vtkPVAxesActor);
60 vtkCxxSetObjectMacro(vtkPVAxesWidget, ParentRenderer, vtkRenderer);
62 //----------------------------------------------------------------------------
63 class vtkPVAxesWidgetObserver : public vtkCommand
66 static vtkPVAxesWidgetObserver *New()
67 {return new vtkPVAxesWidgetObserver;};
69 vtkPVAxesWidgetObserver()
74 virtual void Execute(vtkObject* wdg, unsigned long event, void *calldata)
78 this->AxesWidget->ExecuteEvent(wdg, event, calldata);
82 vtkPVAxesWidget *AxesWidget;
85 //----------------------------------------------------------------------------
86 vtkPVAxesWidget::vtkPVAxesWidget()
88 this->StartEventObserverId = 0;
90 this->EventCallbackCommand->SetCallback(vtkPVAxesWidget::ProcessEvents);
92 this->Observer = vtkPVAxesWidgetObserver::New();
93 this->Observer->AxesWidget = this;
94 this->Renderer = vtkRenderer::New();
95 this->Renderer->SetViewport(0.0, 0.0, 0.2, 0.2);
96 this->Renderer->SetLayer(1);
97 this->Renderer->InteractiveOff();
98 this->Priority = 0.55;
99 this->AxesActor = vtkPVAxesActor::New();
100 this->Renderer->AddActor(this->AxesActor);
101 this->AxesActor->AddToRender(this->Renderer); // tmp
103 this->ParentRenderer = NULL;
106 this->MouseCursorState = vtkPVAxesWidget::Outside;
110 this->Interactive = 1;
112 this->Outline = vtkPolyData::New();
113 this->Outline->Allocate();
114 vtkPoints *points = vtkPoints::New();
116 ptIds[4] = ptIds[0] = points->InsertNextPoint(1, 1, 0);
117 ptIds[1] = points->InsertNextPoint(2, 1, 0);
118 ptIds[2] = points->InsertNextPoint(2, 2, 0);
119 ptIds[3] = points->InsertNextPoint(1, 2, 0);
120 this->Outline->SetPoints(points);
121 this->Outline->InsertNextCell(VTK_POLY_LINE, 5, ptIds);
122 vtkCoordinate *tcoord = vtkCoordinate::New();
123 tcoord->SetCoordinateSystemToDisplay();
124 vtkPolyDataMapper2D *mapper = vtkPolyDataMapper2D::New();
125 mapper->SetInputData(this->Outline);
126 mapper->SetTransformCoordinate(tcoord);
127 this->OutlineActor = vtkActor2D::New();
128 this->OutlineActor->SetMapper(mapper);
129 this->OutlineActor->SetPosition(0, 0);
130 this->OutlineActor->SetPosition2(1, 1);
137 //----------------------------------------------------------------------------
138 vtkPVAxesWidget::~vtkPVAxesWidget()
140 this->Observer->Delete();
141 this->AxesActor->Delete();
142 this->OutlineActor->Delete();
143 this->Outline->Delete();
144 this->SetParentRenderer(NULL);
145 this->Renderer->Delete();
148 //----------------------------------------------------------------------------
149 void vtkPVAxesWidget::SetEnabled(int enabling)
151 if (!this->Interactor)
153 vtkErrorMacro("The interactor must be set prior to enabling/disabling widget");
162 if (!this->ParentRenderer)
164 vtkErrorMacro("The parent renderer must be set prior to enabling this widget");
170 if ( this->EventCallbackCommand )
172 vtkRenderWindowInteractor *i = this->Interactor;
173 i->AddObserver(vtkCommand::MouseMoveEvent,
174 this->EventCallbackCommand, this->Priority);
175 i->AddObserver(vtkCommand::LeftButtonPressEvent,
176 this->EventCallbackCommand, this->Priority);
177 i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
178 this->EventCallbackCommand, this->Priority);
181 this->ParentRenderer->GetRenderWindow()->AddRenderer(this->Renderer);
182 if (this->ParentRenderer->GetRenderWindow()->GetNumberOfLayers() < 2)
184 this->ParentRenderer->GetRenderWindow()->SetNumberOfLayers(2);
186 this->AxesActor->SetVisibility(1);
187 // We need to copy the camera before the compositing observer is called.
188 // Compositing temporarily changes the camera to display an image.
189 this->StartEventObserverId =
190 this->ParentRenderer->AddObserver(vtkCommand::StartEvent,this->Observer,1);
191 this->InvokeEvent(vtkCommand::EnableEvent, NULL);
201 this->Interactor->RemoveObserver(this->EventCallbackCommand);
203 this->AxesActor->SetVisibility(0);
204 if (this->ParentRenderer)
206 if (this->ParentRenderer->GetRenderWindow())
208 this->ParentRenderer->GetRenderWindow()->RemoveRenderer(this->Renderer);
209 this->AxesActor->ReleaseGraphicsResources(this->ParentRenderer->GetRenderWindow());
211 if (this->StartEventObserverId != 0)
213 this->ParentRenderer->RemoveObserver(this->StartEventObserverId);
217 this->InvokeEvent(vtkCommand::DisableEvent, NULL);
221 //----------------------------------------------------------------------------
222 void vtkPVAxesWidget::ExecuteEvent(vtkObject *vtkNotUsed(o),
223 unsigned long vtkNotUsed(event),
224 void *vtkNotUsed(calldata))
226 if (!this->ParentRenderer)
231 vtkCamera *cam = this->ParentRenderer->GetActiveCamera();
232 double pos[3], fp[3], viewup[3];
233 cam->GetPosition(pos);
234 cam->GetFocalPoint(fp);
235 cam->GetViewUp(viewup);
237 cam = this->Renderer->GetActiveCamera();
238 cam->SetPosition(pos);
239 cam->SetFocalPoint(fp);
240 cam->SetViewUp(viewup);
241 this->Renderer->ResetCamera();
243 this->SquareRenderer();
246 void vtkPVAxesWidget::UpdateCursorIcon()
250 this->SetMouseCursor(vtkPVAxesWidget::Outside);
259 int *parentSize = this->ParentRenderer->GetSize();
261 int x = this->Interactor->GetEventPosition()[0];
262 int y = this->Interactor->GetEventPosition()[1];
263 double xNorm = x / (double)parentSize[0];
264 double yNorm = y / (double)parentSize[1];
267 this->Renderer->GetViewport(pos);
269 int pState = this->MouseCursorState;
271 if (xNorm > pos[0] && xNorm < pos[2] && yNorm > pos[1] && yNorm < pos[3])
273 this->MouseCursorState = vtkPVAxesWidget::Inside;
275 else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[3]) < .02)
277 this->MouseCursorState = vtkPVAxesWidget::TopLeft;
279 else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[3]) < .02)
281 this->MouseCursorState = vtkPVAxesWidget::TopRight;
283 else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[1]) < .02)
285 this->MouseCursorState = vtkPVAxesWidget::BottomLeft;
287 else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[1]) < .02)
289 this->MouseCursorState = vtkPVAxesWidget::BottomRight;
293 this->MouseCursorState = vtkPVAxesWidget::Outside;
296 if (pState == this->MouseCursorState)
301 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
303 this->Renderer->RemoveActor(this->OutlineActor);
307 this->Renderer->AddActor(this->OutlineActor);
309 this->Interactor->Render();
311 this->SetMouseCursor(this->MouseCursorState);
314 //----------------------------------------------------------------------------
315 void vtkPVAxesWidget::SetMouseCursor(int cursorState)
319 case vtkPVAxesWidget::Outside:
320 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_DEFAULT);
322 case vtkPVAxesWidget::Inside:
323 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZEALL);
325 case vtkPVAxesWidget::TopLeft:
326 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENW);
328 case vtkPVAxesWidget::TopRight:
329 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENE);
331 case vtkPVAxesWidget::BottomLeft:
332 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESW);
334 case vtkPVAxesWidget::BottomRight:
335 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESE);
340 //----------------------------------------------------------------------------
341 void vtkPVAxesWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
344 void* vtkNotUsed(calldata))
346 vtkPVAxesWidget *self =
347 reinterpret_cast<vtkPVAxesWidget*>(clientdata);
349 if (!self->GetInteractive())
356 case vtkCommand::LeftButtonPressEvent:
357 self->OnButtonPress();
359 case vtkCommand::MouseMoveEvent:
362 case vtkCommand::LeftButtonReleaseEvent:
363 self->OnButtonRelease();
368 //----------------------------------------------------------------------------
369 void vtkPVAxesWidget::OnButtonPress()
371 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
376 this->SetMouseCursor(this->MouseCursorState);
378 this->StartPosition[0] = this->Interactor->GetEventPosition()[0];
379 this->StartPosition[1] = this->Interactor->GetEventPosition()[1];
382 this->EventCallbackCommand->SetAbortFlag(1);
383 this->StartInteraction();
384 this->InvokeEvent(vtkCommand::StartInteractionEvent, NULL);
387 //----------------------------------------------------------------------------
388 void vtkPVAxesWidget::OnButtonRelease()
390 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
396 this->EndInteraction();
397 this->InvokeEvent(vtkCommand::EndInteractionEvent, NULL);
400 //----------------------------------------------------------------------------
401 void vtkPVAxesWidget::OnMouseMove()
405 switch (this->MouseCursorState)
407 case vtkPVAxesWidget::Inside:
410 case vtkPVAxesWidget::TopLeft:
411 this->ResizeTopLeft();
413 case vtkPVAxesWidget::TopRight:
414 this->ResizeTopRight();
416 case vtkPVAxesWidget::BottomLeft:
417 this->ResizeBottomLeft();
419 case vtkPVAxesWidget::BottomRight:
420 this->ResizeBottomRight();
424 this->UpdateCursorIcon();
425 this->EventCallbackCommand->SetAbortFlag(1);
426 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
430 this->UpdateCursorIcon();
434 //----------------------------------------------------------------------------
435 void vtkPVAxesWidget::MoveWidget()
437 int x = this->Interactor->GetEventPosition()[0];
438 int y = this->Interactor->GetEventPosition()[1];
440 int dx = x - this->StartPosition[0];
441 int dy = y - this->StartPosition[1];
443 this->StartPosition[0] = x;
444 this->StartPosition[1] = y;
446 int *size = this->ParentRenderer->GetSize();
447 double dxNorm = dx / (double)size[0];
448 double dyNorm = dy / (double)size[1];
450 double *vp = this->Renderer->GetViewport();
453 newPos[0] = vp[0] + dxNorm;
454 newPos[1] = vp[1] + dyNorm;
455 newPos[2] = vp[2] + dxNorm;
456 newPos[3] = vp[3] + dyNorm;
460 this->StartPosition[0] = 0;
462 newPos[2] = vp[2] - vp[0];
466 this->StartPosition[1] = 0;
468 newPos[3] = vp[3] - vp[1];
472 this->StartPosition[0] = (int)(size[0] - size[0] * (vp[2]-vp[0]));
473 newPos[0] = 1 - (vp[2]-vp[0]);
478 this->StartPosition[1] = (int)(size[1] - size[1]*(vp[3]-vp[1]));
479 newPos[1] = 1 - (vp[3]-vp[1]);
483 this->Renderer->SetViewport(newPos);
484 this->Interactor->Render();
487 //----------------------------------------------------------------------------
488 void vtkPVAxesWidget::ResizeTopLeft()
490 int x = this->Interactor->GetEventPosition()[0];
491 int y = this->Interactor->GetEventPosition()[1];
493 int dx = x - this->StartPosition[0];
494 int dy = y - this->StartPosition[1];
496 int *size = this->ParentRenderer->GetSize();
497 double dxNorm = dx / (double)size[0];
498 double dyNorm = dy / (double)size[1];
502 double absDx = fabs(dxNorm);
503 double absDy = fabs(dyNorm);
516 double *vp = this->Renderer->GetViewport();
518 this->StartPosition[0] = x;
519 this->StartPosition[1] = y;
522 newPos[0] = useX ? vp[0] + change : vp[0] - change;
525 newPos[3] = useX ? vp[3] - change : vp[3] + change;
529 this->StartPosition[0] = 0;
532 if (newPos[0] >= newPos[2]-0.01)
534 newPos[0] = newPos[2] - 0.01;
538 this->StartPosition[1] = size[1];
541 if (newPos[3] <= newPos[1]+0.01)
543 newPos[3] = newPos[1] + 0.01;
546 this->Renderer->SetViewport(newPos);
547 this->Interactor->Render();
550 //----------------------------------------------------------------------------
551 void vtkPVAxesWidget::ResizeTopRight()
553 int x = this->Interactor->GetEventPosition()[0];
554 int y = this->Interactor->GetEventPosition()[1];
556 int dx = x - this->StartPosition[0];
557 int dy = y - this->StartPosition[1];
559 int *size = this->ParentRenderer->GetSize();
560 double dxNorm = dx / (double)size[0];
561 double dyNorm = dy / (double)size[1];
564 double absDx = fabs(dxNorm);
565 double absDy = fabs(dyNorm);
576 double *vp = this->Renderer->GetViewport();
578 this->StartPosition[0] = x;
579 this->StartPosition[1] = y;
584 newPos[2] = vp[2] + change;
585 newPos[3] = vp[3] + change;
589 this->StartPosition[0] = size[0];
592 if (newPos[2] <= newPos[0]+0.01)
594 newPos[2] = newPos[0] + 0.01;
598 this->StartPosition[1] = size[1];
601 if (newPos[3] <= newPos[1]+0.01)
603 newPos[3] = newPos[1] + 0.01;
606 this->Renderer->SetViewport(newPos);
607 this->Interactor->Render();
610 //----------------------------------------------------------------------------
611 void vtkPVAxesWidget::ResizeBottomLeft()
613 int x = this->Interactor->GetEventPosition()[0];
614 int y = this->Interactor->GetEventPosition()[1];
616 int dx = x - this->StartPosition[0];
617 int dy = y - this->StartPosition[1];
619 int *size = this->ParentRenderer->GetSize();
620 double dxNorm = dx / (double)size[0];
621 double dyNorm = dy / (double)size[1];
622 double *vp = this->Renderer->GetViewport();
625 double absDx = fabs(dxNorm);
626 double absDy = fabs(dyNorm);
637 this->StartPosition[0] = x;
638 this->StartPosition[1] = y;
641 newPos[0] = vp[0] + change;
642 newPos[1] = vp[1] + change;
648 this->StartPosition[0] = 0;
651 if (newPos[0] >= newPos[2]-0.01)
653 newPos[0] = newPos[2] - 0.01;
657 this->StartPosition[1] = 0;
660 if (newPos[1] >= newPos[3]-0.01)
662 newPos[1] = newPos[3] - 0.01;
665 this->Renderer->SetViewport(newPos);
666 this->Interactor->Render();
669 //----------------------------------------------------------------------------
670 void vtkPVAxesWidget::ResizeBottomRight()
672 int x = this->Interactor->GetEventPosition()[0];
673 int y = this->Interactor->GetEventPosition()[1];
675 int dx = x - this->StartPosition[0];
676 int dy = y - this->StartPosition[1];
678 int *size = this->ParentRenderer->GetSize();
679 double dxNorm = dx / (double)size[0];
680 double dyNorm = dy / (double)size[1];
682 double *vp = this->Renderer->GetViewport();
686 double absDx = fabs(dxNorm);
687 double absDy = fabs(dyNorm);
700 this->StartPosition[0] = x;
701 this->StartPosition[1] = y;
705 newPos[1] = useX ? vp[1] - change : vp[1] + change;
706 newPos[2] = useX ? vp[2] + change : vp[2] - change;
711 this->StartPosition[0] = size[0];
714 if (newPos[2] <= newPos[0]+0.01)
716 newPos[2] = newPos[0] + 0.01;
720 this->StartPosition[1] = 0;
723 if (newPos[1] >= newPos[3]-0.01)
725 newPos[1] = newPos[3]-0.01;
728 this->Renderer->SetViewport(newPos);
729 this->Interactor->Render();
732 //----------------------------------------------------------------------------
733 void vtkPVAxesWidget::SquareRenderer()
735 int *size = this->Renderer->GetSize();
736 if (size[0] == 0 || size[1] == 0)
742 this->Renderer->GetViewport(vp);
744 double deltaX = vp[2] - vp[0];
745 double newDeltaX = size[1] * deltaX / (double)size[0];
746 double deltaY = vp[3] - vp[1];
747 double newDeltaY = size[0] * deltaY / (double)size[1];
753 if (size[0] > size[1])
755 newDeltaX = size[1] / (double)size[0];
761 newDeltaY = size[0] / (double)size[1];
769 vp[3] = vp[1] + newDeltaY;
773 vp[1] = vp[3] - newDeltaY;
779 vp[2] = vp[0] + newDeltaX;
783 vp[0] = vp[2] - newDeltaX;
787 this->Renderer->SetViewport(vp);
789 this->Renderer->NormalizedDisplayToDisplay(vp[0], vp[1]);
790 this->Renderer->NormalizedDisplayToDisplay(vp[2], vp[3]);
792 vtkPoints *points = this->Outline->GetPoints();
793 points->SetPoint(0, vp[0]+1, vp[1]+1, 0);
794 points->SetPoint(1, vp[2]-1, vp[1]+1, 0);
795 points->SetPoint(2, vp[2]-1, vp[3]-1, 0);
796 points->SetPoint(3, vp[0]+1, vp[3]-1, 0);
799 //----------------------------------------------------------------------------
800 void vtkPVAxesWidget::SetInteractive(int state)
802 if (this->Interactive != state)
804 this->Interactive = state;
809 this->OnButtonRelease();
810 this->MouseCursorState = vtkPVAxesWidget::Outside;
811 this->Renderer->RemoveActor(this->OutlineActor);
812 if (this->Interactor)
814 this->SetMouseCursor(this->MouseCursorState);
815 // this->Interactor->Render();
820 //----------------------------------------------------------------------------
821 void vtkPVAxesWidget::SetOutlineColor(double r, double g, double b)
823 this->OutlineActor->GetProperty()->SetColor(r, g, b);
824 if (this->Interactor)
826 // this->Interactor->Render();
830 //----------------------------------------------------------------------------
831 double* vtkPVAxesWidget::GetOutlineColor()
833 return this->OutlineActor->GetProperty()->GetColor();
836 //----------------------------------------------------------------------------
837 void vtkPVAxesWidget::SetAxisLabelColor(double r, double g, double b)
839 this->AxesActor->GetXAxisLabelProperty()->SetColor(r, g, b);
840 this->AxesActor->GetYAxisLabelProperty()->SetColor(r, g, b);
841 this->AxesActor->GetZAxisLabelProperty()->SetColor(r, g, b);
844 //----------------------------------------------------------------------------
845 double* vtkPVAxesWidget::GetAxisLabelColor()
847 return this->AxesActor->GetXAxisLabelProperty()->GetColor();
850 //----------------------------------------------------------------------------
851 vtkRenderer* vtkPVAxesWidget::GetParentRenderer()
853 return this->ParentRenderer;
856 //----------------------------------------------------------------------------
857 void vtkPVAxesWidget::SetViewport(double minX, double minY,
858 double maxX, double maxY)
860 this->Renderer->SetViewport(minX, minY, maxX, maxY);
863 //----------------------------------------------------------------------------
864 double* vtkPVAxesWidget::GetViewport()
866 return this->Renderer->GetViewport();
869 //----------------------------------------------------------------------------
870 void vtkPVAxesWidget::PrintSelf(ostream& os, vtkIndent indent)
872 this->Superclass::PrintSelf(os, indent);
874 os << indent << "AxesActor: " << this->AxesActor << endl;
875 os << indent << "Interactive: " << this->Interactive << endl;
878 } // end of salomevtk namespace