1 // Created on: 1992-04-06
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Draw_Viewer.hxx>
18 #include <Draw_View.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Draw_Window.hxx>
23 #include <Draw_Display.hxx>
24 #include <TCollection_AsciiString.hxx>
28 #define MotionNotify 6
29 static const Standard_Real DRAWINFINITE = 1e50;
30 Standard_EXPORT Standard_Boolean Draw_Bounds = Standard_True;
31 extern Standard_Boolean Draw_Batch;
32 const Standard_Integer MAXSEGMENT = 1000;
33 Segment segm[MAXSEGMENT];
35 static Draw_View* curview = NULL;
36 static Standard_Integer curviewId = 0;
37 static char blank[2] = "";
38 static Standard_Real xmin,xmax,ymin,ymax;
39 static Standard_Boolean found = Standard_False;
40 static Standard_Integer xpick, ypick, precpick;
41 static gp_Pnt lastPickP1;
42 static gp_Pnt lastPickP2;
43 static Standard_Real lastPickParam;
44 static Draw_Color highlightcol;
45 static Draw_Color currentcolor;
46 static Standard_Boolean highlight = Standard_False;
47 static Standard_Integer ps_vx, ps_vy;
48 static Standard_Real ps_kx, ps_ky;
49 static Standard_Integer ps_px, ps_py;
50 static ostream* ps_stream;
51 static Standard_Integer ps_width[MAXCOLOR];
52 static Standard_Real ps_gray[MAXCOLOR];
54 enum DrawingMode {DRAW, PICK, POSTSCRIPT};
55 static DrawingMode CurrentMode = DRAW;
57 //=======================================================================
60 //=======================================================================
62 Draw_Viewer::Draw_Viewer()
64 if (Draw_Batch) return;
66 for ( i = 0; i < MAXVIEW; i++) myViews[i] = NULL;
67 for (i = 0; i < MAXCOLOR; i++) {
73 //=======================================================================
74 //function : DefineColor
76 //=======================================================================
78 Standard_Boolean Draw_Viewer::DefineColor (const Standard_Integer i, const char* colname)
80 if (Draw_Batch) return 1;
81 return Draw_Window::DefineColor(i,colname);
85 //=======================================================================
88 //=======================================================================
90 void Draw_Viewer::MakeView(const Standard_Integer id,
92 const Standard_Integer X, const Standard_Integer Y,
93 const Standard_Integer W, const Standard_Integer H)
95 if (Draw_Batch) return;
99 myViews[id] = new Draw_View(id,this,X , Y, W, H);
102 myViews[id]->SetDx(W / 2);
103 myViews[id]->SetDy(- H / 2);
105 if (!myViews[id]->Init(typ))
113 //=======================================================================
114 //function : MakeView
116 //=======================================================================
118 void Draw_Viewer::MakeView(const Standard_Integer id,
120 const Standard_Integer X, const Standard_Integer Y,
121 const Standard_Integer W, const Standard_Integer H,
122 HWND win, Standard_Boolean useBuffer)
124 if (Draw_Batch) return;
128 myViews[id] = new Draw_View(id, this, X, Y, W, H, win);
129 myViews[id]->SetUseBuffer(useBuffer);
132 myViews[id]->SetDx( W / 2);
133 myViews[id]->SetDy(-H / 2);
135 if (!myViews[id]->Init(typ))
142 //=======================================================================
143 //function : MakeView
145 //=======================================================================
147 void Draw_Viewer::MakeView (const Standard_Integer id,
151 if (Draw_Batch) return;
155 myViews[id] = new Draw_View(id,this,window);
158 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
159 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
161 if (!myViews[id]->Init(typ))
169 //=======================================================================
170 //function : SetTitle
172 //=======================================================================
174 void Draw_Viewer::SetTitle (const Standard_Integer id, const char* name)
176 if (Draw_Batch) return;
177 if(myViews[id]) myViews[id]->SetTitle (name);
180 //=======================================================================
181 //function : ResetView
182 //purpose : reset view zoom and axes
183 //=======================================================================
185 void Draw_Viewer::ResetView(const Standard_Integer id)
187 if (Draw_Batch) return;
189 myViews[id]->Init(myViews[id]->Type());
194 //=======================================================================
197 //=======================================================================
199 void Draw_Viewer::SetZoom (const Standard_Integer id, const Standard_Real z)
204 Draw_View* aView = myViews[id];
207 Standard_Real zz = z / aView->GetZoom();
209 Standard_Integer X,Y,W,H;
210 GetPosSize(id,X,Y,W,H);
212 const Standard_Real w = 0.5 * static_cast<Standard_Real>(W);
213 const Standard_Real h = 0.5 * static_cast<Standard_Real>(H);
215 const Standard_Integer aDx = static_cast<Standard_Integer>
216 ( w - zz * (w - aView->GetDx()) );
217 const Standard_Integer aDy = static_cast<Standard_Integer>
218 ( -h + zz * (h + aView->GetDy()) );
225 //=======================================================================
226 //function : RotateView
228 //=======================================================================
230 void Draw_Viewer::RotateView (const Standard_Integer id,
232 const Standard_Real A)
234 if (Draw_Batch) return;
236 gp_Trsf T = myViews[id]->GetMatrix();
240 gp_Dir DD(D.X(),D.Y(),0);
243 RotateView(id,PP,DD,A);
247 //=======================================================================
248 //function : RotateView
250 //=======================================================================
252 void Draw_Viewer::RotateView (const Standard_Integer id,
255 const Standard_Real A)
257 if (Draw_Batch) return;
260 T.SetRotation(gp_Ax1(P,D),A);
261 myViews[id]->Transform(T);
266 //=======================================================================
267 //function : SetFocal
269 //=======================================================================
271 void Draw_Viewer::SetFocal (const Standard_Integer id, const Standard_Real F)
273 if (Draw_Batch) return;
275 myViews[id]->SetFocalDistance(F);
278 //=======================================================================
281 //=======================================================================
283 char* Draw_Viewer::GetType (const Standard_Integer id) const
285 if (Draw_Batch) return blank;
287 return const_cast<char*>(myViews[id]->Type());
292 //=======================================================================
295 //=======================================================================
297 Standard_Real Draw_Viewer::Zoom (const Standard_Integer id) const
299 if (Draw_Batch) return Standard_False;
301 return myViews[id]->GetZoom();
306 //=======================================================================
309 //=======================================================================
311 Standard_Real Draw_Viewer::Focal (const Standard_Integer id) const
313 if (Draw_Batch) return 1.;
315 return myViews[id]->GetFocalDistance();
320 //=======================================================================
323 //=======================================================================
325 void Draw_Viewer::GetTrsf (const Standard_Integer id,gp_Trsf& T) const
327 if (Draw_Batch) return;
329 T = myViews[id]->GetMatrix();
332 //=======================================================================
335 //=======================================================================
337 Standard_Boolean Draw_Viewer::Is3D (const Standard_Integer id) const
339 if (Draw_Batch) return Standard_False;
341 return !myViews[id]->Is2D();
343 return Standard_False;
346 //=======================================================================
349 //=======================================================================
351 void Draw_Viewer::SetTrsf (const Standard_Integer id,gp_Trsf& T)
353 if (Draw_Batch) return;
355 myViews[id]->SetMatrix(T);
358 //=======================================================================
359 //function : GetPosSize
361 //=======================================================================
363 void Draw_Viewer::GetPosSize(const Standard_Integer id,
364 Standard_Integer& X, Standard_Integer& Y,
365 Standard_Integer& W, Standard_Integer& H)
367 if (Draw_Batch) return;
368 if (myViews[id] != NULL) {
369 myViews[id]->GetPosition(X, Y);
370 W = myViews[id]->WidthWin();
371 H = myViews[id]->HeightWin();
375 //=======================================================================
376 //function : GetFrame
378 //=======================================================================
380 void Draw_Viewer::GetFrame(const Standard_Integer id,
381 Standard_Integer& xminf, Standard_Integer& yminf,
382 Standard_Integer& xmaxf, Standard_Integer& ymaxf)
384 if (Draw_Batch) return;
386 Standard_Integer X,Y,H,W;
387 GetPosSize(id,X,Y,W,H);
388 xminf = - myViews[id]->GetDx();
389 xmaxf = W - myViews[id]->GetDx();
390 yminf = - myViews[id]->GetDy() - H;
391 ymaxf = - myViews[id]->GetDy();
395 //=======================================================================
398 //=======================================================================
400 void Draw_Viewer::FitView(const Standard_Integer id, const Standard_Integer frame)
402 if (Draw_Batch) return;
405 // is this the only view in its category
406 Standard_Boolean is2d = myViews[id]->Is2D();
407 Standard_Integer i,nbviews = 0;
408 for (i = 1; i < MAXVIEW; i++) {
410 if (myViews[i]->Is2D() == is2d)
414 Standard_Boolean only = (nbviews == 1);
416 Standard_Integer X,Y,H,W;
417 GetPosSize(id,X,Y,W,H);
418 // compute the min max
419 Standard_Integer n = myDrawables.Length();
422 curview = myViews[id];
423 Standard_Real umin,umax,vmin,vmax;
424 Standard_Real u1,u2,v1,v2;
425 umin = vmin = DRAWINFINITE;
426 umax = vmax = -DRAWINFINITE;
428 for (i = 1; i <= n; i++) {
429 Standard_Boolean d3d = myDrawables(i)->Is3D();
430 if ((d3d && !is2d) || (!d3d && is2d)) {
431 // if this is not the only view recompute...
433 DrawOnView(id,myDrawables(i));
434 myDrawables(i)->Bounds(u1,u2,v1,v2);
435 if (u1 < umin) umin = u1;
436 if (u2 > umax) umax = u2;
437 if (v1 < vmin) vmin = v1;
438 if (v2 > vmax) vmax = v2;
442 umin = umin / curview->GetZoom();
443 vmin = vmin / curview->GetZoom();
444 umax = umax / curview->GetZoom();
445 vmax = vmax / curview->GetZoom();
446 if ((umax - umin) < 1.e-6) {
447 if ((vmax - vmin) < 1.e-6)
450 z = ((Standard_Real)(H - 2*frame)) / (vmax - vmin);
453 z = ((Standard_Real)(W - 2*frame)) /((Standard_Real) (umax - umin));
454 if ((vmax - vmin) > 1.e-6) {
455 Standard_Real z2 = ((Standard_Real)(H - 2*frame)) /(vmax - vmin);
460 curview->SetDx( static_cast<Standard_Integer>( W / 2 - 0.5 * (umin+umax) * z) );
461 curview->SetDy( static_cast<Standard_Integer>(-H / 2 - 0.5 * (vmin+vmax) * z) );
465 //=======================================================================
468 //=======================================================================
470 void Draw_Viewer::PanView(const Standard_Integer id,
471 const Standard_Integer DX, const Standard_Integer DY)
473 if (Draw_Batch) return;
475 myViews[id]->SetDx(myViews[id]->GetDx() + DX);
476 myViews[id]->SetDy(myViews[id]->GetDy() + DY);
481 //=======================================================================
484 //=======================================================================
486 void Draw_Viewer::SetPan(const Standard_Integer id,
487 const Standard_Integer DX, const Standard_Integer DY)
489 if (Draw_Batch) return;
491 myViews[id]->SetDx(DX);
492 myViews[id]->SetDy(DY);
496 //=======================================================================
499 //=======================================================================
501 void Draw_Viewer::GetPan(const Standard_Integer id,
502 Standard_Integer& DX, Standard_Integer& DY)
504 if (Draw_Batch) return;
506 DX = myViews[id]->GetDx();
507 DY = myViews[id]->GetDy();
511 //=======================================================================
514 //=======================================================================
516 Standard_Boolean Draw_Viewer::HasView(const Standard_Integer id) const
518 if (Draw_Batch) return Standard_False;
519 if ((id < 0) || id >= MAXVIEW) return Standard_False;
520 return myViews[id] != NULL;
523 //=======================================================================
524 //function : DisplayView
526 //=======================================================================
528 void Draw_Viewer::DisplayView (const Standard_Integer id) const
530 if (Draw_Batch) return;
531 if (myViews[id]) myViews[id]->DisplayWindow();
534 //=======================================================================
535 //function : HideView
537 //=======================================================================
539 void Draw_Viewer::HideView (const Standard_Integer id) const
541 if (Draw_Batch) return;
547 //=======================================================================
548 //function : ClearView
550 //=======================================================================
552 void Draw_Viewer::ClearView(const Standard_Integer id) const
554 if (Draw_Batch) return;
555 if (myViews[id]) myViews[id]->Clear();
558 //=======================================================================
559 //function : RemoveView
561 //=======================================================================
563 void Draw_Viewer::RemoveView(const Standard_Integer id)
565 if (Draw_Batch) return;
572 //=======================================================================
573 //function : RepaintView
575 //=======================================================================
576 void Draw_Viewer::RepaintView (const Standard_Integer id) const
578 if (Draw_Batch) return;
581 Standard_Integer n = myDrawables.Length();
582 for (Standard_Integer i = 1; i <= n; i++)
583 DrawOnView(id,myDrawables(i));
589 //=======================================================================
590 //function : ResizeView
591 //purpose : WNT re-drawing optimization
592 //=======================================================================
593 void Draw_Viewer::ResizeView (const Standard_Integer id) const
595 if (Draw_Batch) return;
596 if (myViews[id] && myViews[id]->GetUseBuffer()) {
597 myViews[id]->InitBuffer();
602 //=======================================================================
603 //function : UpdateView
604 //purpose : WNT re-drawing optimization
605 //=======================================================================
606 void Draw_Viewer::UpdateView (const Standard_Integer id, const Standard_Boolean forced) const
608 if (Draw_Batch) return;
610 if (!myViews[id]->GetUseBuffer() || forced) {
613 // Fast redrawing on WNT
614 if (myViews[id]->GetUseBuffer()) myViews[id]->Redraw();
619 //=======================================================================
620 //function : ConfigView
622 //=======================================================================
624 void Draw_Viewer::ConfigView (const Standard_Integer id) const
626 if (Draw_Batch) return;
629 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
630 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
634 //=======================================================================
635 //function : PostScriptView
637 //=======================================================================
639 void Draw_Viewer::PostScriptView (const Standard_Integer id,
640 const Standard_Integer VXmin,
641 const Standard_Integer VYmin,
642 const Standard_Integer VXmax,
643 const Standard_Integer VYmax,
644 const Standard_Integer PXmin,
645 const Standard_Integer PYmin,
646 const Standard_Integer PXmax,
647 const Standard_Integer PYmax,
648 ostream& sortie) const
650 if (Draw_Batch) return;
656 ps_kx = ((Standard_Real) (PXmax - PXmin)) / ((Standard_Real) (VXmax - VXmin));
657 ps_ky = ((Standard_Real) (PYmax - PYmin)) / ((Standard_Real) (VYmax - VYmin));
659 Standard_Integer n = myDrawables.Length();
661 CurrentMode = POSTSCRIPT;
662 Draw_Display DF = MakeDisplay(id);
663 Standard_Boolean view2d = myViews[id]->Is2D();
664 for (Standard_Integer i = 1; i <= n; i++)
665 if (myDrawables(i)->Is3D()) {
666 if (!view2d) myDrawables(i)->DrawOn(DF);
669 if (view2d) myDrawables(i)->DrawOn(DF);
671 sortie << "stroke\n";
676 //=======================================================================
677 //function : PostColor
679 //=======================================================================
681 void Draw_Viewer::PostColor(const Standard_Integer icol,
682 const Standard_Integer width,
683 const Standard_Real gray)
685 if (Draw_Batch) return;
686 if ((icol < 0) || (icol >= MAXCOLOR)) return;
687 ps_width[icol] = width;
688 ps_gray[icol] = gray;
691 //=======================================================================
692 //function : SaveView
694 //=======================================================================
696 Standard_Boolean Draw_Viewer::SaveView(const Standard_Integer id,
697 const char* filename)
699 if (Draw_Batch) return Standard_False;;
702 return myViews[id]->Save(filename);
706 std::cerr << "View " << id << " doesn't exists!\n";
707 return Standard_False;
711 //=======================================================================
712 //function : RepaintAll
714 //=======================================================================
716 void Draw_Viewer::RepaintAll () const
718 if (Draw_Batch) return;
719 for (Standard_Integer id = 0; id < MAXVIEW; id++)
723 //=======================================================================
724 //function : Repaint2D
726 //=======================================================================
728 void Draw_Viewer::Repaint2D () const
730 if (Draw_Batch) return;
731 for (Standard_Integer id = 0; id < MAXVIEW; id++)
733 if (myViews[id]->Is2D())
738 //=======================================================================
739 //function : Repaint3D
741 //=======================================================================
743 void Draw_Viewer::Repaint3D () const
745 if (Draw_Batch) return;
746 for (Standard_Integer id = 0; id < MAXVIEW; id++)
748 if (!myViews[id]->Is2D())
753 //=======================================================================
754 //function : DeleteView
756 //=======================================================================
758 void Draw_Viewer::DeleteView(const Standard_Integer id)
760 if (Draw_Batch) return;
761 if (myViews[id] != NULL) {
767 //=======================================================================
770 //=======================================================================
772 void Draw_Viewer::Clear()
774 if (Draw_Batch) return;
775 for (Standard_Integer i = 1; i <= myDrawables.Length(); i++)
776 myDrawables(i)->Visible(Standard_False);
778 for (Standard_Integer id = 0; id < MAXVIEW; id++)
782 //=======================================================================
785 //=======================================================================
787 void Draw_Viewer::Clear2D()
789 if (Draw_Batch) return;
790 Standard_Integer i = 1;
791 while (i <= myDrawables.Length()) {
792 if (myDrawables(i)->Is3D())
795 myDrawables(i)->Visible(Standard_False);
796 myDrawables.Remove(i);
799 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
801 if (myViews[id]->Is2D())
807 //=======================================================================
810 //=======================================================================
812 void Draw_Viewer::Clear3D()
814 if (Draw_Batch) return;
815 Standard_Integer i = 1;
816 while (i <= myDrawables.Length()) {
817 if (myDrawables(i)->Is3D()) {
818 myDrawables(i)->Visible(Standard_False);
819 myDrawables.Remove(i);
824 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
826 if (!myViews[id]->Is2D())
832 //=======================================================================
835 //=======================================================================
837 void Draw_Viewer::Flush()
839 if (Draw_Batch) return;
840 Draw_Window::Flush();
843 //=======================================================================
844 //function : DrawOnView
846 //=======================================================================
848 void Draw_Viewer::DrawOnView(const Standard_Integer id,
849 const Handle(Draw_Drawable3D)& D) const
851 if (Draw_Batch) return;
853 Draw_Display d = MakeDisplay(id);
854 xmin = ymin = DRAWINFINITE;
855 xmax = ymax = -DRAWINFINITE;
857 Standard_Boolean view2d = myViews[id]->Is2D();
858 myViews[id]->ResetFrame();
859 if ((D->Is3D() && !view2d) || (!D->Is3D() && view2d))
862 if (CurrentMode == DRAW)
863 D->SetBounds(xmin,xmax,ymin,ymax);
869 //=======================================================================
870 //function : HighlightOnView
872 //=======================================================================
874 void Draw_Viewer::HighlightOnView (const Standard_Integer id,
875 const Handle(Draw_Drawable3D)& D,
876 const Draw_ColorKind C) const
878 if (Draw_Batch) return;
879 highlight = Standard_True;
882 highlight = Standard_False;
885 //=======================================================================
886 //function : AddDrawable
888 //=======================================================================
890 void Draw_Viewer::AddDrawable (const Handle(Draw_Drawable3D)& D)
892 if (Draw_Batch) return;
893 if (!D.IsNull() && !D->Visible()) {
894 myDrawables.Append(D);
895 D->Visible(Standard_True);
899 //=======================================================================
900 //function : RemoveDrawable
902 //=======================================================================
904 void Draw_Viewer::RemoveDrawable (const Handle(Draw_Drawable3D)& D)
906 if (Draw_Batch) return;
907 if (!D.IsNull() && D->Visible()) {
908 Standard_Integer index;
909 for (index = 1; index <= myDrawables.Length(); index++) {
910 if (myDrawables(index) == D) {
911 D->Visible(Standard_False);
912 myDrawables.Remove(index);
919 //=======================================================================
920 //function : MakeDisplay
921 //purpose : return a display on the view
922 //=======================================================================
924 Draw_Display Draw_Viewer::MakeDisplay (const Standard_Integer id) const
926 if (Draw_Batch) {Draw_Display dis;return dis;}
928 curview = myViews[id];
930 Draw_Color initcol(Draw_blanc);
931 // to force setting the color
932 currentcolor = Draw_Color(Draw_rouge);
934 dis.SetColor(initcol);
935 dis.SetMode(0x3 /*GXcopy*/);
939 //=======================================================================
942 //=======================================================================
944 void Draw_Viewer::Select (Standard_Integer& id, Standard_Integer& X, Standard_Integer& Y,
945 Standard_Integer& Button, Standard_Boolean wait)
947 if (Draw_Batch) return;
948 id = X = Y = Button = 0;
949 Standard_Boolean hasView = Standard_False;
950 for (int aViewIter = 0; aViewIter < MAXVIEW; ++aViewIter)
952 if (myViews[aViewIter] != NULL
953 && myViews[aViewIter]->IsMapped())
955 hasView = Standard_True;
961 std::cerr << "No selection is possible with no open views\n";
965 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
967 if (id >=0 && id < MAXVIEW) {
968 if (myViews[id]) myViews[id]->Wait(wait);
972 for(int i=0 ; i<MAXVIEW ; i++)
973 if (myViews[i]) myViews[i]->Wait(wait);
976 Standard_Boolean again = Standard_True;
988 for (iv = 0; iv < MAXVIEW; iv++) {
990 if (myViews[iv]->win == ev.window)
994 if (wait || id == iv) {
1004 again = Standard_False;
1013 again = Standard_False;
1019 X = X - myViews[id]->GetDx();
1020 Y = -Y - myViews[id]->GetDy();
1022 if (!wait) myViews[id]->Wait(!wait);
1023 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1024 Standard_Integer aWindowNumber;
1027 while (id >= MAXVIEW)
1029 GetNextEvent(wait, aWindowNumber, X, Y, Button);
1033 continue; // mouse clicked on window title
1036 for (Standard_Integer anIter = 0; anIter < MAXVIEW; anIter++)
1038 if (myViews[anIter] && myViews[anIter]->IsEqualWindows (aWindowNumber))
1045 X = X - myViews[id]->GetDx();
1046 Y = -Y - myViews[id]->GetDy();
1051 id = MAXVIEW; //:abv 29.05.02: cycle for working in console mode
1052 while ( id >= MAXVIEW ) {
1054 Draw_Window::SelectWait(hWnd, X, Y, Button);
1056 Draw_Window::SelectNoWait(hWnd, X, Y, Button);
1058 // Recherche du numero de la vue grace au HANDLE
1059 for(int i=0 ; i<MAXVIEW ; i++)
1060 if (myViews[i] && myViews[i]->win == hWnd ) id = i;
1062 X = X - myViews[id]->GetDx();
1063 Y = -Y - myViews[id]->GetDy();
1067 //=======================================================================
1070 //=======================================================================
1072 Standard_Integer Draw_Viewer::Pick(const Standard_Integer id,
1073 const Standard_Integer X, const Standard_Integer Y, const Standard_Integer Prec,
1074 Handle(Draw_Drawable3D)& D,
1075 const Standard_Integer first) const
1077 if (Draw_Batch) return 0;
1078 if (myViews[id] == NULL)
1081 // is this the only view in its category
1082 Standard_Boolean is2d = myViews[id]->Is2D();
1083 Standard_Integer i,nbviews = 0;
1084 for (i = 0; i < MAXVIEW; i++)
1087 if (myViews[i]->Is2D() == is2d)
1090 Standard_Boolean only = (nbviews == 1);
1096 found = Standard_False;
1097 Standard_Real x1,x2,y1,y2;
1098 for (i = first+1; i <= myDrawables.Length(); i++) {
1099 Standard_Boolean reject = Standard_False;
1100 // rejection if only view
1102 myDrawables(i)->Bounds(x1,x2,y1,y2);
1103 if ((xpick+Prec < x1) || (xpick-Prec > x2) ||
1104 (ypick+Prec < y1) || (ypick-Prec > y2))
1105 reject = Standard_True;
1108 DrawOnView(id,myDrawables(i));
1114 found = Standard_False;
1115 if (i <= myDrawables.Length())
1122 //=======================================================================
1123 //function : LastPick
1125 //=======================================================================
1127 void Draw_Viewer::LastPick(gp_Pnt& P1, gp_Pnt& P2, Standard_Real& Param)
1129 if (Draw_Batch) return;
1132 Param = lastPickParam;
1135 //=======================================================================
1136 //function : ~Draw_Viewer
1138 //=======================================================================
1140 Draw_Viewer::~Draw_Viewer()
1142 if (Draw_Batch) return;
1143 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1147 //=======================================================================
1148 //function : operator<<
1150 //=======================================================================
1152 Draw_Viewer& Draw_Viewer::operator<<(const Handle(Draw_Drawable3D)& d3d)
1154 if (Draw_Batch) return *this;
1155 if (!d3d.IsNull()) {
1157 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1163 //=======================================================================
1164 //function : GetDrawables
1166 //=======================================================================
1167 const Draw_SequenceOfDrawable3D& Draw_Viewer::GetDrawables()
1172 // *******************************************************************
1174 // *******************************************************************
1179 if (Draw_Batch) return;
1180 if (highlight) curview->SetColor(highlightcol.ID());
1181 curview->DrawSegments(segm,nbseg);
1185 //=======================================================================
1186 //function : SetColor
1188 //=======================================================================
1190 void Draw_Display::SetColor (const Draw_Color& col) const
1192 if (Draw_Batch) return;
1193 if (col.ID() == currentcolor.ID()) return;
1196 switch (CurrentMode) {
1200 curview->SetColor(col.ID());
1204 (*ps_stream) << "stroke\nnewpath\n";
1205 (*ps_stream) << ps_width[col.ID()]<<" setlinewidth\n";
1206 (*ps_stream) << ps_gray[col.ID()]<<" setgray\n";
1213 //=======================================================================
1214 //function : SetMode
1216 //=======================================================================
1218 void Draw_Display::SetMode (const Standard_Integer M) const
1220 if (Draw_Batch) return;
1221 switch (CurrentMode) {
1225 curview->SetMode(M);
1234 //=======================================================================
1237 //=======================================================================
1239 Standard_Real Draw_Display::Zoom() const
1241 if (Draw_Batch) return 1.;
1242 return curview->GetZoom();
1245 //=======================================================================
1248 //=======================================================================
1250 void Draw_Display::Flush () const
1252 if (Draw_Batch) return;
1256 //=======================================================================
1257 //function : DrawString
1259 //=======================================================================
1261 void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1262 const Standard_CString S,
1263 const Standard_Real moveX,
1264 const Standard_Real moveY)
1266 if (Draw_Batch) return;
1267 if (ppt.X() > 1.e09 || ppt.X() < -1.e09 ) return;
1268 if (ppt.Y() > 1.e09 || ppt.Y() < -1.e09 ) return;
1270 gp_Pnt2d pt(ppt.X()*curview->GetZoom(),ppt.Y()*curview->GetZoom());
1272 if (pt.X() > 1.e09 || pt.X() < -1.e09 ) return;
1273 if (pt.Y() > 1.e09 || pt.Y() < -1.e09 ) return;
1275 switch (CurrentMode) {
1279 int X = (int) ( pt.X() + moveX + curview->GetDx());
1280 int Y = (int) (-pt.Y() + moveY - curview->GetDy());
1281 curview->DrawString(X,Y,(char *)S);
1283 if (pt.X() + moveX > xmax) xmax = pt.X();
1284 if (pt.X() + moveX < xmin) xmin = pt.X();
1285 if (-pt.Y() - moveY > ymax) ymax = -pt.Y();
1286 if (-pt.Y() - moveY < ymin) ymin = -pt.Y();
1293 Standard_Integer x = (Standard_Integer )( (pt.X() + moveX - ps_vx) * ps_kx + ps_px);
1294 Standard_Integer y = (Standard_Integer )( (pt.Y() + moveY - ps_vy) * ps_ky + ps_py);
1295 (*ps_stream) <<"stroke\n";
1296 (*ps_stream) << x << " " << y << " m\n";
1297 (*ps_stream) <<"("<<S<<") show\nnewpath\n";
1306 //=======================================================================
1307 //function : DrawString
1309 //=======================================================================
1311 void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1312 const Standard_CString S)
1314 if (Draw_Batch) return;
1315 DrawString(ppt,S,0.0,0.0);
1318 //=======================================================================
1319 //function : DrawString
1321 //=======================================================================
1323 void Draw_Display::DrawString(const gp_Pnt& pt,
1324 const Standard_CString S,
1325 const Standard_Real moveX,
1326 const Standard_Real moveY)
1328 if (Draw_Batch) return;
1329 DrawString(Project(pt),S,moveX,moveY);
1332 //=======================================================================
1333 //function : DrawString
1335 //=======================================================================
1337 void Draw_Display::DrawString(const gp_Pnt& pt,
1338 const Standard_CString S)
1340 if (Draw_Batch) return;
1341 DrawString(Project(pt),S,0.0,0.0);
1345 // *******************************************************************
1346 // Drawing data static variables
1347 // *******************************************************************
1348 static gp_Pnt2d PtCur; // current 2D point
1349 static gp_Pnt PtPers; // current 3D point for Pers
1351 //=======================================================================
1352 //function : Project
1354 //=======================================================================
1356 void Draw_Display::Project(const gp_Pnt& p, gp_Pnt2d& p2d) const
1358 if (Draw_Batch) return;
1360 pt.Transform(curview->GetMatrix());
1361 Standard_Real xp,yp,zp;
1363 if (curview->IsPerspective()) {
1364 const Standard_Real aDistance = curview->GetFocalDistance();
1365 xp = xp * aDistance / (aDistance-zp);
1366 yp = yp * aDistance / (aDistance-zp);
1368 p2d.SetCoord(xp,yp);
1371 //=======================================================================
1372 //function : Draw_Display
1374 //=======================================================================
1376 Draw_Display::Draw_Display ()
1378 if (Draw_Batch) return;
1380 PtPers.SetCoord(0., 0., 0.);
1381 PtPers.Transform(curview->GetMatrix());
1382 PtCur.SetCoord(PtPers.X()*curview->GetZoom(),PtPers.Y()*curview->GetZoom());
1386 //=======================================================================
1387 //function : MoveTo 2D
1389 //=======================================================================
1391 void Draw_Display::MoveTo (const gp_Pnt2d& pp)
1393 if (Draw_Batch) return;
1394 const Standard_Real aZoom = curview->GetZoom();
1395 gp_Pnt2d pt(pp.X() * aZoom, pp.Y() * aZoom);
1396 switch (CurrentMode) {
1401 if (pt.X() > xmax) xmax = pt.X();
1402 if (pt.X() < xmin) xmin = pt.X();
1403 if (pt.Y() > ymax) ymax = pt.Y();
1404 if (pt.Y() < ymin) ymin = pt.Y();
1414 Standard_Integer x = (Standard_Integer )( (pt.X() - ps_vx) * ps_kx + ps_px);
1415 Standard_Integer y = (Standard_Integer )( (pt.Y() - ps_vy) * ps_ky + ps_py);
1416 (*ps_stream) <<"stroke\nnewpath\n"<< x << " " << y << " m\n";
1422 //=======================================================================
1423 //function : DrawTo 2D
1425 //=======================================================================
1426 inline Standard_Integer CalculRegion(const Standard_Real x,
1427 const Standard_Real y,
1428 const Standard_Real x1,
1429 const Standard_Real y1,
1430 const Standard_Real x2,
1431 const Standard_Real y2) {
1433 if(x<x1) { r=1; } else { if(x>x2) { r=2; } else { r=0; } }
1434 if(y<y1) { r|=4; } else { if(y>y2) { r|=8; } }
1438 Standard_Boolean Trim(gp_Pnt2d& P1,gp_Pnt2d& P2,
1443 Standard_Real xa=P1.X(),ya=P1.Y(),xb=P2.X(),yb=P2.Y();
1445 Standard_Integer regiona=0,regionb=0;
1446 regiona = CalculRegion(xa,ya,x0,y0,x1,y1);
1447 regionb = CalculRegion(xb,yb,x0,y0,x1,y1);
1448 if((regiona & regionb)==0) {
1449 Standard_Real dx=xb-xa;
1450 Standard_Real dy=yb-ya;
1451 Standard_Real dab=sqrt(dx*dx+dy*dy);
1452 if(dab<1e-10) return(Standard_False);
1456 Standard_Real xm,ym,mfenx,mfeny;
1457 mfenx=xm=0.5*(x0+x1);
1458 mfeny=ym=0.5*(y0+y1);
1460 Standard_Real d=sqrt(x1*x1+y1*y1) * 2;
1462 Standard_Real p=(xm-xa)*dx+(ym-ya)*dy;
1467 gp_Pnt2d MFen(mfenx,mfeny);
1468 if(MFen.SquareDistance(Pm) > d*d) return(Standard_False);
1470 Standard_Real PmDistP1 = Pm.Distance(P1);
1471 Standard_Real PmDistP2 = Pm.Distance(P2);
1473 Standard_Real amab = (xm-xa)*(xb-xa)+(ym-ya)*(yb-ya);
1475 if(amab > 0) { //-- M est compris entre A et B
1477 P1.SetCoord(xm-d*dx,ym-d*dy);
1480 P2.SetCoord(xm+d*dx,ym+d*dy);
1483 else if(PmDistP1 < PmDistP2) { //-- On a M P1 P2
1485 P2.SetCoord(xm+d*dx,ym+d*dy);
1488 else { //-- On a P1 P2 M
1490 P1.SetCoord(xm-d*dx,ym-d*dy);
1493 return(Standard_True);
1495 else return(Standard_False);
1501 void Draw_Display::DrawTo (const gp_Pnt2d& pp2)
1503 if (Draw_Batch) return;
1504 if (pp2.X() > 1.e09 || pp2.X() < -1.e09 ) return;
1505 if (pp2.Y() > 1.e09 || pp2.Y() < -1.e09 ) return;
1507 gp_Pnt2d p2(pp2.X() * curview->GetZoom(), pp2.Y() * curview->GetZoom());
1509 if (p2.X() > 1.e09 || p2.X() < -1.e09 ) return;
1510 if (p2.Y() > 1.e09 || p2.Y() < -1.e09 ) return;
1512 gp_Pnt2d p1 = PtCur;
1513 if (p1.X() > 1.e09 || p1.X() < -1.e09 ) return;
1514 if (p1.Y() > 1.e09 || p1.Y() < -1.e09 ) return;
1518 switch (CurrentMode) {
1523 Standard_Integer x0,y0,x1,y1;
1524 curview->GetFrame(x0,y0,x1,y1);
1527 //Standard_Integer qx0,qy0,qx1,qy1;
1528 //curview->viewer->GetFrame(curview->id,qx0,qy0,qx1,qy1);
1529 //if(qx0!=x0 || qx1!=x1 || qy0!=y0 || qy1!=y1) {
1530 // x0=qx0; x1=qx1; y0=qy0; y1=qy1;
1538 if(Trim(PI1,PI2,x0,y0,x1,y1))
1540 segm[nbseg].Init(static_cast<Standard_Integer>( PI1.X() + curview->GetDx()),
1541 static_cast<Standard_Integer>(-PI1.Y() - curview->GetDy()),
1542 static_cast<Standard_Integer>( PI2.X() + curview->GetDx()),
1543 static_cast<Standard_Integer>(-PI2.Y() - curview->GetDy()));
1547 segm[nbseg].Init(static_cast<Standard_Integer>( p1.X() + curview->GetDx()),
1548 static_cast<Standard_Integer>(-p1.Y() - curview->GetDy()),
1549 static_cast<Standard_Integer>( p2.X() + curview->GetDx()),
1550 static_cast<Standard_Integer>(-p2.Y() - curview->GetDy()));
1553 if (nbseg == MAXSEGMENT) {
1557 if (p2.X() > xmax) xmax = p2.X();
1558 if (p2.X() < xmin) xmin = p2.X();
1559 if (p2.Y() > ymax) ymax = p2.Y();
1560 if (p2.Y() < ymin) ymin = p2.Y();
1567 Standard_Integer x1 = (int) p1.X() ;
1568 Standard_Integer y1 = (int) p1.Y() ;
1569 Standard_Integer x2 = (int) p2.X() ;
1570 Standard_Integer y2 = (int) p2.Y() ;
1571 if ((x1 >= xpick + precpick) && (x2 >= xpick + precpick)) break;
1572 if ((x1 <= xpick - precpick) && (x2 <= xpick - precpick)) break;
1573 if ((y1 >= ypick + precpick) && (y2 >= ypick + precpick)) break;
1574 if ((y1 <= ypick - precpick) && (y2 <= ypick - precpick)) break;
1576 Standard_Boolean inside = Standard_True;
1577 if ((x1 > xpick + precpick) || (x2 > xpick + precpick)) {
1578 Standard_Real y = (Standard_Real) y1 +
1579 (Standard_Real) (y2-y1) * (Standard_Real) (xpick+precpick-x1) /
1580 (Standard_Real) (x2 - x1);
1581 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1582 found = Standard_True;
1583 lastPickParam = (Standard_Real) (xpick - x1) /
1584 (Standard_Real) (x2 - x1);
1588 inside = Standard_False;
1591 if ((x1 < xpick - precpick) || (x2 < xpick - precpick)) {
1592 Standard_Real y = (Standard_Real) y1 +
1593 (Standard_Real) (y2-y1) * (Standard_Real) (xpick-precpick-x1) /
1594 (Standard_Real) (x2 - x1);
1595 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1596 found = Standard_True;
1597 lastPickParam = (Standard_Real) (xpick - x1) /
1598 (Standard_Real) (x2 - x1);
1602 inside = Standard_False;
1606 if ((y1 > ypick + precpick) || (y2 > ypick + precpick)) {
1607 Standard_Real x = (Standard_Real) x1 +
1608 (Standard_Real) (x2-x1) * (Standard_Real) (ypick+precpick-y1) /
1609 (Standard_Real) (y2 - y1);
1610 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1611 found = Standard_True;
1612 lastPickParam = (Standard_Real) (ypick - y1) /
1613 (Standard_Real) (y2 - y1);
1617 inside = Standard_False;
1621 if ((y1 < ypick - precpick) || (y2 < ypick - precpick)) {
1622 Standard_Real x = (Standard_Real) x1 +
1623 (Standard_Real) (x2-x1) * (Standard_Real) (ypick-precpick-y1) /
1624 (Standard_Real) (y2 - y1);
1625 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1626 found = Standard_True;
1627 lastPickParam = (Standard_Real) (ypick - y1) /
1628 (Standard_Real) (y2 - y1);
1632 inside = Standard_False;
1634 found = found || inside;
1636 if (Abs(x2-x1) > Abs(y2-y1)) {
1637 if (Abs(x2-x1) < 1e-5) lastPickParam = 0;
1639 lastPickParam = (Standard_Real)(xpick - x1) /
1640 (Standard_Real)(x2 - x1);
1643 if (Abs(y2-y1) < 1e-5) lastPickParam = 0;
1645 lastPickParam = (Standard_Real)(ypick - y1) /
1646 (Standard_Real)(y2 - y1);
1654 Standard_Integer x = (Standard_Integer )( (p2.X() - ps_vx) * ps_kx + ps_px);
1655 Standard_Integer y = (Standard_Integer )( (p2.Y() - ps_vy) * ps_ky + ps_py);
1656 (*ps_stream) << x << " " << y << " l\n";
1663 //=======================================================================
1666 //=======================================================================
1668 void Draw_Display::MoveTo (const gp_Pnt& pt)
1670 if (Draw_Batch) return;
1671 if (CurrentMode == PICK) {
1672 if (!found) lastPickP1 = pt;
1676 PtPers.Transform(curview->GetMatrix());
1677 Standard_Real xp = PtPers.X();
1678 Standard_Real yp = PtPers.Y();
1679 if (curview->IsPerspective())
1681 Standard_Real ZPers = PtPers.Z();
1682 const Standard_Real aDistance = curview->GetFocalDistance();
1683 if (ZPers < aDistance * precpers)
1685 xp=xp * aDistance / (aDistance-ZPers);
1686 yp=yp * aDistance / (aDistance-ZPers);
1689 MoveTo(gp_Pnt2d(xp,yp));
1692 //=======================================================================
1695 //=======================================================================
1697 void Draw_Display::DrawTo (const gp_Pnt& pt)
1699 if (Draw_Batch) return;
1700 if ((CurrentMode == PICK) && found) return;
1702 gp_Pnt pt2 = pt.Transformed(curview->GetMatrix());
1703 Standard_Real xp2 = pt2.X();
1704 Standard_Real yp2 = pt2.Y();
1706 if (curview->IsPerspective())
1708 const Standard_Real aZoom = curview->GetZoom();
1709 const Standard_Real aDistance = curview->GetFocalDistance();
1711 Standard_Real xp1 = PtPers.X();
1712 Standard_Real yp1 = PtPers.Y();
1713 Standard_Real zp1 = PtPers.Z();
1714 Standard_Real zp2 = pt2.Z();
1716 if ((zp1 >= aDistance*precpers) && (zp2 >= aDistance*precpers) )
1718 return; // segment is not visible in perspective (behind the eye)
1720 else if (zp1 >= aDistance*precpers)
1722 xp1=xp1+(xp2-xp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1723 yp1=yp1+(yp2-yp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1724 zp1=aDistance*precpers;
1725 xp1=xp1*aDistance/(aDistance-zp1);
1726 yp1=yp1*aDistance/(aDistance-zp1);
1727 MoveTo( gp_Pnt2d(xp1 * aZoom, yp1 * aZoom) );
1729 else if (zp2 >= aDistance*precpers)
1731 xp2=xp2+(xp1-xp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1732 yp2=yp2+(yp1-yp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1733 zp2=aDistance*precpers;
1735 xp2 = xp2 * aDistance / (aDistance - zp2);
1736 yp2 = yp2 * aDistance / (aDistance - zp2);
1738 DrawTo(gp_Pnt2d(xp2,yp2));
1739 if (CurrentMode == PICK) {
1740 if (!found) lastPickP1 = pt;
1741 else lastPickP2 = pt;
1745 //=======================================================================
1748 //=======================================================================
1750 void Draw_Display::Draw (const gp_Pnt& p1, const gp_Pnt& p2)
1752 if (Draw_Batch) return;
1757 //=======================================================================
1760 //=======================================================================
1762 void Draw_Display::Draw(const gp_Pnt2d& p1, const gp_Pnt2d& p2)
1764 if (Draw_Batch) return;
1770 //=======================================================================
1773 //=======================================================================
1775 Standard_Integer Draw_Display::ViewId() const
1777 if (Draw_Batch) return 0;
1782 //=======================================================================
1783 //function : HasPicked
1785 //=======================================================================
1787 Standard_Boolean Draw_Display::HasPicked() const
1789 if (Draw_Batch) return Standard_False;