0030520: VIS - IVtkTools_ShapePicker::GetPickPosition() returns incorrect point
[occt.git] / src / IVtkDraw / IVtkDraw.cxx
CommitLineData
52f99d93 1// Created on: 2012-02-03
2//
3// Copyright (c) 2012-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16
17#ifdef NOMINMAX
18#undef NOMINMAX /* avoid #define min() and max() */
19#endif
20#ifdef NOMSG
21#undef NOMSG /* avoid #define SendMessage etc. */
22#endif
23#ifdef NODRAWTEXT
24#undef NODRAWTEXT /* avoid #define DrawText etc. */
25#endif
26#ifdef NONLS
27#undef NONLS /* avoid #define CompareString etc. */
28#endif
29#ifdef NOGDI
30#undef NOGDI /* avoid #define SetPrinter (winspool.h) etc. */
31#endif
32#ifdef NOSERVICE
33#undef NOSERVICE
34#endif
35#ifdef NOKERNEL
36#undef NOKERNEL
37#endif
38#ifdef NOUSER
39#undef NOUSER
40#endif
41#ifdef NOMCX
42#undef NOMCX
43#endif
44#ifdef NOIME
45#undef NOIME
46#endif
47
48#include <stdio.h>
49#ifdef HAVE_STRINGS_H
50# include <strings.h>
51#endif
52
53#ifdef _WIN32
52f99d93 54#include <windows.h>
55#include <WNT_WClass.hxx>
56#include <WNT_Window.hxx>
57#endif
58
59#include <Draw.hxx>
60#include <Draw_Interpretor.hxx>
61#include <Draw_PluginMacro.hxx>
62#include <TCollection_AsciiString.hxx>
63#include <TopoDS_Shape.hxx>
64#include <BRep_Builder.hxx>
65#include <BRepTools.hxx>
66#include <DBRep.hxx>
67#include <NCollection_DoubleMap.hxx>
68#include <NCollection_List.hxx>
69#include <NCollection_DataMap.hxx>
70#include <TopTools_DataMapOfIntegerShape.hxx>
71#include <OpenGl_GraphicDriver.hxx>
72#include <Aspect_DisplayConnection.hxx>
73
74#include <IVtk_Types.hxx>
75#include <IVtkVTK_ShapeData.hxx>
76#include <IVtkOCC_Shape.hxx>
77#include <IVtkOCC_ShapeMesher.hxx>
78#include <IVtkTools_ShapeDataSource.hxx>
79#include <IVtkTools_ShapeObject.hxx>
80#include <IVtkTools_SubPolyDataFilter.hxx>
81#include <IVtkTools_DisplayModeFilter.hxx>
82#include <IVtkTools_ShapePicker.hxx>
83
84#include <IVtkDraw.hxx>
85#include <IVtkDraw_HighlightAndSelectionPipeline.hxx>
86#include <IVtkDraw_Interactor.hxx>
87
a9660929 88// prevent disabling some MSVC warning messages by VTK headers
89#ifdef _MSC_VER
90#pragma warning(push)
91#pragma warning(disable: 4244)
92#endif
52f99d93 93#include <vtkAlgorithmOutput.h>
94#include <vtkAppendPolyData.h>
95#include <vtkBMPWriter.h>
96#include <vtkCamera.h>
97#include <vtkCellData.h>
98#include <vtkCommand.h>
99#include <vtkGeometryFilter.h>
100#include <vtkIdTypeArray.h>
101#include <vtkImageResize.h>
102#include <vtkImageWriter.h>
103#include <vtkInteractorStyleTrackballCamera.h>
104#include <vtkJPEGWriter.h>
105#include <vtkPNGWriter.h>
106#include <vtkPNMWriter.h>
107#include <vtkPolyDataMapper.h>
108#include <vtkProperty.h>
109#include <vtkRenderWindow.h>
110#include <vtkRenderer.h>
111#include <vtkRenderWindowInteractor.h>
112#include <vtkSmartPointer.h>
113#include <vtkTIFFWriter.h>
114#include <vtkWindowToImageFilter.h>
52f99d93 115#ifndef _WIN32
116#include <X11/X.h>
117#include <X11/Shell.h>
118#include <X11/Xlib.h>
119#include <GL/glx.h>
120#include <Xw_Window.hxx>
121#include <vtkXRenderWindowInteractor.h>
122#include <vtkXOpenGLRenderWindow.h>
123#include <X11/Xutil.h>
124#include <tk.h>
125#endif
a9660929 126#ifdef _MSC_VER
127#pragma warning(pop)
128#endif
52f99d93 129
130// workaround name conflicts with OCCT methods (in class TopoDS_Shape for example)
131#ifdef Convex
132 #undef Convex
133#endif
134#ifdef Status
135 #undef Status
136#endif
137
138//================================================================
139// TYPE DEFINITIONS
140//================================================================
141
142typedef NCollection_DoubleMap<TopoDS_Shape, TCollection_AsciiString> DoubleMapOfShapesAndNames;
143typedef NCollection_DoubleMap<vtkSmartPointer<vtkActor>, TCollection_AsciiString> DoubleMapOfActorsAndNames;
144
145typedef IVtkDraw_HighlightAndSelectionPipeline PipelinePtr;
52f99d93 146
147//================================================================
148// GLOBAL VARIABLES
149//================================================================
150
151Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
152
153static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
154{
155 static Handle(Aspect_DisplayConnection) aDisplayConnection;
156 return aDisplayConnection;
157}
158
159static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
160{
161 GetDisplayConnection() = theDisplayConnection;
162}
163
164static DoubleMapOfShapesAndNames& GetMapOfShapes()
165{
166 static DoubleMapOfShapesAndNames aMap;
167 return aMap;
168}
169
170static DoubleMapOfActorsAndNames& GetMapOfActors()
171{
172 static DoubleMapOfActorsAndNames aMap;
173 return aMap;
174}
175
176static vtkSmartPointer<vtkRenderer>& GetRenderer()
177{
178 static vtkSmartPointer<vtkRenderer> aRenderer;
179 return aRenderer;
180}
181
182static Handle(ShapePipelineMap)& GetPipelines()
183{
184 static Handle(ShapePipelineMap) aPLMap;
185 if (aPLMap.IsNull())
186 {
187 aPLMap = new ShapePipelineMap();
188 }
189
190 return aPLMap;
191}
192
193static Handle(PipelinePtr) GetPipeline (const IVtk_IdType& theShapeID)
194{
195 Handle(PipelinePtr) aPtr;
196 GetPipelines()->Find (theShapeID, aPtr);
197 return aPtr;
198}
199
200//! Get VTK render pipeline with shape ID got from actor.
201static Handle(PipelinePtr) PipelineByActor (const vtkSmartPointer<vtkActor>& theActor)
202{
203 IVtk_IdType aShapeID = IVtkTools_ShapeObject::GetShapeSource (theActor)->GetShape()->GetId();
204 return GetPipeline (aShapeID);
205}
206
207//! Get VTK render pipeline with actor that has the input name.
208static Handle(PipelinePtr) PipelineByActorName (const TCollection_AsciiString& theName)
209{
210 const vtkSmartPointer<vtkActor>& anActor = GetMapOfActors().Find2 (theName);
211 return PipelineByActor (anActor);
212}
213
52f99d93 214#ifdef _WIN32
215
216static Handle(WNT_Window)& GetWindow()
217{
218 static Handle(WNT_Window) aWindow;
219 return aWindow;
220}
221
222#else
223
224static Handle(Xw_Window)& GetWindow()
225{
226 static Handle(Xw_Window) aXWWin;
227 return aXWWin;
228}
229
230#endif
231
232static vtkSmartPointer<IVtkDraw_Interactor>& GetInteractor()
233{
234 static vtkSmartPointer<IVtkDraw_Interactor> anInteractor;
235 return anInteractor;
236}
237
238static vtkSmartPointer<IVtkTools_ShapePicker>& GetPicker()
239{
240 static vtkSmartPointer<IVtkTools_ShapePicker> aPicker;
241 return aPicker;
242}
243
244//! Generate identical number for shape
245Standard_Integer GenerateId()
246{
247 static unsigned int aShapesCounter = (unsigned int )-1;
248 return (Standard_Integer )++aShapesCounter;
249}
250
251//=========================================================
252// Function : WClass
253// Purpose :
254//=========================================================
ad03c234 255const Handle(Standard_Transient)& IVtkDraw::WClass()
52f99d93 256{
ad03c234 257 static Handle(Standard_Transient) aWindowClass;
bd6c4619 258#ifdef _WIN32
52f99d93 259 if (aWindowClass.IsNull())
260 {
261 aWindowClass = new WNT_WClass ("GWVTK_Class", DefWindowProc,
262 CS_VREDRAW | CS_HREDRAW, 0, 0,
ad03c234 263 ::LoadCursorW (NULL, IDC_ARROW));
52f99d93 264 }
265#endif
266 return aWindowClass;
267}
268
269//==============================================================
270// Function : ViewerInit
271// Purpose :
272//==============================================================
273void IVtkDraw::ViewerInit (Standard_Integer thePxLeft,
274 Standard_Integer thePxTop,
275 Standard_Integer thePxWidth,
276 Standard_Integer thePxHeight)
277{
278 static Standard_Boolean isFirst = Standard_True;
279
280 Standard_Integer aPxLeft = 0;
281 Standard_Integer aPxTop = 460;
282 Standard_Integer aPxWidth = 409;
283 Standard_Integer aPxHeight = 409;
284
285 if (thePxLeft != 0)
286 {
287 aPxLeft = thePxLeft;
288 }
289 if (thePxTop != 0)
290 {
291 aPxTop = thePxTop;
292 }
293 if (thePxWidth != 0)
294 {
295 aPxWidth = thePxWidth;
296 }
297 if (thePxHeight != 0)
298 {
299 aPxHeight = thePxHeight;
300 }
301
302 if (isFirst)
303 {
304 SetDisplayConnection (new Aspect_DisplayConnection ());
bd6c4619 305#ifdef _WIN32
52f99d93 306 if (GetWindow().IsNull())
307 {
308 GetWindow() = new WNT_Window ("IVtkTest",
309 Handle(WNT_WClass)::DownCast (WClass()),
310 WS_OVERLAPPEDWINDOW,
311 aPxLeft, aPxTop,
312 aPxWidth, aPxHeight,
313 Quantity_NOC_BLACK);
314 GetWindow()->SetVirtual (Draw_VirtualWindows);
315 }
316#else
317
318 if (GetWindow().IsNull())
319 {
320 GetWindow() = new Xw_Window (GetDisplayConnection(),
321 "IVtkTest",
322 aPxLeft, aPxTop,
323 aPxWidth, aPxHeight);
324 GetWindow()->SetVirtual (Draw_VirtualWindows);
325 }
326#endif
327 // Init pipeline
328 GetRenderer() = vtkSmartPointer<vtkRenderer>::New();
329
330 vtkSmartPointer<vtkRenderWindow> aRenWin = vtkSmartPointer<vtkRenderWindow>::New();
331 aRenWin->AddRenderer (GetRenderer());
332 GetRenderer()->GetActiveCamera()->ParallelProjectionOn();
333 aRenWin->SetSize (aPxWidth, aPxHeight);
334
bd6c4619 335#ifdef _WIN32
52f99d93 336 aRenWin->SetWindowId((void*)GetWindow()->HWindow());
337#else
338 Window aWindowId = GetWindow()->XWindow();
339 aRenWin->SetWindowId ((void*)aWindowId);
340 Display *aDisplayId = GetDisplayConnection()->GetDisplay();
341 aRenWin->SetDisplayId (aDisplayId);
342
343 // Setup XWindow
344 XSynchronize (aDisplayId, 1);
345 GetWindow()->Map();
346
347 // X11 : For keyboard on SUN
348 XWMHints wmhints;
349 wmhints.flags = InputHint;
350 wmhints.input = 1;
351
352 XSetWMHints (aDisplayId, aWindowId, &wmhints);
353
354 XSelectInput (aDisplayId, aWindowId, ExposureMask | KeyPressMask |
355 ButtonPressMask | ButtonReleaseMask |
356 StructureNotifyMask |
357 PointerMotionMask |
358 Button1MotionMask | Button2MotionMask |
359 Button3MotionMask
360 );
361
362 XSynchronize (aDisplayId, 0);
363
364#endif
365
366 // Init interactor
367 GetInteractor() = vtkSmartPointer<IVtkDraw_Interactor>::New();
368 GetInteractor()->SetRenderWindow (aRenWin);
369 GetInteractor()->SetOCCWindow (GetWindow());
370
371 vtkSmartPointer<vtkInteractorStyleTrackballCamera>
372 aStyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
373 GetInteractor()->SetInteractorStyle (aStyle);
374
375 // Init picker
376 GetPicker() = vtkSmartPointer<IVtkTools_ShapePicker>::New();
896faa72 377 GetPicker()->SetTolerance (0.025f);
52f99d93 378 GetPicker()->SetRenderer (GetRenderer());
379
380 GetInteractor()->SetShapePicker (GetPicker());
381 GetInteractor()->SetPipelines (GetPipelines());
382 GetInteractor()->Initialize();
383
384 aRenWin->SetOffScreenRendering(Draw_VirtualWindows);
385 aRenWin->Render();
386
387 isFirst = Standard_False;
388 }
389
390 GetWindow()->Map();
391}
392
393//================================================================
394// Function : VtkInit
395// Purpose :
396//================================================================
397static Standard_Integer VtkInit (Draw_Interpretor& ,
398 Standard_Integer theArgNum,
399 const char** theArgs)
400{
401 Standard_Integer aPxLeft = (theArgNum > 1) ? atoi(theArgs[1]) : 0;
402 Standard_Integer aPxTop = (theArgNum > 2) ? atoi(theArgs[2]) : 0;
403 Standard_Integer aPxWidth = (theArgNum > 3) ? atoi(theArgs[3]) : 0;
404 Standard_Integer aPxHeight = (theArgNum > 4) ? atoi(theArgs[4]) : 0;
405
406 IVtkDraw::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight);
407 return 0;
408}
409
410
411//================================================================
412// Function : CreateActor
413// Purpose :
414//================================================================
415vtkActor* CreateActor (const Standard_Integer theId,
416 const TopoDS_Shape& theShape)
417{
418 if ( theShape.IsNull() )
419 {
420 return NULL;
421 }
422
423 Handle(PipelinePtr) aPL = new PipelinePtr (theShape, theId);
424 GetPipelines()->Bind (theId, aPL);
425
426 return aPL->Actor();
427}
428
429//================================================================
430// Function : VtkDisplay
431// Purpose :
432//================================================================
433
434static Standard_Integer VtkDisplay (Draw_Interpretor& theDI,
435 Standard_Integer theArgNum,
436 const char** theArgs)
437{
438 // Check viewer
439 if (!GetInteractor()->IsEnabled())
440 {
441 theDI << theArgs[0] << " error : call ivtkinit before\n";
442 return 1; // TCL_ERROR
443 }
444
445 // Check arguments
446 if (theArgNum < 2)
447 {
448 theDI << theArgs[0] << " error : expects at least 1 argument\n";
449 return 1; // TCL_ERROR
450 }
451
452 TCollection_AsciiString aName;
453 TopoDS_Shape anOldShape, aNewShape;
a2f76b15 454 vtkSmartPointer<vtkRenderer>& aRenderer = GetRenderer();
52f99d93 455 for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
456 {
457 // Get name of shape
458 aName = theArgs[anIndex];
459 // Get shape from DRAW
460 aNewShape = DBRep::Get (theArgs[anIndex]);
461
462 // The shape is already in the map
463 if (GetMapOfShapes().IsBound2 (aName))
464 {
465 // Get shape from map
466 anOldShape = GetMapOfShapes().Find2 (aName);
467 // Equal shapes
468 if (anOldShape.IsEqual (aNewShape))
469 {
470 // Get actor from map and display it
471 PipelineByActorName (aName)->AddToRenderer (aRenderer);
472 }
473 // Different shapes
474 else
475 {
476 if (aNewShape.IsNull()) continue;
477 // Create actor from DRAW shape
478 vtkActor* anActor = CreateActor (GenerateId(), aNewShape);
479 // Remove old actor from render
480 PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
481 // Update maps
482 GetMapOfShapes().UnBind2 (aName);
483 GetMapOfShapes().Bind (aNewShape, aName);
484 GetMapOfActors().UnBind2 (aName);
485 GetMapOfActors().Bind (anActor, aName);
486 // Display new actor
487 PipelineByActorName (aName)->AddToRenderer (aRenderer);
488 // Compute selection for displayed actors
489 GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
490 }
491 }
492 // There is no shape with given name in map
493 else
494 {
495 if (aNewShape.IsNull()) continue;
496 // Create actor from DRAW shape
a2f76b15 497 Standard_Integer anId = GenerateId();
498 vtkSmartPointer<vtkActor> anActor = CreateActor (anId, aNewShape);
52f99d93 499 // Update maps
500 GetMapOfShapes().Bind (aNewShape, aName);
501 GetMapOfActors().Bind (anActor, aName);
502 // Display actor
a2f76b15 503 GetPipeline(anId)->AddToRenderer(aRenderer);
52f99d93 504
505 // Compute selection for displayed actors
506 GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
507 }
508 }
509
510 // Redraw window
511 aRenderer->ResetCamera();
512 GetInteractor()->GetRenderWindow()->Render();
513
514 return 0;
515}
516
517//================================================================
518// Function : VtkErase
519// Purpose :
520//================================================================
521static Standard_Integer VtkErase (Draw_Interpretor& theDI,
522 Standard_Integer theArgNum,
523 const char** theArgs)
524{
525 // Check viewer
526 if (!GetInteractor()->IsEnabled())
527 {
528 theDI << theArgs[0] << " error : call ivtkinit before\n";
529 return 1; // TCL_ERROR
530 }
531
532 vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
533 // Erase all objects
534 if (theArgNum == 1)
535 {
536 DoubleMapOfActorsAndNames::Iterator anIterator (GetMapOfActors());
537 while (anIterator.More())
538 {
539 PipelineByActor (anIterator.Key1())->RemoveFromRenderer (aRenderer);
540 anIterator.Next();
541 }
542 }
543 // Erase named objects
544 else
545 {
546 TCollection_AsciiString aName;
547 for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
548 {
549 aName = theArgs[anIndex];
550 if (GetMapOfActors().IsBound2 (aName))
551 {
552 PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
553 }
554 }
555 }
556
557 // Redraw window
558 aRenderer->ResetCamera();
559 GetInteractor()->GetRenderWindow()->Render();
560 return 0;
561}
562
a2f76b15 563//================================================================
564// Function : VtkRemove
565// Purpose : Remove the actor from memory.
566//================================================================
567static Standard_Integer VtkRemove(Draw_Interpretor& theDI,
568 Standard_Integer theArgNum,
569 const char** theArgs)
570{
571 // Check viewer
572 if (!GetInteractor()->IsEnabled())
573 {
574 theDI << theArgs[0] << " error : call ivtkinit before\n";
575 return 1; // TCL_ERROR
576 }
577
578 vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
579
580 // Remove all objects
581 if (theArgNum == 1)
582 {
583 // Remove all actors from the renderer
584 DoubleMapOfActorsAndNames::Iterator anIterator(GetMapOfActors());
585 while (anIterator.More())
586 {
587 vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc =
588 IVtkTools_ShapeObject::GetShapeSource(anIterator.Key1());
589 if (aSrc.GetPointer() != NULL && !(aSrc->GetShape().IsNull()))
590 {
591 GetPicker()->RemoveSelectableObject(aSrc->GetShape());
592 }
593 else
594 {
595 aRenderer->RemoveActor(anIterator.Key1());
596 }
597 anIterator.Next();
598 }
599 // Remove all pipelines from the renderer
600 for (ShapePipelineMap::Iterator anIt(*GetPipelines()); anIt.More(); anIt.Next())
601 {
602 anIt.Value()->RemoveFromRenderer(aRenderer);
603 }
604 // Clear maps and remove all TopoDS_Shapes, actors and pipelines
605 GetMapOfShapes().Clear();
606 GetMapOfActors().Clear();
607 GetPipelines()->Clear();
608 }
609 // Remove named objects
610 else
611 {
612 TCollection_AsciiString aName;
613 for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
614 {
615 aName = theArgs[anIndex];
616 if (GetMapOfActors().IsBound2(aName))
617 {
618 // Remove the actor and its pipeline (if found) from the renderer
619 vtkSmartPointer<vtkActor> anActor = GetMapOfActors().Find2(aName);
620 vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc =
621 IVtkTools_ShapeObject::GetShapeSource(anActor);
622 if (aSrc.GetPointer() != NULL && !(aSrc->GetShape().IsNull()))
623 {
624 IVtk_IdType aShapeID = aSrc->GetShape()->GetId();
625 GetPicker()->RemoveSelectableObject(aSrc->GetShape());
626 GetPipeline(aSrc->GetShape()->GetId())->RemoveFromRenderer(aRenderer);
627 GetPipelines()->UnBind(aShapeID); // Remove a pipepline
628 }
629 else
630 {
631 aRenderer->RemoveActor(anActor);
632 }
633 // Remove the TopoDS_Shape and the actor
634 GetMapOfShapes().UnBind2(aName); // Remove a TopoDS shape
635 GetMapOfActors().UnBind2(aName); // Remove an actor
636 }
637 }
638 }
639
640 // Redraw window
641 aRenderer->ResetCamera();
642 GetInteractor()->GetRenderWindow()->Render();
643 return 0;
644}
645
52f99d93 646//================================================================
647// Function : VtkSetDisplayMode
648// Purpose :
649// Draw args : ivtksetdispmode [name] mode(0,1)
650//================================================================
651static Standard_Integer VtkSetDisplayMode (Draw_Interpretor& theDI,
652 Standard_Integer theArgNum,
653 const char** theArgs)
654{
655 // Check viewer
656 if (!GetInteractor()->IsEnabled())
657 {
658 theDI << theArgs[0] << " error: call ivtkinit before\n";
659 return 1; // TCL_ERROR
660 }
661
662 // Check arguments
663 if (theArgNum != 2 && theArgNum != 3)
664 {
665 theDI << theArgs[0] << " error: expects 1 or 2 arguments\n";
666 return 1; // TCL_ERROR
667 }
668
669 vtkSmartPointer<vtkActor> anActor;
670 // Set disp mode for all objects
671 if (theArgNum == 2)
672 {
673 // Get mode
674 Standard_Integer aMode = Draw::Atoi (theArgs[1]);
675 DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
676 while (anIter.More())
677 {
678 anActor = anIter.Key1();
679 IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
680 if (aSrc)
681 {
682 IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
683 if (!anOccShape.IsNull())
684 {
685 IVtkTools_DisplayModeFilter* aFilter = GetPipeline ( anOccShape->GetId() )->GetDisplayModeFilter();
686 aFilter->SetDisplayMode((IVtk_DisplayMode)aMode);
687 aFilter->Modified();
688 aFilter->Update();
689 }
690 }
691 anIter.Next();
692 }
693 }
694 // Set disp mode for named object
695 else
696 {
697 Standard_Integer aMode = atoi(theArgs[2]);
698 TCollection_AsciiString aName = theArgs[1];
699 if (GetMapOfActors().IsBound2 (aName))
700 {
701 anActor = GetMapOfActors().Find2 (aName);
702 vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
703 if (aSrc)
704 {
705 IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
706 if (!anOccShape.IsNull())
707 {
708 IVtkTools_DisplayModeFilter* aFilter = GetPipeline (anOccShape->GetId())->GetDisplayModeFilter();
709 aFilter->SetDisplayMode ((IVtk_DisplayMode)aMode);
710 aFilter->Modified();
711 aFilter->Update();
712 }
713 }
714 }
715 }
716
717 // Redraw window
718 GetInteractor()->Render();
719 return 0;
720}
721
722//================================================================
723// Function : VtkSetSelectionMode
724// Purpose :
725// Draw args : ivtksetselmode [name] mode on/off(0,1)
726//================================================================
727static Standard_Integer VtkSetSelectionMode (Draw_Interpretor& theDI,
728 Standard_Integer theArgNum,
729 const char** theArgs)
730{
731 // Check viewer
732 if (!GetInteractor()->IsEnabled())
733 {
734 theDI << theArgs[0] << " error: call ivtkinit before\n";
735 return 1; // TCL_ERROR
736 }
737
738 // Check arguments
739 if (theArgNum != 3 && theArgNum != 4)
740 {
741 theDI << theArgs[0] << " error: expects 2 or 3 arguments\n";
742 return 1; // TCL_ERROR
743 }
744
745 vtkSmartPointer<vtkActor> anActor;
746 Standard_Integer aMode;
747 Standard_Boolean isTurnOn;
748 // Set sel mode for all objects
749 if (theArgNum == 3)
750 {
751 aMode = atoi (theArgs[1]);
dde68833 752 isTurnOn = (atoi (theArgs[2]) != 0);
52f99d93 753 if (aMode < 0 || aMode > 8)
754 {
755 theDI << theArgs[0] << " error: only 0-8 selection modes are supported\n";
756 return 1; // TCL_ERROR
757 }
758 DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
759 while (anIter.More())
760 {
761 anActor = anIter.Key1();
762
763 if (aMode == SM_Shape && isTurnOn)
764 {
765 IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
766 IVtk_SelectionModeList::Iterator anIt (aList);
767 // Turn off all sel modes differed from SM_Shape
768 while (anIt.More())
769 {
770 IVtk_SelectionMode aCurMode = anIt.Value();
771 if (SM_Shape != aCurMode)
772 {
773 GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
774 }
775 anIt.Next();
776 }
777 GetPicker()->SetSelectionMode (anActor, SM_Shape);
778 }
779
780 if (aMode != SM_Shape)
781 {
782 if (isTurnOn)
783 {
784 GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
785 GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
786 if (aMode == SM_Vertex)
787 {
788 GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
789 }
790 }
791 else
792 {
793 GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
794 IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
795 if (!aList.Size())
796 {
797 GetPicker()->SetSelectionMode(anActor, SM_Shape);
798 }
799 if (aMode == SM_Vertex)
800 {
801 GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
802 }
803 }
804 }
805 anIter.Next();
806 }
807 }
808
809 // Set sel mode for named object
810 if (theArgNum == 4)
811 {
812 aMode = atoi (theArgs[2]);
dde68833 813 isTurnOn = (atoi (theArgs[3]) != 0);
52f99d93 814
815 if (aMode < 0 || aMode > 8)
816 {
817 theDI << theArgs[0] << " error: only 0-8 selection modes are supported\n";
818 return 1; // TCL_ERROR
819 }
820
821 TCollection_AsciiString aName = theArgs[1];
822 if (GetMapOfActors().IsBound2 (aName))
823 {
824 anActor = GetMapOfActors().Find2 (aName);
825
826 if (aMode == SM_Shape && isTurnOn)
827 {
828 IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
829 IVtk_SelectionModeList::Iterator anIt (aList);
830 // Turn off all sel modes differed from SM_Shape
831 while (anIt.More())
832 {
833 IVtk_SelectionMode aCurMode = anIt.Value();
834 if (SM_Shape != aCurMode)
835 {
836 GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
837 }
838 anIt.Next();
839 }
840 GetPicker()->SetSelectionMode (anActor, SM_Shape);
841 }
842
843 if (aMode != SM_Shape)
844 {
845 if (isTurnOn)
846 {
847 GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
848 GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
849 if (aMode == SM_Vertex)
850 {
851 GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
852 }
853 }
854 else
855 {
856 GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
857 IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
858 if (!aList.Size())
859 {
860 GetPicker()->SetSelectionMode(anActor, SM_Shape);
861 }
862 if (aMode == SM_Vertex)
863 {
864 GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
865 }
866 }
867 }
868 }
869 }
870
871 // Redraw window
872 GetInteractor()->Render();
873
874 return 0;
875}
876
877//================================================================
878// Function : VtkMoveTo
879// Purpose :
880// Draw args : ivtkmoveto x y
881//================================================================
882static Standard_Integer VtkMoveTo(Draw_Interpretor& theDI,
883 Standard_Integer theArgNum,
884 const char** theArgs)
885{
886 // Check viewer
887 if (!GetInteractor()->IsEnabled())
888 {
889 theDI << theArgs[0] << " error: call ivtkinit before\n";
890 return 1; // TCL_ERROR
891 }
892
893 // Check args
894 if (theArgNum != 3)
895 {
896 theDI << theArgs[0] << " error: expects 2 arguments\n";
897 return 1; // TCL_ERROR
898 }
899
900 Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[2]) - 1;
901 GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
1e756cb9 902
903 gp_XYZ aPickPnt;
904 GetInteractor()->Selector()->GetPickPosition (aPickPnt.ChangeData());
905 theDI << aPickPnt.X() << " " << aPickPnt.Y() << " " << aPickPnt.Z();
52f99d93 906 return 0;
907}
908
909//================================================================
910// Function : VtkSelect
911// Purpose :
912// Draw args : ivtkselect x y
913//================================================================
914static Standard_Integer VtkSelect (Draw_Interpretor& theDI,
915 Standard_Integer theArgNum,
916 const char** theArgs)
917{
918 // Check viewer
919 if (!GetInteractor()->IsEnabled())
920 {
921 theDI << theArgs[0] << " error: call ivtkinit before\n";
922 return 1; // TCL_ERROR
923 }
924
925 // Check args
926 if (theArgNum != 3)
927 {
928 theDI << theArgs[0] << " error: expects 3 arguments\n";
929 return 1; // TCL_ERROR
930 }
931
a2f76b15 932 Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[2]) - 1;
52f99d93 933 GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
934 GetInteractor()->OnSelection();
935 return 0;
936
937}
938
939//===================================================================
940// Fubction : VtkFit
941// Purpose :
942// Draw args : ivtkfit
943//===================================================================
944
945static Standard_Integer VtkFit (Draw_Interpretor& theDI,
946 Standard_Integer,
947 const char** theArgs)
948{
949 // Check viewer
950 if (!GetInteractor()->IsEnabled())
951 {
952 theDI << theArgs[0] << " error : call ivtkinit before \n";
953 return 1; //TCL_ERROR
954 }
955
956 GetRenderer()->ResetCamera();
957 GetInteractor()->Render();
958 return 0;
959}
960
961//===================================================================
962// Fubction : VtkDump
963// Purpose :
964// Draw args : ivtkdump FullFilename.{png|bmp|jpeg|tiff|pnm}
965// [buffer={rgb|rgba|depth}] [width height]
966// [stereoproj={L|R}]
967//===================================================================
968static Standard_Integer VtkDump (Draw_Interpretor& theDI,
969 Standard_Integer theArgNum,
970 const char** theArgs)
971{
972 // Check viewer
973 if (!GetInteractor()->IsEnabled())
974 {
975 std::cout << theArgs[0] << " error : call ivtkinit before \n";
976 return 1;
977 }
978
979 if (theArgNum < 2)
980 {
981 theDI << theArgs[0] << " error : wrong number of parameters. Type 'help"
982 << theArgs[0] << "' for more information.\n";
983 }
984 vtkSmartPointer<vtkWindowToImageFilter> anImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
985
986 anImageFilter->SetInput (GetInteractor()->GetRenderWindow());
987 // Set custom buffer type
988 if (theArgNum > 2)
989 {
990 TCollection_AsciiString aBufferType (theArgs[2]);
991 aBufferType.LowerCase();
992 if (aBufferType.IsEqual ("rgb"))
993 {
994 anImageFilter->SetInputBufferTypeToRGB();
995 }
996 else if (aBufferType.IsEqual ("rgba"))
997 {
998 anImageFilter->SetInputBufferTypeToRGBA();
999 }
1000 else if (aBufferType.IsEqual ("depth"))
1001 {
1002 anImageFilter->SetInputBufferTypeToZBuffer();
1003 }
1004 }
1005 anImageFilter->Update();
1006
1007 // Set custom stereo projection options
1008 if (theArgNum > 5 && GetRenderer()->GetRenderWindow()->GetStereoRender())
1009 {
1010 Standard_CString aStereoProjStr = theArgs[5];
1011
1012 Standard_Integer aStereoType = GetRenderer()->GetRenderWindow()->GetStereoType();
1013 if (strcasecmp (aStereoProjStr, "L"))
1014 {
1015 GetRenderer()->GetRenderWindow()->SetStereoTypeToLeft();
1016 GetRenderer()->GetRenderWindow()->StereoUpdate();
1017 anImageFilter->Update();
1018 GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
1019 }
1020 else if (strcasecmp (aStereoProjStr, "R"))
1021 {
1022 GetRenderer()->GetRenderWindow()->SetStereoTypeToRight();
1023 GetRenderer()->GetRenderWindow()->StereoUpdate();
1024 anImageFilter->Update();
1025 GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
1026 }
1027 else
1028 {
1029 theDI << theArgs[0] << " error: unknown value for stereo projection.\n";
1030 return 1;
1031 }
1032 }
1033
1034 // Set parameters for image writer
1035 vtkSmartPointer<vtkImageWriter> anImageWriter;
1036 TCollection_AsciiString aFilename (theArgs[1]);
1037 Standard_Integer anExtStart = aFilename.SearchFromEnd (TCollection_AsciiString("."));
1038 TCollection_AsciiString aFormat = (anExtStart == -1) ? TCollection_AsciiString("")
1039 : aFilename.SubString (anExtStart + 1, aFilename.Length());
1040 aFormat.LowerCase();
1041
1042 if (aFormat.IsEqual ("png"))
1043 {
1044 anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
1045 }
1046 else if (aFormat.IsEqual ("bmp"))
1047 {
1048 anImageWriter = vtkSmartPointer<vtkBMPWriter>::New();
1049 }
1050 else if (aFormat.IsEqual ("jpeg"))
1051 {
1052 anImageWriter = vtkSmartPointer<vtkJPEGWriter>::New();
1053 }
1054 else if (aFormat.IsEqual ("tiff"))
1055 {
1056 anImageWriter = vtkSmartPointer<vtkTIFFWriter>::New();
1057 }
1058 else if (aFormat.IsEqual ("pnm"))
1059 {
1060 anImageWriter = vtkSmartPointer<vtkPNMWriter>::New();
1061 }
1062 else // aFormat is unsupported or not set.
1063 {
1064 if (aFormat.IsEmpty())
1065 {
1066 theDI << theArgs[0] << " warning: the image format is not set.\n"
1067 << "The image will be saved into PNG format.\n";
1068 anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
1069 aFormat = TCollection_AsciiString ("png");
1070 if (anExtStart != -1)
1071 {
1072 aFilename.Split (anExtStart);
1073 }
1074 else
1075 {
1076 aFilename += ".";
1077 }
1078 aFilename += aFormat;
1079 }
1080 else
1081 {
1082 theDI << theArgs[0] << " error: the image format "
1083 << aFormat.ToCString() <<" is not supported.\n";
1084 return 1;
1085 }
1086
1087 }
1088
1089 anImageWriter->SetFileName (aFilename.ToCString());
1090
1091 Standard_Integer aWidth = (theArgNum > 3) ? atoi (theArgs[3]) : 0;
1092 Standard_Integer aHeight = (theArgNum > 4) ? atoi (theArgs[4]) : 0;
1093 if (aWidth >= 0 || aHeight >= 0)
1094 {
1095 // Scale image
1096 vtkSmartPointer<vtkImageResize> anImageResize = vtkSmartPointer<vtkImageResize>::New();
1097#if VTK_MAJOR_VERSION <= 5
1098 anImageResize->SetInput (anImageFilter->GetOutput());
1099#else
1100 anImageResize->SetInputData (anImageFilter->GetOutput());
1101#endif
1102
1103 anImageResize->SetOutputDimensions (aWidth, aHeight, 1);
1104 anImageResize->Update();
1105 anImageWriter->SetInputConnection (anImageResize->GetOutputPort());
1106 }
1107 else
1108 {
1109 anImageWriter->SetInputConnection (anImageFilter->GetOutputPort());
1110 }
1111 anImageWriter->Write();
1112
1113 return 0;
1114}
1115
1116//===================================================================
1117// Fubction : VtkBackgroundColor
1118// Purpose :
1119// Draw args : ivtkbgcolor r g b
1120// r,g,b = [0..255]
1121//===================================================================
1122static Standard_Integer VtkBackgroundColor (Draw_Interpretor& theDI,
1123 Standard_Integer theArgNum,
1124 const char** theArgs)
1125{
1126 if (theArgNum != 4 && theArgNum != 7)
1127 {
1128 theDI << theArgs[0] << " error : wrong number of parameters.\n"
1129 << "Type 'help " << theArgs[0] << "' for more information.\n";
1130 return 1;
1131 }
1132
1133 // Check viewer
1134 if (!GetInteractor()->IsEnabled())
1135 {
1136 std::cout << theArgs[0] << " error : call ivtkinit before \n";
1137 return 1;
1138 }
1139
1140 Standard_Real aR = Draw::Atof(theArgs[1])/255.0;
1141 Standard_Real aG = Draw::Atof(theArgs[2])/255.0;
1142 Standard_Real aB = Draw::Atof(theArgs[3])/255.0;
1143
1144 GetRenderer()->SetGradientBackground(false);
1145 GetRenderer()->SetBackground (aR, aG, aB);
1146
1147 if (theArgNum == 7)
1148 {
1149 Standard_Real aR2 = Draw::Atof(theArgs[4])/255.0;
1150 Standard_Real aG2 = Draw::Atof(theArgs[5])/255.0;
1151 Standard_Real aB2 = Draw::Atof(theArgs[6])/255.0;
1152
1153 GetRenderer()->SetBackground2(aR2, aG2, aB2);
1154 GetRenderer()->SetGradientBackground(true);
1155 }
1156
1157 GetInteractor()->Render();
1158
1159 return 0;
1160}
1161
1162//================================================================
1163// Function : Commands
1164// Purpose :
1165//================================================================
1166void IVtkDraw::Commands (Draw_Interpretor& theCommands)
1167{
1168 const char *group = "VtkViewer";
1169
1170 theCommands.Add("ivtkinit",
1171 "ivtkinit usage:\n"
1172 "ivtkinit [leftPx topPx widthPx heightPx]"
1173 "\n\t\t: Creates the Vtk window",
1174 __FILE__, VtkInit, group);
1175
1176 theCommands.Add("ivtkdisplay",
1177 "ivtkdisplay usage:\n"
1178 "ivtkdisplay name1 name2 ..."
1179 "\n\t\t: Displayes named objects in current view.",
1180 __FILE__, VtkDisplay, group);
1181
1182 theCommands.Add("ivtkerase",
1183 "ivtkerase usage:\n"
1184 "ivtkerase [name1 name2 ...]"
1185 "\n\t\t: Removes from renderer named objects or all objects.",
1186 __FILE__, VtkErase, group);
a2f76b15 1187
1188 theCommands.Add("ivtkremove",
1189 "ivtkremove usage:\n"
1190 "ivtkremove [name1 name2 ...]"
1191 "\n\t\t: Removes from renderer and from memory named objects or all objects.",
1192 __FILE__, VtkRemove, group);
52f99d93 1193
1194 theCommands.Add("ivtksetdispmode",
1195 "ivtksetdispmode usage:\n"
1196 "ivtksetdispmode [name] mode (0,1)"
1197 "\n\t\t: Sets or unsets display mode 'mode' to the object with name 'name' or to all objects"
1198 "if name is not defined.",
1199 __FILE__, VtkSetDisplayMode, group);
1200
1201 theCommands.Add("ivtksetselmode",
1202 "ivtksetselmode usage:\n"
1203 " ivtksetselmode [name] mode on/off(0,1)"
1204 "\n\t\t: Sets or unsets selection mode 'mode' to the object with name 'name' or to the all displayed objects.",
1205 __FILE__, VtkSetSelectionMode, group);
1206
1207 theCommands.Add("ivtkmoveto",
1208 "ivtkmoveto usage:\n"
1209 "ivtkmoveto x y"
1210 "\n\t\t: Moves position to the pixel with coordinates (x,y). The object on this position is highlighted.",
1211 __FILE__, VtkMoveTo, group);
1212
1213 theCommands.Add("ivtkselect",
1214 "ivtkselect usage:\n"
1215 "ivtkselect x y"
1216 "\n\t\t: Selects object which correspond to the pixel with input coordinates (x,y).",
1217 __FILE__, VtkSelect, group);
1218
1219 theCommands.Add("ivtkfit",
1220 "ivtkfit usage:\n"
1221 "ivtkfit"
1222 "\n\t\t: Fits view according all displayed objects.",
1223 __FILE__, VtkFit, group);
1224
1225 theCommands.Add("ivtkdump",
1226 "ivtkdump usage:\n"
1227 "ivtkdump <FullFilename>.{png|bmp|jpeg|tiff|pnm} [buffer={rgb|rgba|depth}] [width height] [stereoproj={L|R}]"
1228 "\n\t\t: Dumps contents of viewer window to PNG, BMP, JPEG, TIFF or PNM file",
1229 __FILE__, VtkDump, group);
1230
1231 theCommands.Add("ivtkbgcolor",
1232 "ivtkbgcolor usage:\n"
1233 "ivtkbgcolor r g b [r2 g2 b2]\n"
1234 "\n\t\t: Sets uniform background color or gradient one if second triple of paramers is set."
1235 "Color parameters r,g,b = [0..255].",
1236 __FILE__, VtkBackgroundColor, group);
1237}
1238
1239
1240//================================================================
1241// Function : Factory
1242// Purpose :
1243//================================================================
1244void IVtkDraw::Factory (Draw_Interpretor& theDI)
1245{
1246 // definition of Viewer Commands
1247 IVtkDraw::Commands (theDI);
1248}
1249
1250// Declare entry point PLUGINFACTORY
1251DPLUGIN(IVtkDraw)
1252