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 // Updated by GG Tue Oct 22 16:22:10 1996
18 // reason : Try to compress the pixel image
19 // in PseudoColor 8 planes format
20 // see : SaveView(filename)
22 #include <Draw_Viewer.hxx>
23 #include <Draw_View.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <Draw_Window.hxx>
28 #include <Draw_Display.hxx>
33 #define MotionNotify 6
34 static const Standard_Real DRAWINFINITE = 1e50;
35 Standard_EXPORT Standard_Boolean Draw_Bounds = Standard_True;
36 extern Standard_Boolean Draw_Batch;
37 const Standard_Integer MAXSEGMENT = 1000;
38 Segment segm[MAXSEGMENT];
40 static Draw_View* curview = NULL;
41 static Standard_Integer curviewId = 0;
42 static char blank[2] = "";
43 static Standard_Real xmin,xmax,ymin,ymax;
44 static Standard_Boolean found = Standard_False;
45 static Standard_Integer xpick, ypick, precpick;
46 static gp_Pnt lastPickP1;
47 static gp_Pnt lastPickP2;
48 static Standard_Real lastPickParam;
49 static Draw_Color highlightcol;
50 static Draw_Color currentcolor;
51 static Standard_Boolean highlight = Standard_False;
52 static Standard_Integer ps_vx, ps_vy;
53 static Standard_Real ps_kx, ps_ky;
54 static Standard_Integer ps_px, ps_py;
55 static ostream* ps_stream;
56 static Standard_Integer ps_width[MAXCOLOR];
57 static Standard_Real ps_gray[MAXCOLOR];
59 enum DrawingMode {DRAW, PICK, POSTSCRIPT};
60 static DrawingMode CurrentMode = DRAW;
62 //=======================================================================
65 //=======================================================================
67 Draw_Viewer::Draw_Viewer()
69 if (Draw_Batch) return;
71 for ( i = 0; i < MAXVIEW; i++) myViews[i] = NULL;
72 for (i = 0; i < MAXCOLOR; i++) {
78 //=======================================================================
79 //function : DefineColor
81 //=======================================================================
83 Standard_Boolean Draw_Viewer::DefineColor (const Standard_Integer i, const char* colname)
85 if (Draw_Batch) return 1;
86 return Draw_Window::DefineColor(i,colname);
90 //=======================================================================
93 //=======================================================================
95 void Draw_Viewer::MakeView(const Standard_Integer id,
97 const Standard_Integer X, const Standard_Integer Y,
98 const Standard_Integer W, const Standard_Integer H)
100 if (Draw_Batch) return;
104 myViews[id] = new Draw_View(id,this,X , Y, W, H);
107 myViews[id]->SetDx(W / 2);
108 myViews[id]->SetDy(- H / 2);
110 if (!myViews[id]->Init(typ))
118 //=======================================================================
119 //function : MakeView
121 //=======================================================================
123 void Draw_Viewer::MakeView(const Standard_Integer id,
125 const Standard_Integer X, const Standard_Integer Y,
126 const Standard_Integer W, const Standard_Integer H,
127 HWND win, Standard_Boolean useBuffer)
129 if (Draw_Batch) return;
133 myViews[id] = new Draw_View(id, this, X, Y, W, H, win);
134 myViews[id]->SetUseBuffer(useBuffer);
137 myViews[id]->SetDx( W / 2);
138 myViews[id]->SetDy(-H / 2);
140 if (!myViews[id]->Init(typ))
147 //=======================================================================
148 //function : MakeView
150 //=======================================================================
152 void Draw_Viewer::MakeView (const Standard_Integer id,
156 if (Draw_Batch) return;
160 myViews[id] = new Draw_View(id,this,window);
163 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
164 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
166 if (!myViews[id]->Init(typ))
174 //=======================================================================
175 //function : SetTitle
177 //=======================================================================
179 void Draw_Viewer::SetTitle (const Standard_Integer id, const char* name)
181 if (Draw_Batch) return;
182 if(myViews[id]) myViews[id]->SetTitle((char*)name);
185 //=======================================================================
186 //function : ResetView
187 //purpose : reset view zoom and axes
188 //=======================================================================
190 void Draw_Viewer::ResetView(const Standard_Integer id)
192 if (Draw_Batch) return;
194 myViews[id]->Init(myViews[id]->Type());
199 //=======================================================================
202 //=======================================================================
204 void Draw_Viewer::SetZoom (const Standard_Integer id, const Standard_Real z)
209 Draw_View* aView = myViews[id];
212 Standard_Real zz = z / aView->GetZoom();
214 Standard_Integer X,Y,W,H;
215 GetPosSize(id,X,Y,W,H);
217 const Standard_Real w = 0.5 * static_cast<Standard_Real>(W);
218 const Standard_Real h = 0.5 * static_cast<Standard_Real>(H);
220 const Standard_Integer aDx = static_cast<Standard_Integer>
221 ( w - zz * (w - aView->GetDx()) );
222 const Standard_Integer aDy = static_cast<Standard_Integer>
223 ( -h + zz * (h + aView->GetDy()) );
230 //=======================================================================
231 //function : RotateView
233 //=======================================================================
235 void Draw_Viewer::RotateView (const Standard_Integer id,
237 const Standard_Real A)
239 if (Draw_Batch) return;
241 gp_Trsf T = myViews[id]->GetMatrix();
245 gp_Dir DD(D.X(),D.Y(),0);
248 RotateView(id,PP,DD,A);
252 //=======================================================================
253 //function : RotateView
255 //=======================================================================
257 void Draw_Viewer::RotateView (const Standard_Integer id,
260 const Standard_Real A)
262 if (Draw_Batch) return;
265 T.SetRotation(gp_Ax1(P,D),A);
266 myViews[id]->Transform(T);
271 //=======================================================================
272 //function : SetFocal
274 //=======================================================================
276 void Draw_Viewer::SetFocal (const Standard_Integer id, const Standard_Real F)
278 if (Draw_Batch) return;
280 myViews[id]->SetFocalDistance(F);
283 //=======================================================================
286 //=======================================================================
288 char* Draw_Viewer::GetType (const Standard_Integer id) const
290 if (Draw_Batch) return blank;
292 return const_cast<char*>(myViews[id]->Type());
297 //=======================================================================
300 //=======================================================================
302 Standard_Real Draw_Viewer::Zoom (const Standard_Integer id) const
304 if (Draw_Batch) return Standard_False;
306 return myViews[id]->GetZoom();
311 //=======================================================================
314 //=======================================================================
316 Standard_Real Draw_Viewer::Focal (const Standard_Integer id) const
318 if (Draw_Batch) return 1.;
320 return myViews[id]->GetFocalDistance();
325 //=======================================================================
328 //=======================================================================
330 void Draw_Viewer::GetTrsf (const Standard_Integer id,gp_Trsf& T) const
332 if (Draw_Batch) return;
334 T = myViews[id]->GetMatrix();
337 //=======================================================================
340 //=======================================================================
342 Standard_Boolean Draw_Viewer::Is3D (const Standard_Integer id) const
344 if (Draw_Batch) return Standard_False;
346 return !myViews[id]->Is2D();
348 return Standard_False;
351 //=======================================================================
354 //=======================================================================
356 void Draw_Viewer::SetTrsf (const Standard_Integer id,gp_Trsf& T)
358 if (Draw_Batch) return;
360 myViews[id]->SetMatrix(T);
363 //=======================================================================
364 //function : GetPosSize
366 //=======================================================================
368 void Draw_Viewer::GetPosSize(const Standard_Integer id,
369 Standard_Integer& X, Standard_Integer& Y,
370 Standard_Integer& W, Standard_Integer& H)
372 if (Draw_Batch) return;
373 if (myViews[id] != NULL) {
374 myViews[id]->GetPosition(X, Y);
375 W = myViews[id]->WidthWin();
376 H = myViews[id]->HeightWin();
380 //=======================================================================
381 //function : GetFrame
383 //=======================================================================
385 void Draw_Viewer::GetFrame(const Standard_Integer id,
386 Standard_Integer& xminf, Standard_Integer& yminf,
387 Standard_Integer& xmaxf, Standard_Integer& ymaxf)
389 if (Draw_Batch) return;
391 Standard_Integer X,Y,H,W;
392 GetPosSize(id,X,Y,W,H);
393 xminf = - myViews[id]->GetDx();
394 xmaxf = W - myViews[id]->GetDx();
395 yminf = - myViews[id]->GetDy() - H;
396 ymaxf = - myViews[id]->GetDy();
400 //=======================================================================
403 //=======================================================================
405 void Draw_Viewer::FitView(const Standard_Integer id, const Standard_Integer frame)
407 if (Draw_Batch) return;
410 // is this the only view in its category
411 Standard_Boolean is2d = myViews[id]->Is2D();
412 Standard_Integer i,nbviews = 0;
413 for (i = 1; i < MAXVIEW; i++) {
415 if (myViews[i]->Is2D() == is2d)
419 Standard_Boolean only = (nbviews == 1);
421 Standard_Integer X,Y,H,W;
422 GetPosSize(id,X,Y,W,H);
423 // compute the min max
424 Standard_Integer n = myDrawables.Length();
427 curview = myViews[id];
428 Standard_Real umin,umax,vmin,vmax;
429 Standard_Real u1,u2,v1,v2;
430 umin = vmin = DRAWINFINITE;
431 umax = vmax = -DRAWINFINITE;
433 for (i = 1; i <= n; i++) {
434 Standard_Boolean d3d = myDrawables(i)->Is3D();
435 if ((d3d && !is2d) || (!d3d && is2d)) {
436 // if this is not the only view recompute...
438 DrawOnView(id,myDrawables(i));
439 myDrawables(i)->Bounds(u1,u2,v1,v2);
440 if (u1 < umin) umin = u1;
441 if (u2 > umax) umax = u2;
442 if (v1 < vmin) vmin = v1;
443 if (v2 > vmax) vmax = v2;
447 umin = umin / curview->GetZoom();
448 vmin = vmin / curview->GetZoom();
449 umax = umax / curview->GetZoom();
450 vmax = vmax / curview->GetZoom();
451 if ((umax - umin) < 1.e-6) {
452 if ((vmax - vmin) < 1.e-6)
455 z = ((Standard_Real)(H - 2*frame)) / (vmax - vmin);
458 z = ((Standard_Real)(W - 2*frame)) /((Standard_Real) (umax - umin));
459 if ((vmax - vmin) > 1.e-6) {
460 Standard_Real z2 = ((Standard_Real)(H - 2*frame)) /(vmax - vmin);
465 curview->SetDx( static_cast<Standard_Integer>( W / 2 - 0.5 * (umin+umax) * z) );
466 curview->SetDy( static_cast<Standard_Integer>(-H / 2 - 0.5 * (vmin+vmax) * z) );
470 //=======================================================================
473 //=======================================================================
475 void Draw_Viewer::PanView(const Standard_Integer id,
476 const Standard_Integer DX, const Standard_Integer DY)
478 if (Draw_Batch) return;
480 myViews[id]->SetDx(myViews[id]->GetDx() + DX);
481 myViews[id]->SetDy(myViews[id]->GetDy() + DY);
486 //=======================================================================
489 //=======================================================================
491 void Draw_Viewer::SetPan(const Standard_Integer id,
492 const Standard_Integer DX, const Standard_Integer DY)
494 if (Draw_Batch) return;
496 myViews[id]->SetDx(DX);
497 myViews[id]->SetDy(DY);
501 //=======================================================================
504 //=======================================================================
506 void Draw_Viewer::GetPan(const Standard_Integer id,
507 Standard_Integer& DX, Standard_Integer& DY)
509 if (Draw_Batch) return;
511 DX = myViews[id]->GetDx();
512 DY = myViews[id]->GetDy();
516 //=======================================================================
519 //=======================================================================
521 Standard_Boolean Draw_Viewer::HasView(const Standard_Integer id) const
523 if (Draw_Batch) return Standard_False;
524 if ((id < 0) || id >= MAXVIEW) return Standard_False;
525 return myViews[id] != NULL;
528 //=======================================================================
529 //function : DisplayView
531 //=======================================================================
533 void Draw_Viewer::DisplayView (const Standard_Integer id) const
535 if (Draw_Batch) return;
536 if (myViews[id]) myViews[id]->DisplayWindow();
539 //=======================================================================
540 //function : HideView
542 //=======================================================================
544 void Draw_Viewer::HideView (const Standard_Integer id) const
546 if (Draw_Batch) return;
552 //=======================================================================
553 //function : ClearView
555 //=======================================================================
557 void Draw_Viewer::ClearView(const Standard_Integer id) const
559 if (Draw_Batch) return;
560 if (myViews[id]) myViews[id]->Clear();
563 //=======================================================================
564 //function : RemoveView
566 //=======================================================================
568 void Draw_Viewer::RemoveView(const Standard_Integer id)
570 if (Draw_Batch) return;
577 //=======================================================================
578 //function : RepaintView
580 //=======================================================================
581 void Draw_Viewer::RepaintView (const Standard_Integer id) const
583 if (Draw_Batch) return;
586 Standard_Integer n = myDrawables.Length();
587 for (Standard_Integer i = 1; i <= n; i++)
588 DrawOnView(id,myDrawables(i));
594 //=======================================================================
595 //function : ResizeView
596 //purpose : WNT re-drawing optimization
597 //=======================================================================
598 void Draw_Viewer::ResizeView (const Standard_Integer id) const
600 if (Draw_Batch) return;
601 if (myViews[id] && myViews[id]->GetUseBuffer()) {
602 myViews[id]->InitBuffer();
607 //=======================================================================
608 //function : UpdateView
609 //purpose : WNT re-drawing optimization
610 //=======================================================================
611 void Draw_Viewer::UpdateView (const Standard_Integer id, const Standard_Boolean forced) const
613 if (Draw_Batch) return;
615 if (!myViews[id]->GetUseBuffer() || forced) {
618 // Fast redrawing on WNT
619 if (myViews[id]->GetUseBuffer()) myViews[id]->Redraw();
624 //=======================================================================
625 //function : ConfigView
627 //=======================================================================
629 void Draw_Viewer::ConfigView (const Standard_Integer id) const
631 if (Draw_Batch) return;
634 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
635 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
639 //=======================================================================
640 //function : PostScriptView
642 //=======================================================================
644 void Draw_Viewer::PostScriptView (const Standard_Integer id,
645 const Standard_Integer VXmin,
646 const Standard_Integer VYmin,
647 const Standard_Integer VXmax,
648 const Standard_Integer VYmax,
649 const Standard_Integer PXmin,
650 const Standard_Integer PYmin,
651 const Standard_Integer PXmax,
652 const Standard_Integer PYmax,
653 ostream& sortie) const
655 if (Draw_Batch) return;
661 ps_kx = ((Standard_Real) (PXmax - PXmin)) / ((Standard_Real) (VXmax - VXmin));
662 ps_ky = ((Standard_Real) (PYmax - PYmin)) / ((Standard_Real) (VYmax - VYmin));
664 Standard_Integer n = myDrawables.Length();
666 CurrentMode = POSTSCRIPT;
667 Draw_Display DF = MakeDisplay(id);
668 Standard_Boolean view2d = myViews[id]->Is2D();
669 for (Standard_Integer i = 1; i <= n; i++)
670 if (myDrawables(i)->Is3D()) {
671 if (!view2d) myDrawables(i)->DrawOn(DF);
674 if (view2d) myDrawables(i)->DrawOn(DF);
676 sortie << "stroke\n";
681 //=======================================================================
682 //function : PostColor
684 //=======================================================================
686 void Draw_Viewer::PostColor(const Standard_Integer icol,
687 const Standard_Integer width,
688 const Standard_Real gray)
690 if (Draw_Batch) return;
691 if ((icol < 0) || (icol >= MAXCOLOR)) return;
692 ps_width[icol] = width;
693 ps_gray[icol] = gray;
696 //=======================================================================
697 //function : SaveView
699 //=======================================================================
701 Standard_Boolean Draw_Viewer::SaveView(const Standard_Integer id,
702 const char* filename)
704 if (Draw_Batch) return Standard_False;;
707 return myViews[id]->Save(filename);
711 std::cerr << "View " << id << " doesn't exists!\n";
712 return Standard_False;
716 //=======================================================================
717 //function : RepaintAll
719 //=======================================================================
721 void Draw_Viewer::RepaintAll () const
723 if (Draw_Batch) return;
724 for (Standard_Integer id = 0; id < MAXVIEW; id++)
728 //=======================================================================
729 //function : Repaint2D
731 //=======================================================================
733 void Draw_Viewer::Repaint2D () const
735 if (Draw_Batch) return;
736 for (Standard_Integer id = 0; id < MAXVIEW; id++)
738 if (myViews[id]->Is2D())
743 //=======================================================================
744 //function : Repaint3D
746 //=======================================================================
748 void Draw_Viewer::Repaint3D () const
750 if (Draw_Batch) return;
751 for (Standard_Integer id = 0; id < MAXVIEW; id++)
753 if (!myViews[id]->Is2D())
758 //=======================================================================
759 //function : DeleteView
761 //=======================================================================
763 void Draw_Viewer::DeleteView(const Standard_Integer id)
765 if (Draw_Batch) return;
766 if (myViews[id] != NULL) {
772 //=======================================================================
775 //=======================================================================
777 void Draw_Viewer::Clear()
779 if (Draw_Batch) return;
780 for (Standard_Integer i = 1; i <= myDrawables.Length(); i++)
781 myDrawables(i)->Visible(Standard_False);
783 for (Standard_Integer id = 0; id < MAXVIEW; id++)
787 //=======================================================================
790 //=======================================================================
792 void Draw_Viewer::Clear2D()
794 if (Draw_Batch) return;
795 Standard_Integer i = 1;
796 while (i <= myDrawables.Length()) {
797 if (myDrawables(i)->Is3D())
800 myDrawables(i)->Visible(Standard_False);
801 myDrawables.Remove(i);
804 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
806 if (myViews[id]->Is2D())
812 //=======================================================================
815 //=======================================================================
817 void Draw_Viewer::Clear3D()
819 if (Draw_Batch) return;
820 Standard_Integer i = 1;
821 while (i <= myDrawables.Length()) {
822 if (myDrawables(i)->Is3D()) {
823 myDrawables(i)->Visible(Standard_False);
824 myDrawables.Remove(i);
829 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
831 if (!myViews[id]->Is2D())
837 //=======================================================================
840 //=======================================================================
842 void Draw_Viewer::Flush()
844 if (Draw_Batch) return;
845 Draw_Window::Flush();
848 //=======================================================================
849 //function : DrawOnView
851 //=======================================================================
853 void Draw_Viewer::DrawOnView(const Standard_Integer id,
854 const Handle(Draw_Drawable3D)& D) const
856 if (Draw_Batch) return;
858 Draw_Display d = MakeDisplay(id);
859 xmin = ymin = DRAWINFINITE;
860 xmax = ymax = -DRAWINFINITE;
862 Standard_Boolean view2d = myViews[id]->Is2D();
863 myViews[id]->ResetFrame();
864 if ((D->Is3D() && !view2d) || (!D->Is3D() && view2d))
867 if (CurrentMode == DRAW)
868 D->SetBounds(xmin,xmax,ymin,ymax);
874 //=======================================================================
875 //function : HighlightOnView
877 //=======================================================================
879 void Draw_Viewer::HighlightOnView (const Standard_Integer id,
880 const Handle(Draw_Drawable3D)& D,
881 const Draw_ColorKind C) const
883 if (Draw_Batch) return;
884 highlight = Standard_True;
887 highlight = Standard_False;
890 //=======================================================================
891 //function : AddDrawable
893 //=======================================================================
895 void Draw_Viewer::AddDrawable (const Handle(Draw_Drawable3D)& D)
897 if (Draw_Batch) return;
898 if (!D.IsNull() && !D->Visible()) {
899 myDrawables.Append(D);
900 D->Visible(Standard_True);
904 //=======================================================================
905 //function : RemoveDrawable
907 //=======================================================================
909 void Draw_Viewer::RemoveDrawable (const Handle(Draw_Drawable3D)& D)
911 if (Draw_Batch) return;
912 if (!D.IsNull() && D->Visible()) {
913 Standard_Integer index;
914 for (index = 1; index <= myDrawables.Length(); index++) {
915 if (myDrawables(index) == D) {
916 D->Visible(Standard_False);
917 myDrawables.Remove(index);
924 //=======================================================================
925 //function : MakeDisplay
926 //purpose : return a display on the view
927 //=======================================================================
929 Draw_Display Draw_Viewer::MakeDisplay (const Standard_Integer id) const
931 if (Draw_Batch) {Draw_Display dis;return dis;}
933 curview = myViews[id];
936 Draw_Color initcol(Draw_blanc);
937 // to force setting the color
938 currentcolor = Draw_Color(Draw_rouge);
940 dis.SetColor(initcol);
945 //=======================================================================
948 //=======================================================================
949 void Draw_Viewer::Select (Standard_Integer& id, Standard_Integer& X, Standard_Integer& Y,
950 Standard_Integer& Button, Standard_Boolean wait)
952 if (Draw_Batch) return;
954 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
956 if (id >=0 && id < MAXVIEW) {
957 if (myViews[id]) myViews[id]->Wait(wait);
961 for(int i=0 ; i<MAXVIEW ; i++)
962 if (myViews[i]) myViews[i]->Wait(wait);
965 Standard_Boolean again = Standard_True;
977 for (iv = 0; iv < MAXVIEW; iv++) {
979 if (myViews[iv]->win == ev.window)
983 if (wait || id == iv) {
993 again = Standard_False;
1002 again = Standard_False;
1008 X = X - myViews[id]->GetDx();
1009 Y = -Y - myViews[id]->GetDy();
1011 if (!wait) myViews[id]->Wait(!wait);
1012 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1013 Standard_Integer aWindowNumber;
1016 while (id >= MAXVIEW)
1018 GetNextEvent(wait, aWindowNumber, X, Y, Button);
1022 continue; // mouse clicked on window title
1025 for (Standard_Integer anIter = 0; anIter < MAXVIEW; anIter++)
1027 if (myViews[anIter] && myViews[anIter]->IsEqualWindows (aWindowNumber))
1034 X = X - myViews[id]->GetDx();
1035 Y = -Y - myViews[id]->GetDy();
1040 id = MAXVIEW; //:abv 29.05.02: cycle for working in console mode
1041 while ( id >= MAXVIEW ) {
1043 Draw_Window::SelectWait(hWnd, X, Y, Button);
1045 Draw_Window::SelectNoWait(hWnd, X, Y, Button);
1047 // Recherche du numero de la vue grace au HANDLE
1048 for(int i=0 ; i<MAXVIEW ; i++)
1049 if (myViews[i] && myViews[i]->win == hWnd ) id = i;
1051 X = X - myViews[id]->GetDx();
1052 Y = -Y - myViews[id]->GetDy();
1056 //=======================================================================
1059 //=======================================================================
1061 Standard_Integer Draw_Viewer::Pick(const Standard_Integer id,
1062 const Standard_Integer X, const Standard_Integer Y, const Standard_Integer Prec,
1063 Handle(Draw_Drawable3D)& D,
1064 const Standard_Integer first) const
1066 if (Draw_Batch) return 0;
1067 if (myViews[id] == NULL)
1070 // is this the only view in its category
1071 Standard_Boolean is2d = myViews[id]->Is2D();
1072 Standard_Integer i,nbviews = 0;
1073 for (i = 0; i < MAXVIEW; i++)
1076 if (myViews[i]->Is2D() == is2d)
1079 Standard_Boolean only = (nbviews == 1);
1085 found = Standard_False;
1086 Standard_Real x1,x2,y1,y2;
1087 for (i = first+1; i <= myDrawables.Length(); i++) {
1088 Standard_Boolean reject = Standard_False;
1089 // rejection if only view
1091 myDrawables(i)->Bounds(x1,x2,y1,y2);
1092 if ((xpick+Prec < x1) || (xpick-Prec > x2) ||
1093 (ypick+Prec < y1) || (ypick-Prec > y2))
1094 reject = Standard_True;
1097 DrawOnView(id,myDrawables(i));
1103 found = Standard_False;
1104 if (i <= myDrawables.Length())
1111 //=======================================================================
1112 //function : LastPick
1114 //=======================================================================
1116 void Draw_Viewer::LastPick(gp_Pnt& P1, gp_Pnt& P2, Standard_Real& Param)
1118 if (Draw_Batch) return;
1121 Param = lastPickParam;
1124 //=======================================================================
1125 //function : ~Draw_Viewer
1127 //=======================================================================
1129 Draw_Viewer::~Draw_Viewer()
1131 if (Draw_Batch) return;
1132 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1136 //=======================================================================
1137 //function : operator<<
1139 //=======================================================================
1141 Draw_Viewer& Draw_Viewer::operator<<(const Handle(Draw_Drawable3D)& d3d)
1143 if (Draw_Batch) return *this;
1144 if (!d3d.IsNull()) {
1146 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1152 //=======================================================================
1153 //function : GetDrawables
1155 //=======================================================================
1156 const Draw_SequenceOfDrawable3D& Draw_Viewer::GetDrawables()
1161 // *******************************************************************
1163 // *******************************************************************
1168 if (Draw_Batch) return;
1169 if (highlight) curview->SetColor(highlightcol.ID());
1170 curview->DrawSegments(segm,nbseg);
1174 //=======================================================================
1175 //function : SetColor
1177 //=======================================================================
1179 void Draw_Display::SetColor (const Draw_Color& col) const
1181 if (Draw_Batch) return;
1182 if (col.ID() == currentcolor.ID()) return;
1185 switch (CurrentMode) {
1189 curview->SetColor(col.ID());
1193 (*ps_stream) << "stroke\nnewpath\n";
1194 (*ps_stream) << ps_width[col.ID()]<<" setlinewidth\n";
1195 (*ps_stream) << ps_gray[col.ID()]<<" setgray\n";
1202 //=======================================================================
1203 //function : SetMode
1205 //=======================================================================
1207 void Draw_Display::SetMode (const Standard_Integer M) const
1209 if (Draw_Batch) return;
1210 switch (CurrentMode) {
1214 curview->SetMode(M);
1223 //=======================================================================
1226 //=======================================================================
1228 Standard_Real Draw_Display::Zoom() const
1230 if (Draw_Batch) return 1.;
1231 return curview->GetZoom();
1234 //=======================================================================
1237 //=======================================================================
1239 void Draw_Display::Flush () const
1241 if (Draw_Batch) return;
1245 //=======================================================================
1246 //function : DrawString
1248 //=======================================================================
1250 void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1251 const Standard_CString S,
1252 const Standard_Real moveX,
1253 const Standard_Real moveY)
1255 if (Draw_Batch) return;
1256 if (ppt.X() > 1.e09 || ppt.X() < -1.e09 ) return;
1257 if (ppt.Y() > 1.e09 || ppt.Y() < -1.e09 ) return;
1259 gp_Pnt2d pt(ppt.X()*curview->GetZoom(),ppt.Y()*curview->GetZoom());
1261 if (pt.X() > 1.e09 || pt.X() < -1.e09 ) return;
1262 if (pt.Y() > 1.e09 || pt.Y() < -1.e09 ) return;
1264 switch (CurrentMode) {
1268 int X = (int) ( pt.X() + moveX + curview->GetDx());
1269 int Y = (int) (-pt.Y() + moveY - curview->GetDy());
1270 curview->DrawString(X,Y,(char *)S);
1272 if (pt.X() + moveX > xmax) xmax = pt.X();
1273 if (pt.X() + moveX < xmin) xmin = pt.X();
1274 if (-pt.Y() - moveY > ymax) ymax = -pt.Y();
1275 if (-pt.Y() - moveY < ymin) ymin = -pt.Y();
1282 Standard_Integer x = (Standard_Integer )( (pt.X() + moveX - ps_vx) * ps_kx + ps_px);
1283 Standard_Integer y = (Standard_Integer )( (pt.Y() + moveY - ps_vy) * ps_ky + ps_py);
1284 (*ps_stream) <<"stroke\n";
1285 (*ps_stream) << x << " " << y << " m\n";
1286 (*ps_stream) <<"("<<S<<") show\nnewpath\n";
1295 //=======================================================================
1296 //function : DrawString
1298 //=======================================================================
1300 void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1301 const Standard_CString S)
1303 if (Draw_Batch) return;
1304 DrawString(ppt,S,0.0,0.0);
1307 //=======================================================================
1308 //function : DrawString
1310 //=======================================================================
1312 void Draw_Display::DrawString(const gp_Pnt& pt,
1313 const Standard_CString S,
1314 const Standard_Real moveX,
1315 const Standard_Real moveY)
1317 if (Draw_Batch) return;
1318 DrawString(Project(pt),S,moveX,moveY);
1321 //=======================================================================
1322 //function : DrawString
1324 //=======================================================================
1326 void Draw_Display::DrawString(const gp_Pnt& pt,
1327 const Standard_CString S)
1329 if (Draw_Batch) return;
1330 DrawString(Project(pt),S,0.0,0.0);
1334 // *******************************************************************
1335 // Drawing data static variables
1336 // *******************************************************************
1337 static gp_Pnt2d PtCur; // current 2D point
1338 static gp_Pnt PtPers; // current 3D point for Pers
1340 //=======================================================================
1341 //function : Project
1343 //=======================================================================
1345 void Draw_Display::Project(const gp_Pnt& p, gp_Pnt2d& p2d) const
1347 if (Draw_Batch) return;
1349 pt.Transform(curview->GetMatrix());
1350 Standard_Real xp,yp,zp;
1352 if (curview->IsPerspective()) {
1353 const Standard_Real aDistance = curview->GetFocalDistance();
1354 xp = xp * aDistance / (aDistance-zp);
1355 yp = yp * aDistance / (aDistance-zp);
1357 p2d.SetCoord(xp,yp);
1360 //=======================================================================
1361 //function : Draw_Display
1363 //=======================================================================
1365 Draw_Display::Draw_Display ()
1367 if (Draw_Batch) return;
1369 PtPers.SetCoord(0., 0., 0.);
1370 PtPers.Transform(curview->GetMatrix());
1371 PtCur.SetCoord(PtPers.X()*curview->GetZoom(),PtPers.Y()*curview->GetZoom());
1375 //=======================================================================
1376 //function : MoveTo 2D
1378 //=======================================================================
1380 void Draw_Display::MoveTo (const gp_Pnt2d& pp)
1382 if (Draw_Batch) return;
1383 const Standard_Real aZoom = curview->GetZoom();
1384 gp_Pnt2d pt(pp.X() * aZoom, pp.Y() * aZoom);
1385 switch (CurrentMode) {
1390 if (pt.X() > xmax) xmax = pt.X();
1391 if (pt.X() < xmin) xmin = pt.X();
1392 if (pt.Y() > ymax) ymax = pt.Y();
1393 if (pt.Y() < ymin) ymin = pt.Y();
1403 Standard_Integer x = (Standard_Integer )( (pt.X() - ps_vx) * ps_kx + ps_px);
1404 Standard_Integer y = (Standard_Integer )( (pt.Y() - ps_vy) * ps_ky + ps_py);
1405 (*ps_stream) <<"stroke\nnewpath\n"<< x << " " << y << " m\n";
1411 //=======================================================================
1412 //function : DrawTo 2D
1414 //=======================================================================
1415 inline Standard_Integer CalculRegion(const Standard_Real x,
1416 const Standard_Real y,
1417 const Standard_Real x1,
1418 const Standard_Real y1,
1419 const Standard_Real x2,
1420 const Standard_Real y2) {
1422 if(x<x1) { r=1; } else { if(x>x2) { r=2; } else { r=0; } }
1423 if(y<y1) { r|=4; } else { if(y>y2) { r|=8; } }
1427 Standard_Boolean Trim(gp_Pnt2d& P1,gp_Pnt2d& P2,
1432 Standard_Real xa=P1.X(),ya=P1.Y(),xb=P2.X(),yb=P2.Y();
1434 Standard_Integer regiona=0,regionb=0;
1435 regiona = CalculRegion(xa,ya,x0,y0,x1,y1);
1436 regionb = CalculRegion(xb,yb,x0,y0,x1,y1);
1437 if((regiona & regionb)==0) {
1438 Standard_Real dx=xb-xa;
1439 Standard_Real dy=yb-ya;
1440 Standard_Real dab=sqrt(dx*dx+dy*dy);
1441 if(dab<1e-10) return(Standard_False);
1445 Standard_Real xm,ym,mfenx,mfeny;
1446 mfenx=xm=0.5*(x0+x1);
1447 mfeny=ym=0.5*(y0+y1);
1449 Standard_Real d=sqrt(x1*x1+y1*y1) * 2;
1451 Standard_Real p=(xm-xa)*dx+(ym-ya)*dy;
1456 gp_Pnt2d MFen(mfenx,mfeny);
1457 if(MFen.SquareDistance(Pm) > d*d) return(Standard_False);
1459 Standard_Real PmDistP1 = Pm.Distance(P1);
1460 Standard_Real PmDistP2 = Pm.Distance(P2);
1462 Standard_Real amab = (xm-xa)*(xb-xa)+(ym-ya)*(yb-ya);
1464 if(amab > 0) { //-- M est compris entre A et B
1466 P1.SetCoord(xm-d*dx,ym-d*dy);
1469 P2.SetCoord(xm+d*dx,ym+d*dy);
1472 else if(PmDistP1 < PmDistP2) { //-- On a M P1 P2
1474 P2.SetCoord(xm+d*dx,ym+d*dy);
1477 else { //-- On a P1 P2 M
1479 P1.SetCoord(xm-d*dx,ym-d*dy);
1482 return(Standard_True);
1484 else return(Standard_False);
1490 void Draw_Display::DrawTo (const gp_Pnt2d& pp2)
1492 if (Draw_Batch) return;
1493 if (pp2.X() > 1.e09 || pp2.X() < -1.e09 ) return;
1494 if (pp2.Y() > 1.e09 || pp2.Y() < -1.e09 ) return;
1496 gp_Pnt2d p2(pp2.X() * curview->GetZoom(), pp2.Y() * curview->GetZoom());
1498 if (p2.X() > 1.e09 || p2.X() < -1.e09 ) return;
1499 if (p2.Y() > 1.e09 || p2.Y() < -1.e09 ) return;
1501 gp_Pnt2d p1 = PtCur;
1502 if (p1.X() > 1.e09 || p1.X() < -1.e09 ) return;
1503 if (p1.Y() > 1.e09 || p1.Y() < -1.e09 ) return;
1507 switch (CurrentMode) {
1512 Standard_Integer x0,y0,x1,y1;
1513 curview->GetFrame(x0,y0,x1,y1);
1516 //Standard_Integer qx0,qy0,qx1,qy1;
1517 //curview->viewer->GetFrame(curview->id,qx0,qy0,qx1,qy1);
1518 //if(qx0!=x0 || qx1!=x1 || qy0!=y0 || qy1!=y1) {
1519 // x0=qx0; x1=qx1; y0=qy0; y1=qy1;
1527 if(Trim(PI1,PI2,x0,y0,x1,y1))
1529 segm[nbseg].Init(static_cast<Standard_Integer>( PI1.X() + curview->GetDx()),
1530 static_cast<Standard_Integer>(-PI1.Y() - curview->GetDy()),
1531 static_cast<Standard_Integer>( PI2.X() + curview->GetDx()),
1532 static_cast<Standard_Integer>(-PI2.Y() - curview->GetDy()));
1536 segm[nbseg].Init(static_cast<Standard_Integer>( p1.X() + curview->GetDx()),
1537 static_cast<Standard_Integer>(-p1.Y() - curview->GetDy()),
1538 static_cast<Standard_Integer>( p2.X() + curview->GetDx()),
1539 static_cast<Standard_Integer>(-p2.Y() - curview->GetDy()));
1542 if (nbseg == MAXSEGMENT) {
1546 if (p2.X() > xmax) xmax = p2.X();
1547 if (p2.X() < xmin) xmin = p2.X();
1548 if (p2.Y() > ymax) ymax = p2.Y();
1549 if (p2.Y() < ymin) ymin = p2.Y();
1556 Standard_Integer x1 = (int) p1.X() ;
1557 Standard_Integer y1 = (int) p1.Y() ;
1558 Standard_Integer x2 = (int) p2.X() ;
1559 Standard_Integer y2 = (int) p2.Y() ;
1560 if ((x1 >= xpick + precpick) && (x2 >= xpick + precpick)) break;
1561 if ((x1 <= xpick - precpick) && (x2 <= xpick - precpick)) break;
1562 if ((y1 >= ypick + precpick) && (y2 >= ypick + precpick)) break;
1563 if ((y1 <= ypick - precpick) && (y2 <= ypick - precpick)) break;
1565 Standard_Boolean inside = Standard_True;
1566 if ((x1 > xpick + precpick) || (x2 > xpick + precpick)) {
1567 Standard_Real y = (Standard_Real) y1 +
1568 (Standard_Real) (y2-y1) * (Standard_Real) (xpick+precpick-x1) /
1569 (Standard_Real) (x2 - x1);
1570 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1571 found = Standard_True;
1572 lastPickParam = (Standard_Real) (xpick - x1) /
1573 (Standard_Real) (x2 - x1);
1577 inside = Standard_False;
1580 if ((x1 < xpick - precpick) || (x2 < xpick - precpick)) {
1581 Standard_Real y = (Standard_Real) y1 +
1582 (Standard_Real) (y2-y1) * (Standard_Real) (xpick-precpick-x1) /
1583 (Standard_Real) (x2 - x1);
1584 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1585 found = Standard_True;
1586 lastPickParam = (Standard_Real) (xpick - x1) /
1587 (Standard_Real) (x2 - x1);
1591 inside = Standard_False;
1595 if ((y1 > ypick + precpick) || (y2 > ypick + precpick)) {
1596 Standard_Real x = (Standard_Real) x1 +
1597 (Standard_Real) (x2-x1) * (Standard_Real) (ypick+precpick-y1) /
1598 (Standard_Real) (y2 - y1);
1599 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1600 found = Standard_True;
1601 lastPickParam = (Standard_Real) (ypick - y1) /
1602 (Standard_Real) (y2 - y1);
1606 inside = Standard_False;
1610 if ((y1 < ypick - precpick) || (y2 < ypick - precpick)) {
1611 Standard_Real x = (Standard_Real) x1 +
1612 (Standard_Real) (x2-x1) * (Standard_Real) (ypick-precpick-y1) /
1613 (Standard_Real) (y2 - y1);
1614 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1615 found = Standard_True;
1616 lastPickParam = (Standard_Real) (ypick - y1) /
1617 (Standard_Real) (y2 - y1);
1621 inside = Standard_False;
1623 found = found || inside;
1625 if (Abs(x2-x1) > Abs(y2-y1)) {
1626 if (Abs(x2-x1) < 1e-5) lastPickParam = 0;
1628 lastPickParam = (Standard_Real)(xpick - x1) /
1629 (Standard_Real)(x2 - x1);
1632 if (Abs(y2-y1) < 1e-5) lastPickParam = 0;
1634 lastPickParam = (Standard_Real)(ypick - y1) /
1635 (Standard_Real)(y2 - y1);
1643 Standard_Integer x = (Standard_Integer )( (p2.X() - ps_vx) * ps_kx + ps_px);
1644 Standard_Integer y = (Standard_Integer )( (p2.Y() - ps_vy) * ps_ky + ps_py);
1645 (*ps_stream) << x << " " << y << " l\n";
1652 //=======================================================================
1655 //=======================================================================
1657 void Draw_Display::MoveTo (const gp_Pnt& pt)
1659 if (Draw_Batch) return;
1660 if (CurrentMode == PICK) {
1661 if (!found) lastPickP1 = pt;
1665 PtPers.Transform(curview->GetMatrix());
1666 Standard_Real xp = PtPers.X();
1667 Standard_Real yp = PtPers.Y();
1668 if (curview->IsPerspective())
1670 Standard_Real ZPers = PtPers.Z();
1671 const Standard_Real aDistance = curview->GetFocalDistance();
1672 if (ZPers < aDistance * precpers)
1674 xp=xp * aDistance / (aDistance-ZPers);
1675 yp=yp * aDistance / (aDistance-ZPers);
1678 MoveTo(gp_Pnt2d(xp,yp));
1681 //=======================================================================
1684 //=======================================================================
1686 void Draw_Display::DrawTo (const gp_Pnt& pt)
1688 if (Draw_Batch) return;
1689 if ((CurrentMode == PICK) && found) return;
1691 gp_Pnt pt2 = pt.Transformed(curview->GetMatrix());
1692 Standard_Real xp2 = pt2.X();
1693 Standard_Real yp2 = pt2.Y();
1695 if (curview->IsPerspective())
1697 const Standard_Real aZoom = curview->GetZoom();
1698 const Standard_Real aDistance = curview->GetFocalDistance();
1700 Standard_Real xp1 = PtPers.X();
1701 Standard_Real yp1 = PtPers.Y();
1702 Standard_Real zp1 = PtPers.Z();
1703 Standard_Real zp2 = pt2.Z();
1705 if ((zp1 >= aDistance*precpers) && (zp2 >= aDistance*precpers) )
1707 return; // segment is not visible in perspective (behind the eye)
1709 else if (zp1 >= aDistance*precpers)
1711 xp1=xp1+(xp2-xp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1712 yp1=yp1+(yp2-yp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1713 zp1=aDistance*precpers;
1714 xp1=xp1*aDistance/(aDistance-zp1);
1715 yp1=yp1*aDistance/(aDistance-zp1);
1716 MoveTo( gp_Pnt2d(xp1 * aZoom, yp1 * aZoom) );
1718 else if (zp2 >= aDistance*precpers)
1720 xp2=xp2+(xp1-xp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1721 yp2=yp2+(yp1-yp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1722 zp2=aDistance*precpers;
1724 xp2 = xp2 * aDistance / (aDistance - zp2);
1725 yp2 = yp2 * aDistance / (aDistance - zp2);
1727 DrawTo(gp_Pnt2d(xp2,yp2));
1728 if (CurrentMode == PICK) {
1729 if (!found) lastPickP1 = pt;
1730 else lastPickP2 = pt;
1734 //=======================================================================
1737 //=======================================================================
1739 void Draw_Display::Draw (const gp_Pnt& p1, const gp_Pnt& p2)
1741 if (Draw_Batch) return;
1746 //=======================================================================
1749 //=======================================================================
1751 void Draw_Display::Draw(const gp_Pnt2d& p1, const gp_Pnt2d& p2)
1753 if (Draw_Batch) return;
1759 //=======================================================================
1762 //=======================================================================
1764 Standard_Integer Draw_Display::ViewId() const
1766 if (Draw_Batch) return 0;
1771 //=======================================================================
1772 //function : HasPicked
1774 //=======================================================================
1776 Standard_Boolean Draw_Display::HasPicked() const
1778 if (Draw_Batch) return Standard_False;