0028110: Configuration - specify Unicode charset instead of multibyte in project...
[occt.git] / src / Draw / Draw_Viewer.cxx
CommitLineData
b311480e 1// Created on: 1992-04-06
2// Created by: Remi LEQUETTE
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17#include <Draw_Viewer.hxx>
96f3bacc 18#include <Draw_View.hxx>
7fd59977 19
20#include <gp_Pnt.hxx>
21#include <gp_Pnt2d.hxx>
22#include <Draw_Window.hxx>
23#include <Draw_Display.hxx>
ad03c234 24#include <TCollection_AsciiString.hxx>
7fd59977 25
26#define precpers 0.95
27#define ButtonPress 4
28#define MotionNotify 6
29static const Standard_Real DRAWINFINITE = 1e50;
30Standard_EXPORT Standard_Boolean Draw_Bounds = Standard_True;
31extern Standard_Boolean Draw_Batch;
32const Standard_Integer MAXSEGMENT = 1000;
33Segment segm[MAXSEGMENT];
34static int nbseg=0;
35static Draw_View* curview = NULL;
36static Standard_Integer curviewId = 0;
37static char blank[2] = "";
38static Standard_Real xmin,xmax,ymin,ymax;
39static Standard_Boolean found = Standard_False;
40static Standard_Integer xpick, ypick, precpick;
41static gp_Pnt lastPickP1;
42static gp_Pnt lastPickP2;
43static Standard_Real lastPickParam;
44static Draw_Color highlightcol;
45static Draw_Color currentcolor;
46static Standard_Boolean highlight = Standard_False;
47static Standard_Integer ps_vx, ps_vy;
48static Standard_Real ps_kx, ps_ky;
49static Standard_Integer ps_px, ps_py;
50static ostream* ps_stream;
51static Standard_Integer ps_width[MAXCOLOR];
52static Standard_Real ps_gray[MAXCOLOR];
53
54enum DrawingMode {DRAW, PICK, POSTSCRIPT};
55static DrawingMode CurrentMode = DRAW;
56
7fd59977 57//=======================================================================
58//function : Create
59//purpose :
60//=======================================================================
61
62Draw_Viewer::Draw_Viewer()
63{
64 if (Draw_Batch) return;
65 Standard_Integer i;
66 for ( i = 0; i < MAXVIEW; i++) myViews[i] = NULL;
67 for (i = 0; i < MAXCOLOR; i++) {
68 ps_width[i] = 1;
69 ps_gray[i] = 0;
70 }
71}
72
73//=======================================================================
74//function : DefineColor
75//purpose :
76//=======================================================================
77
78Standard_Boolean Draw_Viewer::DefineColor (const Standard_Integer i, const char* colname)
79{
80 if (Draw_Batch) return 1;
81 return Draw_Window::DefineColor(i,colname);
82}
83
84
85//=======================================================================
86//function : MakeView
87//purpose :
88//=======================================================================
89
90void Draw_Viewer::MakeView(const Standard_Integer id,
91 const char* typ,
92 const Standard_Integer X, const Standard_Integer Y,
93 const Standard_Integer W, const Standard_Integer H)
94{
95 if (Draw_Batch) return;
96 if (id < MAXVIEW) {
97
98 DeleteView(id);
99 myViews[id] = new Draw_View(id,this,X , Y, W, H);
100
101 // View fields
96f3bacc 102 myViews[id]->SetDx(W / 2);
103 myViews[id]->SetDy(- H / 2);
7fd59977 104
105 if (!myViews[id]->Init(typ))
106 DeleteView(id);
107
108 RepaintView(id);
109 }
110}
111
57c28b61 112#ifdef _WIN32
7fd59977 113//=======================================================================
114//function : MakeView
115//purpose :
116//=======================================================================
117
118void Draw_Viewer::MakeView(const Standard_Integer id,
119 const char* typ,
120 const Standard_Integer X, const Standard_Integer Y,
121 const Standard_Integer W, const Standard_Integer H,
122 HWND win, Standard_Boolean useBuffer)
123{
124 if (Draw_Batch) return;
125 if (id < MAXVIEW) {
126
127 DeleteView(id);
128 myViews[id] = new Draw_View(id, this, X, Y, W, H, win);
129 myViews[id]->SetUseBuffer(useBuffer);
130
131 // View fields
96f3bacc 132 myViews[id]->SetDx( W / 2);
133 myViews[id]->SetDy(-H / 2);
7fd59977 134
135 if (!myViews[id]->Init(typ))
136 DeleteView(id);
137 RepaintView(id);
138 }
139}
140#endif
141
142//=======================================================================
143//function : MakeView
144//purpose :
145//=======================================================================
146
147void Draw_Viewer::MakeView (const Standard_Integer id,
148 const char* typ,
149 const char* window)
150{
151 if (Draw_Batch) return;
152 if (id < MAXVIEW) {
153
154 DeleteView(id);
155 myViews[id] = new Draw_View(id,this,window);
156
157
96f3bacc 158 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
159 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
7fd59977 160
161 if (!myViews[id]->Init(typ))
162 DeleteView(id);
163
164 RepaintView(id);
165 }
166}
167
168
169//=======================================================================
170//function : SetTitle
171//purpose :
172//=======================================================================
173
174void Draw_Viewer::SetTitle (const Standard_Integer id, const char* name)
175{
176 if (Draw_Batch) return;
ad03c234 177 if(myViews[id]) myViews[id]->SetTitle (name);
7fd59977 178}
179
180//=======================================================================
181//function : ResetView
182//purpose : reset view zoom and axes
183//=======================================================================
184
185void Draw_Viewer::ResetView(const Standard_Integer id)
186{
187 if (Draw_Batch) return;
188 if (myViews[id]) {
96f3bacc 189 myViews[id]->Init(myViews[id]->Type());
7fd59977 190 ConfigView(id);
191 }
192}
193
194//=======================================================================
195//function : SetZoom
196//purpose :
197//=======================================================================
198
199void Draw_Viewer::SetZoom (const Standard_Integer id, const Standard_Real z)
200{
96f3bacc 201 if (Draw_Batch)
202 return;
203
204 Draw_View* aView = myViews[id];
205 if (aView)
206 {
207 Standard_Real zz = z / aView->GetZoom();
208 aView->SetZoom(z);
7fd59977 209 Standard_Integer X,Y,W,H;
210 GetPosSize(id,X,Y,W,H);
96f3bacc 211
212 const Standard_Real w = 0.5 * static_cast<Standard_Real>(W);
213 const Standard_Real h = 0.5 * static_cast<Standard_Real>(H);
214
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()) );
219
220 aView->SetDx(aDx);
221 aView->SetDy(aDy);
7fd59977 222 }
223}
224
225//=======================================================================
226//function : RotateView
227//purpose :
228//=======================================================================
229
230void Draw_Viewer::RotateView (const Standard_Integer id,
231 const gp_Dir2d& D,
232 const Standard_Real A)
233{
234 if (Draw_Batch) return;
235 if (myViews[id]) {
96f3bacc 236 gp_Trsf T = myViews[id]->GetMatrix();
7fd59977 237
238 T.Invert();
239 gp_Pnt PP(0,0,0);
240 gp_Dir DD(D.X(),D.Y(),0);
241 PP.Transform(T);
242 DD.Transform(T);
243 RotateView(id,PP,DD,A);
244 }
245}
246
247//=======================================================================
248//function : RotateView
249//purpose :
250//=======================================================================
251
252void Draw_Viewer::RotateView (const Standard_Integer id,
253 const gp_Pnt& P,
254 const gp_Dir& D,
255 const Standard_Real A)
256{
257 if (Draw_Batch) return;
258 if (myViews[id]) {
259 gp_Trsf T;
260 T.SetRotation(gp_Ax1(P,D),A);
96f3bacc 261 myViews[id]->Transform(T);
7fd59977 262 }
263}
264
265
266//=======================================================================
267//function : SetFocal
268//purpose :
269//=======================================================================
270
271void Draw_Viewer::SetFocal (const Standard_Integer id, const Standard_Real F)
272{
273 if (Draw_Batch) return;
274 if (myViews[id])
96f3bacc 275 myViews[id]->SetFocalDistance(F);
7fd59977 276}
277
278//=======================================================================
279//function : GetType
280//purpose :
281//=======================================================================
282
283char* Draw_Viewer::GetType (const Standard_Integer id) const
284{
285 if (Draw_Batch) return blank;
286 if (myViews[id])
96f3bacc 287 return const_cast<char*>(myViews[id]->Type());
7fd59977 288 else
289 return blank;
290}
291
292//=======================================================================
293//function : Zoom
294//purpose :
295//=======================================================================
296
297Standard_Real Draw_Viewer::Zoom (const Standard_Integer id) const
298{
299 if (Draw_Batch) return Standard_False;
300 if (myViews[id])
96f3bacc 301 return myViews[id]->GetZoom();
7fd59977 302 else
96f3bacc 303 return 0.0;
7fd59977 304}
305
306//=======================================================================
307//function : Focal
308//purpose :
309//=======================================================================
310
311Standard_Real Draw_Viewer::Focal (const Standard_Integer id) const
312{
313 if (Draw_Batch) return 1.;
314 if (myViews[id])
96f3bacc 315 return myViews[id]->GetFocalDistance();
7fd59977 316 else
317 return 0;
318}
319
320//=======================================================================
321//function : GetTrsf
322//purpose :
323//=======================================================================
324
325void Draw_Viewer::GetTrsf (const Standard_Integer id,gp_Trsf& T) const
326{
327 if (Draw_Batch) return;
328 if (myViews[id])
96f3bacc 329 T = myViews[id]->GetMatrix();
7fd59977 330}
331
332//=======================================================================
333//function : Is3D
334//purpose :
335//=======================================================================
336
337Standard_Boolean Draw_Viewer::Is3D (const Standard_Integer id) const
338{
339 if (Draw_Batch) return Standard_False;
340 if (myViews[id])
96f3bacc 341 return !myViews[id]->Is2D();
7fd59977 342 else
343 return Standard_False;
344}
345
346//=======================================================================
347//function : SetTrsf
348//purpose :
349//=======================================================================
350
351void Draw_Viewer::SetTrsf (const Standard_Integer id,gp_Trsf& T)
352{
353 if (Draw_Batch) return;
354 if (myViews[id])
96f3bacc 355 myViews[id]->SetMatrix(T);
7fd59977 356}
357
358//=======================================================================
359//function : GetPosSize
360//purpose :
361//=======================================================================
362
363void Draw_Viewer::GetPosSize(const Standard_Integer id,
364 Standard_Integer& X, Standard_Integer& Y,
365 Standard_Integer& W, Standard_Integer& H)
366{
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();
372 }
373}
374
375//=======================================================================
376//function : GetFrame
377//purpose :
378//=======================================================================
379
380void Draw_Viewer::GetFrame(const Standard_Integer id,
381 Standard_Integer& xminf, Standard_Integer& yminf,
382 Standard_Integer& xmaxf, Standard_Integer& ymaxf)
383{
384 if (Draw_Batch) return;
385 if (myViews[id]) {
386 Standard_Integer X,Y,H,W;
387 GetPosSize(id,X,Y,W,H);
96f3bacc 388 xminf = - myViews[id]->GetDx();
389 xmaxf = W - myViews[id]->GetDx();
390 yminf = - myViews[id]->GetDy() - H;
391 ymaxf = - myViews[id]->GetDy();
7fd59977 392 }
393}
394
395//=======================================================================
396//function : FitView
397//purpose :
398//=======================================================================
399
400void Draw_Viewer::FitView(const Standard_Integer id, const Standard_Integer frame)
401{
402 if (Draw_Batch) return;
403 if (myViews[id]) {
404
405 // is this the only view in its category
96f3bacc 406 Standard_Boolean is2d = myViews[id]->Is2D();
7fd59977 407 Standard_Integer i,nbviews = 0;
408 for (i = 1; i < MAXVIEW; i++) {
409 if (myViews[i]) {
96f3bacc 410 if (myViews[i]->Is2D() == is2d)
411 ++nbviews;
7fd59977 412 }
413 }
414 Standard_Boolean only = (nbviews == 1);
415
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();
420 if (n == 0) return;
421// Draw_Display DF;
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;
427
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...
432 if (!only)
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;
439 }
440 }
441 Standard_Real z;
96f3bacc 442 umin = umin / curview->GetZoom();
443 vmin = vmin / curview->GetZoom();
444 umax = umax / curview->GetZoom();
445 vmax = vmax / curview->GetZoom();
7fd59977 446 if ((umax - umin) < 1.e-6) {
447 if ((vmax - vmin) < 1.e-6)
448 return;
449 else
450 z = ((Standard_Real)(H - 2*frame)) / (vmax - vmin);
451 }
452 else {
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);
456 if (z2 < z) z = z2;
457 }
458 }
96f3bacc 459 curview->SetZoom(z);
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) );
7fd59977 462 }
463}
464
465//=======================================================================
466//function : PanView
467//purpose :
468//=======================================================================
469
470void Draw_Viewer::PanView(const Standard_Integer id,
471 const Standard_Integer DX, const Standard_Integer DY)
472{
473 if (Draw_Batch) return;
474 if (myViews[id]) {
96f3bacc 475 myViews[id]->SetDx(myViews[id]->GetDx() + DX);
476 myViews[id]->SetDy(myViews[id]->GetDy() + DY);
7fd59977 477 }
478}
479
480
481//=======================================================================
482//function : SetPan
483//purpose :
484//=======================================================================
485
486void Draw_Viewer::SetPan(const Standard_Integer id,
487 const Standard_Integer DX, const Standard_Integer DY)
488{
489 if (Draw_Batch) return;
490 if (myViews[id]) {
96f3bacc 491 myViews[id]->SetDx(DX);
492 myViews[id]->SetDy(DY);
7fd59977 493 }
494}
495
496//=======================================================================
497//function : GetPan
498//purpose :
499//=======================================================================
500
501void Draw_Viewer::GetPan(const Standard_Integer id,
502 Standard_Integer& DX, Standard_Integer& DY)
503{
504 if (Draw_Batch) return;
505 if (myViews[id]) {
96f3bacc 506 DX = myViews[id]->GetDx();
507 DY = myViews[id]->GetDy();
7fd59977 508 }
509}
510
511//=======================================================================
512//function : HasView
513//purpose :
514//=======================================================================
515
516Standard_Boolean Draw_Viewer::HasView(const Standard_Integer id) const
517{
518 if (Draw_Batch) return Standard_False;
519 if ((id < 0) || id >= MAXVIEW) return Standard_False;
520 return myViews[id] != NULL;
521}
522
523//=======================================================================
524//function : DisplayView
525//purpose :
526//=======================================================================
527
528void Draw_Viewer::DisplayView (const Standard_Integer id) const
529{
530 if (Draw_Batch) return;
531 if (myViews[id]) myViews[id]->DisplayWindow();
532}
533
534//=======================================================================
535//function : HideView
536//purpose :
537//=======================================================================
538
539void Draw_Viewer::HideView (const Standard_Integer id) const
540{
541 if (Draw_Batch) return;
542 if (myViews[id]) {
543 //
544 }
545}
546
547//=======================================================================
548//function : ClearView
549//purpose :
550//=======================================================================
551
552void Draw_Viewer::ClearView(const Standard_Integer id) const
553{
554 if (Draw_Batch) return;
555 if (myViews[id]) myViews[id]->Clear();
556}
557
558//=======================================================================
559//function : RemoveView
560//purpose :
561//=======================================================================
562
563void Draw_Viewer::RemoveView(const Standard_Integer id)
564{
565 if (Draw_Batch) return;
566 if (myViews[id]) {
567 delete myViews[id];
568 myViews[id] = NULL;
569 }
570}
571
572//=======================================================================
573//function : RepaintView
574//purpose :
575//=======================================================================
576void Draw_Viewer::RepaintView (const Standard_Integer id) const
577{
578 if (Draw_Batch) return;
579 if (myViews[id]) {
580 ClearView(id);
581 Standard_Integer n = myDrawables.Length();
582 for (Standard_Integer i = 1; i <= n; i++)
583 DrawOnView(id,myDrawables(i));
584 }
585}
586
587
57c28b61 588#ifdef _WIN32
7fd59977 589//=======================================================================
590//function : ResizeView
591//purpose : WNT re-drawing optimization
592//=======================================================================
593void Draw_Viewer::ResizeView (const Standard_Integer id) const
594{
595 if (Draw_Batch) return;
596 if (myViews[id] && myViews[id]->GetUseBuffer()) {
597 myViews[id]->InitBuffer();
598 RepaintView(id);
599 }
600}
601
602//=======================================================================
603//function : UpdateView
604//purpose : WNT re-drawing optimization
605//=======================================================================
606void Draw_Viewer::UpdateView (const Standard_Integer id, const Standard_Boolean forced) const
607{
608 if (Draw_Batch) return;
609 if (myViews[id]) {
610 if (!myViews[id]->GetUseBuffer() || forced) {
611 RepaintView(id);
612 }
613 // Fast redrawing on WNT
614 if (myViews[id]->GetUseBuffer()) myViews[id]->Redraw();
615 }
616}
617#endif
618
619//=======================================================================
620//function : ConfigView
621//purpose :
622//=======================================================================
623
624void Draw_Viewer::ConfigView (const Standard_Integer id) const
625{
626 if (Draw_Batch) return;
96f3bacc 627 if (myViews[id])
628 {
629 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
630 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
7fd59977 631 }
632}
633
634//=======================================================================
635//function : PostScriptView
636//purpose :
637//=======================================================================
638
639void 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
649{
650 if (Draw_Batch) return;
651 if (myViews[id]) {
652 ps_vx = VXmin;
653 ps_vy = VYmin;
654 ps_px = PXmin;
655 ps_py = PYmin;
656 ps_kx = ((Standard_Real) (PXmax - PXmin)) / ((Standard_Real) (VXmax - VXmin));
657 ps_ky = ((Standard_Real) (PYmax - PYmin)) / ((Standard_Real) (VYmax - VYmin));
658 ps_stream = &sortie;
659 Standard_Integer n = myDrawables.Length();
660 if (n == 0) return;
661 CurrentMode = POSTSCRIPT;
662 Draw_Display DF = MakeDisplay(id);
96f3bacc 663 Standard_Boolean view2d = myViews[id]->Is2D();
7fd59977 664 for (Standard_Integer i = 1; i <= n; i++)
665 if (myDrawables(i)->Is3D()) {
666 if (!view2d) myDrawables(i)->DrawOn(DF);
667 }
668 else {
669 if (view2d) myDrawables(i)->DrawOn(DF);
670 }
671 sortie << "stroke\n";
672 CurrentMode = DRAW;
673 }
674}
675
676//=======================================================================
677//function : PostColor
678//purpose :
679//=======================================================================
680
681void Draw_Viewer::PostColor(const Standard_Integer icol,
682 const Standard_Integer width,
683 const Standard_Real gray)
684{
685 if (Draw_Batch) return;
686 if ((icol < 0) || (icol >= MAXCOLOR)) return;
687 ps_width[icol] = width;
688 ps_gray[icol] = gray;
689}
690
691//=======================================================================
692//function : SaveView
693//purpose :
694//=======================================================================
695
696Standard_Boolean Draw_Viewer::SaveView(const Standard_Integer id,
697 const char* filename)
698{
699 if (Draw_Batch) return Standard_False;;
700 Flush();
701 if (myViews[id]) {
702 return myViews[id]->Save(filename);
703 }
704 else
705 {
706 std::cerr << "View " << id << " doesn't exists!\n";
707 return Standard_False;
708 }
709}
710
711//=======================================================================
712//function : RepaintAll
713//purpose :
714//=======================================================================
715
716void Draw_Viewer::RepaintAll () const
717{
718 if (Draw_Batch) return;
719 for (Standard_Integer id = 0; id < MAXVIEW; id++)
720 RepaintView(id);
721}
722
723//=======================================================================
724//function : Repaint2D
725//purpose :
726//=======================================================================
727
728void Draw_Viewer::Repaint2D () const
729{
730 if (Draw_Batch) return;
731 for (Standard_Integer id = 0; id < MAXVIEW; id++)
732 if (myViews[id]) {
96f3bacc 733 if (myViews[id]->Is2D())
734 RepaintView(id);
7fd59977 735 }
736}
737
738//=======================================================================
739//function : Repaint3D
740//purpose :
741//=======================================================================
742
743void Draw_Viewer::Repaint3D () const
744{
745 if (Draw_Batch) return;
746 for (Standard_Integer id = 0; id < MAXVIEW; id++)
747 if (myViews[id]) {
96f3bacc 748 if (!myViews[id]->Is2D())
749 RepaintView(id);
7fd59977 750 }
751}
752
753//=======================================================================
7fd59977 754//function : DeleteView
755//purpose :
756//=======================================================================
757
758void Draw_Viewer::DeleteView(const Standard_Integer id)
759{
760 if (Draw_Batch) return;
761 if (myViews[id] != NULL) {
762 delete myViews[id];
763 myViews[id] = NULL;
764 }
765}
766
767//=======================================================================
768//function : Clear
769//purpose :
770//=======================================================================
771
772void Draw_Viewer::Clear()
773{
774 if (Draw_Batch) return;
775 for (Standard_Integer i = 1; i <= myDrawables.Length(); i++)
776 myDrawables(i)->Visible(Standard_False);
777 myDrawables.Clear();
778 for (Standard_Integer id = 0; id < MAXVIEW; id++)
779 ClearView(id);
780}
781
782//=======================================================================
783//function : Clear2D
784//purpose :
785//=======================================================================
786
787void Draw_Viewer::Clear2D()
788{
789 if (Draw_Batch) return;
790 Standard_Integer i = 1;
791 while (i <= myDrawables.Length()) {
792 if (myDrawables(i)->Is3D())
793 i++;
794 else {
795 myDrawables(i)->Visible(Standard_False);
796 myDrawables.Remove(i);
797 }
798 }
799 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
800 if (myViews[id]) {
96f3bacc 801 if (myViews[id]->Is2D())
802 ClearView(id);
7fd59977 803 }
804 }
805}
806
807//=======================================================================
808//function : Clear3D
809//purpose :
810//=======================================================================
811
812void Draw_Viewer::Clear3D()
813{
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);
820 }
821 else
822 i++;
823 }
824 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
825 if (myViews[id]) {
96f3bacc 826 if (!myViews[id]->Is2D())
827 ClearView(id);
7fd59977 828 }
829 }
830}
831
832//=======================================================================
833//function : Flush
834//purpose :
835//=======================================================================
836
837void Draw_Viewer::Flush()
838{
839 if (Draw_Batch) return;
840 Draw_Window::Flush();
841}
842
843//=======================================================================
844//function : DrawOnView
845//purpose :
846//=======================================================================
847
848void Draw_Viewer::DrawOnView(const Standard_Integer id,
849 const Handle(Draw_Drawable3D)& D) const
850{
851 if (Draw_Batch) return;
852 if (myViews[id]) {
853 Draw_Display d = MakeDisplay(id);
854 xmin = ymin = DRAWINFINITE;
855 xmax = ymax = -DRAWINFINITE;
856
96f3bacc 857 Standard_Boolean view2d = myViews[id]->Is2D();
7fd59977 858 myViews[id]->ResetFrame();
96f3bacc 859 if ((D->Is3D() && !view2d) || (!D->Is3D() && view2d))
860 {
7fd59977 861 D->DrawOn(d);
7fd59977 862 if (CurrentMode == DRAW)
96f3bacc 863 D->SetBounds(xmin,xmax,ymin,ymax);
7fd59977 864 d.Flush();
865 }
866 }
867}
868
869//=======================================================================
870//function : HighlightOnView
871//purpose :
872//=======================================================================
873
874void Draw_Viewer::HighlightOnView (const Standard_Integer id,
875 const Handle(Draw_Drawable3D)& D,
876 const Draw_ColorKind C) const
877{
878 if (Draw_Batch) return;
879 highlight = Standard_True;
880 highlightcol = C;
881 DrawOnView(id,D);
882 highlight = Standard_False;
883}
884
885//=======================================================================
886//function : AddDrawable
887//purpose :
888//=======================================================================
889
890void Draw_Viewer::AddDrawable (const Handle(Draw_Drawable3D)& D)
891{
892 if (Draw_Batch) return;
893 if (!D.IsNull() && !D->Visible()) {
894 myDrawables.Append(D);
895 D->Visible(Standard_True);
896 }
897}
898
899//=======================================================================
900//function : RemoveDrawable
901//purpose :
902//=======================================================================
903
904void Draw_Viewer::RemoveDrawable (const Handle(Draw_Drawable3D)& D)
905{
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);
913 return;
914 }
915 }
916 }
917}
918
919//=======================================================================
920//function : MakeDisplay
921//purpose : return a display on the view
922//=======================================================================
923
924Draw_Display Draw_Viewer::MakeDisplay (const Standard_Integer id) const
925{
926 if (Draw_Batch) {Draw_Display dis;return dis;}
927 curviewId = id;
928 curview = myViews[id];
929 int GXcopy = 0x3;
930 nbseg = 0;
931 Draw_Color initcol(Draw_blanc);
932 // to force setting the color
933 currentcolor = Draw_Color(Draw_rouge);
934 Draw_Display dis;
935 dis.SetColor(initcol);
936 dis.SetMode(GXcopy);
937 return dis;
938}
939
940//=======================================================================
941//function : Select
942//purpose :
943//=======================================================================
944void Draw_Viewer::Select (Standard_Integer& id, Standard_Integer& X, Standard_Integer& Y,
945 Standard_Integer& Button, Standard_Boolean wait)
946{
947 if (Draw_Batch) return;
948 Flush();
67d97f0e 949#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7fd59977 950 if (!wait) {
951 if (id >=0 && id < MAXVIEW) {
952 if (myViews[id]) myViews[id]->Wait(wait);
953 }
954 }
955 else {
956 for(int i=0 ; i<MAXVIEW ; i++)
957 if (myViews[i]) myViews[i]->Wait(wait);
958 }
959
960 Standard_Boolean again = Standard_True;
961 while (again) {
962
963 Event ev;
964 ev.type = 0;
965
966 GetNextEvent(ev);
967
968 switch (ev.type) {
969
970 case ButtonPress :
971 Standard_Integer iv;
972 for (iv = 0; iv < MAXVIEW; iv++) {
973 if (myViews[iv]) {
974 if (myViews[iv]->win == ev.window)
975 break;
976 }
977 }
978 if (wait || id == iv) {
979 if (iv < MAXVIEW) {
980 id = iv;
981 X = ev.x;
982 Y = ev.y;
983 Button = ev.button;
984 }
985 else {
986 id = -1;
987 }
988 again = Standard_False;
989 }
990 break;
991
992 case MotionNotify :
993 if (wait) break;
994 X = ev.x;
995 Y = ev.y;
996 Button = 0;
997 again = Standard_False;
998 break;
999 }
1000 }
1001
1002 if (id != -1) {
96f3bacc 1003 X = X - myViews[id]->GetDx();
1004 Y = -Y - myViews[id]->GetDy();
7fd59977 1005 }
1006 if (!wait) myViews[id]->Wait(!wait);
67d97f0e 1007#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1008 Standard_Integer aWindowNumber;
1009
1010 id = MAXVIEW;
1011 while (id >= MAXVIEW)
1012 {
1013 GetNextEvent(wait, aWindowNumber, X, Y, Button);
96f3bacc 1014
67d97f0e 1015 if (Y < 0)
1016 {
1017 continue; // mouse clicked on window title
1018 }
1019
1020 for (Standard_Integer anIter = 0; anIter < MAXVIEW; anIter++)
1021 {
1022 if (myViews[anIter] && myViews[anIter]->IsEqualWindows (aWindowNumber))
1023 {
1024 id = anIter;
1025 }
1026 }
1027 }
1028
96f3bacc 1029 X = X - myViews[id]->GetDx();
1030 Y = -Y - myViews[id]->GetDy();
67d97f0e 1031
7fd59977 1032#else
1033 HANDLE hWnd;
1034
1035 id = MAXVIEW; //:abv 29.05.02: cycle for working in console mode
1036 while ( id >= MAXVIEW ) {
1037 if (wait)
1038 Draw_Window::SelectWait(hWnd, X, Y, Button);
1039 else
1040 Draw_Window::SelectNoWait(hWnd, X, Y, Button);
1041
1042 // Recherche du numero de la vue grace au HANDLE
1043 for(int i=0 ; i<MAXVIEW ; i++)
1044 if (myViews[i] && myViews[i]->win == hWnd ) id = i;
1045 }
96f3bacc 1046 X = X - myViews[id]->GetDx();
1047 Y = -Y - myViews[id]->GetDy();
7fd59977 1048#endif
1049}
1050
1051//=======================================================================
1052//function : Pick
1053//purpose :
1054//=======================================================================
1055
1056Standard_Integer Draw_Viewer::Pick(const Standard_Integer id,
1057 const Standard_Integer X, const Standard_Integer Y, const Standard_Integer Prec,
1058 Handle(Draw_Drawable3D)& D,
1059 const Standard_Integer first) const
1060{
1061 if (Draw_Batch) return 0;
1062 if (myViews[id] == NULL)
1063 return 0;
1064
1065 // is this the only view in its category
96f3bacc 1066 Standard_Boolean is2d = myViews[id]->Is2D();
7fd59977 1067 Standard_Integer i,nbviews = 0;
96f3bacc 1068 for (i = 0; i < MAXVIEW; i++)
1069 {
1070 if (myViews[i])
1071 if (myViews[i]->Is2D() == is2d)
1072 ++nbviews;
7fd59977 1073 }
1074 Standard_Boolean only = (nbviews == 1);
1075
1076 CurrentMode = PICK;
1077 xpick = X;
1078 ypick = Y;
1079 precpick = Prec;
1080 found = Standard_False;
1081 Standard_Real x1,x2,y1,y2;
1082 for (i = first+1; i <= myDrawables.Length(); i++) {
1083 Standard_Boolean reject = Standard_False;
1084 // rejection if only view
1085 if (only) {
1086 myDrawables(i)->Bounds(x1,x2,y1,y2);
1087 if ((xpick+Prec < x1) || (xpick-Prec > x2) ||
1088 (ypick+Prec < y1) || (ypick-Prec > y2))
1089 reject = Standard_True;
1090 }
1091 if (!reject) {
1092 DrawOnView(id,myDrawables(i));
1093 if (found)
1094 break;
1095 }
1096 }
1097 CurrentMode = DRAW;
1098 found = Standard_False;
1099 if (i <= myDrawables.Length())
1100 D = myDrawables(i);
1101 else
1102 i = 0;
1103 return i;
1104}
1105
1106//=======================================================================
1107//function : LastPick
1108//purpose :
1109//=======================================================================
1110
1111void Draw_Viewer::LastPick(gp_Pnt& P1, gp_Pnt& P2, Standard_Real& Param)
1112{
1113 if (Draw_Batch) return;
1114 P1 = lastPickP1;
1115 P2 = lastPickP2;
1116 Param = lastPickParam;
1117}
1118
1119//=======================================================================
1120//function : ~Draw_Viewer
1121//purpose :
1122//=======================================================================
1123
1124Draw_Viewer::~Draw_Viewer()
1125{
1126 if (Draw_Batch) return;
1127 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1128 DeleteView(id);
1129}
1130
1131//=======================================================================
1132//function : operator<<
1133//purpose :
1134//=======================================================================
1135
1136Draw_Viewer& Draw_Viewer::operator<<(const Handle(Draw_Drawable3D)& d3d)
1137{
1138 if (Draw_Batch) return *this;
1139 if (!d3d.IsNull()) {
1140 AddDrawable(d3d);
1141 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1142 DrawOnView(id,d3d);
1143 }
1144 return *this;
1145}
1146
1147//=======================================================================
1148//function : GetDrawables
1149//purpose :
1150//=======================================================================
1151const Draw_SequenceOfDrawable3D& Draw_Viewer::GetDrawables()
1152{
1153 return myDrawables;
1154}
1155
1156// *******************************************************************
1157// DISPLAY methods
1158// *******************************************************************
1159
1160
1161void Draw_Flush()
1162{
1163 if (Draw_Batch) return;
1164 if (highlight) curview->SetColor(highlightcol.ID());
1165 curview->DrawSegments(segm,nbseg);
1166 nbseg = 0;
1167}
1168
1169//=======================================================================
1170//function : SetColor
1171//purpose :
1172//=======================================================================
1173
1174void Draw_Display::SetColor (const Draw_Color& col) const
1175{
1176 if (Draw_Batch) return;
1177 if (col.ID() == currentcolor.ID()) return;
1178
1179 currentcolor = col;
1180 switch (CurrentMode) {
1181
1182 case DRAW :
1183 Draw_Flush();
1184 curview->SetColor(col.ID());
1185 break;
1186
1187 case POSTSCRIPT :
1188 (*ps_stream) << "stroke\nnewpath\n";
1189 (*ps_stream) << ps_width[col.ID()]<<" setlinewidth\n";
1190 (*ps_stream) << ps_gray[col.ID()]<<" setgray\n";
1191
1192 case PICK :
1193 break;
1194 }
1195}
1196
1197//=======================================================================
1198//function : SetMode
1199//purpose :
1200//=======================================================================
1201
1202void Draw_Display::SetMode (const Standard_Integer M) const
1203{
1204 if (Draw_Batch) return;
1205 switch (CurrentMode) {
1206
1207 case DRAW :
1208 Draw_Flush();
1209 curview->SetMode(M);
1210 break;
1211
1212 case PICK :
1213 case POSTSCRIPT :
1214 break;
1215 }
1216}
1217
1218//=======================================================================
1219//function : Zoom
1220//purpose :
1221//=======================================================================
1222
1223Standard_Real Draw_Display::Zoom() const
1224{
1225 if (Draw_Batch) return 1.;
96f3bacc 1226 return curview->GetZoom();
7fd59977 1227}
1228
1229//=======================================================================
1230//function : Flush
1231//purpose :
1232//=======================================================================
1233
1234void Draw_Display::Flush () const
1235{
1236 if (Draw_Batch) return;
1237 Draw_Flush();
1238}
1239
1240//=======================================================================
1241//function : DrawString
1242//purpose :
1243//=======================================================================
1244
1245void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1246 const Standard_CString S,
1247 const Standard_Real moveX,
1248 const Standard_Real moveY)
1249{
1250 if (Draw_Batch) return;
1251 if (ppt.X() > 1.e09 || ppt.X() < -1.e09 ) return;
1252 if (ppt.Y() > 1.e09 || ppt.Y() < -1.e09 ) return;
1253
96f3bacc 1254 gp_Pnt2d pt(ppt.X()*curview->GetZoom(),ppt.Y()*curview->GetZoom());
7fd59977 1255
1256 if (pt.X() > 1.e09 || pt.X() < -1.e09 ) return;
1257 if (pt.Y() > 1.e09 || pt.Y() < -1.e09 ) return;
1258
1259 switch (CurrentMode) {
1260
1261 case DRAW :
1262 {
96f3bacc 1263 int X = (int) ( pt.X() + moveX + curview->GetDx());
1264 int Y = (int) (-pt.Y() + moveY - curview->GetDy());
7fd59977 1265 curview->DrawString(X,Y,(char *)S);
1266 if (Draw_Bounds) {
1267 if (pt.X() + moveX > xmax) xmax = pt.X();
1268 if (pt.X() + moveX < xmin) xmin = pt.X();
1269 if (-pt.Y() - moveY > ymax) ymax = -pt.Y();
1270 if (-pt.Y() - moveY < ymin) ymin = -pt.Y();
1271 }
1272 }
1273 break;
1274
1275 case POSTSCRIPT :
1276 {
1277 Standard_Integer x = (Standard_Integer )( (pt.X() + moveX - ps_vx) * ps_kx + ps_px);
1278 Standard_Integer y = (Standard_Integer )( (pt.Y() + moveY - ps_vy) * ps_ky + ps_py);
1279 (*ps_stream) <<"stroke\n";
1280 (*ps_stream) << x << " " << y << " m\n";
1281 (*ps_stream) <<"("<<S<<") show\nnewpath\n";
1282 }
1283 break;
1284
1285 case PICK :
1286 break;
1287 }
1288}
1289
1290//=======================================================================
1291//function : DrawString
1292//purpose :
1293//=======================================================================
1294
1295void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1296 const Standard_CString S)
1297{
1298 if (Draw_Batch) return;
1299 DrawString(ppt,S,0.0,0.0);
1300}
1301
1302//=======================================================================
1303//function : DrawString
1304//purpose :
1305//=======================================================================
1306
1307void Draw_Display::DrawString(const gp_Pnt& pt,
1308 const Standard_CString S,
1309 const Standard_Real moveX,
1310 const Standard_Real moveY)
1311{
1312 if (Draw_Batch) return;
1313 DrawString(Project(pt),S,moveX,moveY);
1314}
1315
1316//=======================================================================
1317//function : DrawString
1318//purpose :
1319//=======================================================================
1320
1321void Draw_Display::DrawString(const gp_Pnt& pt,
1322 const Standard_CString S)
1323{
1324 if (Draw_Batch) return;
1325 DrawString(Project(pt),S,0.0,0.0);
1326}
1327
1328
1329// *******************************************************************
1330// Drawing data static variables
1331// *******************************************************************
1332static gp_Pnt2d PtCur; // current 2D point
1333static gp_Pnt PtPers; // current 3D point for Pers
1334
1335//=======================================================================
1336//function : Project
1337//purpose :
1338//=======================================================================
1339
1340void Draw_Display::Project(const gp_Pnt& p, gp_Pnt2d& p2d) const
1341{
1342 if (Draw_Batch) return;
1343 gp_Pnt pt = p;
96f3bacc 1344 pt.Transform(curview->GetMatrix());
7fd59977 1345 Standard_Real xp,yp,zp;
1346 pt.Coord(xp,yp,zp);
96f3bacc 1347 if (curview->IsPerspective()) {
1348 const Standard_Real aDistance = curview->GetFocalDistance();
1349 xp = xp * aDistance / (aDistance-zp);
1350 yp = yp * aDistance / (aDistance-zp);
7fd59977 1351 }
1352 p2d.SetCoord(xp,yp);
1353}
1354
1355//=======================================================================
1356//function : Draw_Display
1357//purpose :
1358//=======================================================================
1359
1360Draw_Display::Draw_Display ()
1361{
1362 if (Draw_Batch) return;
1363 if (curview) {
96f3bacc 1364 PtPers.SetCoord(0., 0., 0.);
1365 PtPers.Transform(curview->GetMatrix());
1366 PtCur.SetCoord(PtPers.X()*curview->GetZoom(),PtPers.Y()*curview->GetZoom());
7fd59977 1367 }
1368}
1369
1370//=======================================================================
1371//function : MoveTo 2D
1372//purpose :
1373//=======================================================================
1374
1375void Draw_Display::MoveTo (const gp_Pnt2d& pp)
1376{
1377 if (Draw_Batch) return;
96f3bacc 1378 const Standard_Real aZoom = curview->GetZoom();
1379 gp_Pnt2d pt(pp.X() * aZoom, pp.Y() * aZoom);
7fd59977 1380 switch (CurrentMode) {
1381
1382 case DRAW :
1383 PtCur = pt;
1384 if (Draw_Bounds) {
1385 if (pt.X() > xmax) xmax = pt.X();
1386 if (pt.X() < xmin) xmin = pt.X();
1387 if (pt.Y() > ymax) ymax = pt.Y();
1388 if (pt.Y() < ymin) ymin = pt.Y();
1389 }
1390 break;
1391
1392 case PICK :
1393 PtCur = pt;
1394 break;
1395
1396 case POSTSCRIPT :
1397 {
1398 Standard_Integer x = (Standard_Integer )( (pt.X() - ps_vx) * ps_kx + ps_px);
1399 Standard_Integer y = (Standard_Integer )( (pt.Y() - ps_vy) * ps_ky + ps_py);
1400 (*ps_stream) <<"stroke\nnewpath\n"<< x << " " << y << " m\n";
1401 }
1402 break;
1403 }
1404}
1405
1406//=======================================================================
1407//function : DrawTo 2D
1408//purpose :
1409//=======================================================================
1410inline Standard_Integer CalculRegion(const Standard_Real x,
1411 const Standard_Real y,
1412 const Standard_Real x1,
1413 const Standard_Real y1,
1414 const Standard_Real x2,
1415 const Standard_Real y2) {
1416 Standard_Integer r;
1417 if(x<x1) { r=1; } else { if(x>x2) { r=2; } else { r=0; } }
1418 if(y<y1) { r|=4; } else { if(y>y2) { r|=8; } }
1419 return(r);
1420}
1421
1422Standard_Boolean Trim(gp_Pnt2d& P1,gp_Pnt2d& P2,
1423 Standard_Real x0,
1424 Standard_Real y0,
1425 Standard_Real x1,
1426 Standard_Real y1) {
1427 Standard_Real xa=P1.X(),ya=P1.Y(),xb=P2.X(),yb=P2.Y();
1428
1429 Standard_Integer regiona=0,regionb=0;
1430 regiona = CalculRegion(xa,ya,x0,y0,x1,y1);
1431 regionb = CalculRegion(xb,yb,x0,y0,x1,y1);
1432 if((regiona & regionb)==0) {
1433 Standard_Real dx=xb-xa;
1434 Standard_Real dy=yb-ya;
1435 Standard_Real dab=sqrt(dx*dx+dy*dy);
1436 if(dab<1e-10) return(Standard_False);
1437 dx/=dab;
1438 dy/=dab;
1439
1440 Standard_Real xm,ym,mfenx,mfeny;
1441 mfenx=xm=0.5*(x0+x1);
1442 mfeny=ym=0.5*(y0+y1);
1443 x1-=x0; y1-=y0;
1444 Standard_Real d=sqrt(x1*x1+y1*y1) * 2;
1445
1446 Standard_Real p=(xm-xa)*dx+(ym-ya)*dy;
1447 xm=xa+p*dx;
1448 ym=ya+p*dy;
1449 gp_Pnt2d Pm(xm,ym);
1450
1451 gp_Pnt2d MFen(mfenx,mfeny);
1452 if(MFen.SquareDistance(Pm) > d*d) return(Standard_False);
1453
1454 Standard_Real PmDistP1 = Pm.Distance(P1);
1455 Standard_Real PmDistP2 = Pm.Distance(P2);
1456
1457 Standard_Real amab = (xm-xa)*(xb-xa)+(ym-ya)*(yb-ya);
1458
1459 if(amab > 0) { //-- M est compris entre A et B
1460 if(PmDistP1 > d) {
1461 P1.SetCoord(xm-d*dx,ym-d*dy);
1462 }
1463 if(PmDistP2 >d) {
1464 P2.SetCoord(xm+d*dx,ym+d*dy);
1465 }
1466 }
1467 else if(PmDistP1 < PmDistP2) { //-- On a M P1 P2
1468 if(PmDistP2 > d) {
1469 P2.SetCoord(xm+d*dx,ym+d*dy);
1470 }
1471 }
1472 else { //-- On a P1 P2 M
1473 if(PmDistP1 > d) {
1474 P1.SetCoord(xm-d*dx,ym-d*dy);
1475 }
1476 }
1477 return(Standard_True);
1478 }
1479 else return(Standard_False);
1480}
1481
1482
1483
1484
1485void Draw_Display::DrawTo (const gp_Pnt2d& pp2)
1486{
1487 if (Draw_Batch) return;
1488 if (pp2.X() > 1.e09 || pp2.X() < -1.e09 ) return;
1489 if (pp2.Y() > 1.e09 || pp2.Y() < -1.e09 ) return;
1490
96f3bacc 1491 gp_Pnt2d p2(pp2.X() * curview->GetZoom(), pp2.Y() * curview->GetZoom());
7fd59977 1492
1493 if (p2.X() > 1.e09 || p2.X() < -1.e09 ) return;
1494 if (p2.Y() > 1.e09 || p2.Y() < -1.e09 ) return;
1495
1496 gp_Pnt2d p1 = PtCur;
1497 if (p1.X() > 1.e09 || p1.X() < -1.e09 ) return;
1498 if (p1.Y() > 1.e09 || p1.Y() < -1.e09 ) return;
1499
1500 PtCur = p2;
1501
1502 switch (CurrentMode) {
1503
1504 case DRAW : {
1505
1506#if 1
1507 Standard_Integer x0,y0,x1,y1;
1508 curview->GetFrame(x0,y0,x1,y1);
1509
1510
1511 //Standard_Integer qx0,qy0,qx1,qy1;
1512 //curview->viewer->GetFrame(curview->id,qx0,qy0,qx1,qy1);
1513 //if(qx0!=x0 || qx1!=x1 || qy0!=y0 || qy1!=y1) {
1514 // x0=qx0; x1=qx1; y0=qy0; y1=qy1;
1515 //}
1516
1517
1518
1519 gp_Pnt2d PI1(p1);
1520 gp_Pnt2d PI2(p2);
1521
96f3bacc 1522 if(Trim(PI1,PI2,x0,y0,x1,y1))
1523 {
1524 segm[nbseg].Init(static_cast<Standard_Integer>( PI1.X() + curview->GetDx()),
1525 static_cast<Standard_Integer>(-PI1.Y() - curview->GetDy()),
1526 static_cast<Standard_Integer>( PI2.X() + curview->GetDx()),
1527 static_cast<Standard_Integer>(-PI2.Y() - curview->GetDy()));
1528 ++nbseg;
7fd59977 1529 }
1530#else
96f3bacc 1531 segm[nbseg].Init(static_cast<Standard_Integer>( p1.X() + curview->GetDx()),
1532 static_cast<Standard_Integer>(-p1.Y() - curview->GetDy()),
1533 static_cast<Standard_Integer>( p2.X() + curview->GetDx()),
1534 static_cast<Standard_Integer>(-p2.Y() - curview->GetDy()));
7fd59977 1535 nbseg++;
1536#endif
1537 if (nbseg == MAXSEGMENT) {
1538 Draw_Flush();
1539 }
1540 if (Draw_Bounds) {
1541 if (p2.X() > xmax) xmax = p2.X();
1542 if (p2.X() < xmin) xmin = p2.X();
1543 if (p2.Y() > ymax) ymax = p2.Y();
1544 if (p2.Y() < ymin) ymin = p2.Y();
1545 }
1546 }
1547 break;
1548
1549 case PICK :
1550 if (!found) {
1551 Standard_Integer x1 = (int) p1.X() ;
1552 Standard_Integer y1 = (int) p1.Y() ;
1553 Standard_Integer x2 = (int) p2.X() ;
1554 Standard_Integer y2 = (int) p2.Y() ;
1555 if ((x1 >= xpick + precpick) && (x2 >= xpick + precpick)) break;
1556 if ((x1 <= xpick - precpick) && (x2 <= xpick - precpick)) break;
1557 if ((y1 >= ypick + precpick) && (y2 >= ypick + precpick)) break;
1558 if ((y1 <= ypick - precpick) && (y2 <= ypick - precpick)) break;
1559
1560 Standard_Boolean inside = Standard_True;
1561 if ((x1 > xpick + precpick) || (x2 > xpick + precpick)) {
1562 Standard_Real y = (Standard_Real) y1 +
1563 (Standard_Real) (y2-y1) * (Standard_Real) (xpick+precpick-x1) /
1564 (Standard_Real) (x2 - x1);
1565 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1566 found = Standard_True;
1567 lastPickParam = (Standard_Real) (xpick - x1) /
1568 (Standard_Real) (x2 - x1);
1569 break;
1570 }
1571 else
1572 inside = Standard_False;
1573 }
1574
1575 if ((x1 < xpick - precpick) || (x2 < xpick - precpick)) {
1576 Standard_Real y = (Standard_Real) y1 +
1577 (Standard_Real) (y2-y1) * (Standard_Real) (xpick-precpick-x1) /
1578 (Standard_Real) (x2 - x1);
1579 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1580 found = Standard_True;
1581 lastPickParam = (Standard_Real) (xpick - x1) /
1582 (Standard_Real) (x2 - x1);
1583 break;
1584 }
1585 else
1586 inside = Standard_False;
1587 }
1588
1589
1590 if ((y1 > ypick + precpick) || (y2 > ypick + precpick)) {
1591 Standard_Real x = (Standard_Real) x1 +
1592 (Standard_Real) (x2-x1) * (Standard_Real) (ypick+precpick-y1) /
1593 (Standard_Real) (y2 - y1);
1594 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1595 found = Standard_True;
1596 lastPickParam = (Standard_Real) (ypick - y1) /
1597 (Standard_Real) (y2 - y1);
1598 break;
1599 }
1600 else
1601 inside = Standard_False;
1602 }
1603
1604
1605 if ((y1 < ypick - precpick) || (y2 < ypick - precpick)) {
1606 Standard_Real x = (Standard_Real) x1 +
1607 (Standard_Real) (x2-x1) * (Standard_Real) (ypick-precpick-y1) /
1608 (Standard_Real) (y2 - y1);
1609 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1610 found = Standard_True;
1611 lastPickParam = (Standard_Real) (ypick - y1) /
1612 (Standard_Real) (y2 - y1);
1613 break;
1614 }
1615 else
1616 inside = Standard_False;
1617 }
1618 found = found || inside;
1619 if (found) {
1620 if (Abs(x2-x1) > Abs(y2-y1)) {
1621 if (Abs(x2-x1) < 1e-5) lastPickParam = 0;
1622 else
1623 lastPickParam = (Standard_Real)(xpick - x1) /
1624 (Standard_Real)(x2 - x1);
1625 }
1626 else {
1627 if (Abs(y2-y1) < 1e-5) lastPickParam = 0;
1628 else
1629 lastPickParam = (Standard_Real)(ypick - y1) /
1630 (Standard_Real)(y2 - y1);
1631 }
1632 }
1633 }
1634 break;
1635
1636 case POSTSCRIPT :
1637 {
1638 Standard_Integer x = (Standard_Integer )( (p2.X() - ps_vx) * ps_kx + ps_px);
1639 Standard_Integer y = (Standard_Integer )( (p2.Y() - ps_vy) * ps_ky + ps_py);
1640 (*ps_stream) << x << " " << y << " l\n";
1641 }
1642 break;
1643 }
1644
1645}
1646
1647//=======================================================================
1648//function : MoveTo
1649//purpose :
1650//=======================================================================
1651
1652void Draw_Display::MoveTo (const gp_Pnt& pt)
1653{
1654 if (Draw_Batch) return;
1655 if (CurrentMode == PICK) {
1656 if (!found) lastPickP1 = pt;
1657 else return;
1658 }
1659 PtPers = pt;
96f3bacc 1660 PtPers.Transform(curview->GetMatrix());
7fd59977 1661 Standard_Real xp = PtPers.X();
1662 Standard_Real yp = PtPers.Y();
96f3bacc 1663 if (curview->IsPerspective())
1664 {
7fd59977 1665 Standard_Real ZPers = PtPers.Z();
96f3bacc 1666 const Standard_Real aDistance = curview->GetFocalDistance();
1667 if (ZPers < aDistance * precpers)
1668 {
1669 xp=xp * aDistance / (aDistance-ZPers);
1670 yp=yp * aDistance / (aDistance-ZPers);
7fd59977 1671 }
1672 }
1673 MoveTo(gp_Pnt2d(xp,yp));
1674}
1675
1676//=======================================================================
1677//function : DrawTo
1678//purpose :
1679//=======================================================================
1680
1681void Draw_Display::DrawTo (const gp_Pnt& pt)
1682{
1683 if (Draw_Batch) return;
1684 if ((CurrentMode == PICK) && found) return;
1685
96f3bacc 1686 gp_Pnt pt2 = pt.Transformed(curview->GetMatrix());
7fd59977 1687 Standard_Real xp2 = pt2.X();
1688 Standard_Real yp2 = pt2.Y();
1689
96f3bacc 1690 if (curview->IsPerspective())
1691 {
1692 const Standard_Real aZoom = curview->GetZoom();
1693 const Standard_Real aDistance = curview->GetFocalDistance();
1694
7fd59977 1695 Standard_Real xp1 = PtPers.X();
1696 Standard_Real yp1 = PtPers.Y();
1697 Standard_Real zp1 = PtPers.Z();
1698 Standard_Real zp2 = pt2.Z();
1699 PtPers = pt2;
96f3bacc 1700 if ((zp1 >= aDistance*precpers) && (zp2 >= aDistance*precpers) )
1701 {
7fd59977 1702 return; // segment is not visible in perspective (behind the eye)
1703 }
96f3bacc 1704 else if (zp1 >= aDistance*precpers)
1705 {
1706 xp1=xp1+(xp2-xp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1707 yp1=yp1+(yp2-yp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1708 zp1=aDistance*precpers;
1709 xp1=xp1*aDistance/(aDistance-zp1);
1710 yp1=yp1*aDistance/(aDistance-zp1);
1711 MoveTo( gp_Pnt2d(xp1 * aZoom, yp1 * aZoom) );
1712 }
1713 else if (zp2 >= aDistance*precpers)
1714 {
1715 xp2=xp2+(xp1-xp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1716 yp2=yp2+(yp1-yp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1717 zp2=aDistance*precpers;
7fd59977 1718 }
96f3bacc 1719 xp2 = xp2 * aDistance / (aDistance - zp2);
1720 yp2 = yp2 * aDistance / (aDistance - zp2);
7fd59977 1721 }
1722 DrawTo(gp_Pnt2d(xp2,yp2));
1723 if (CurrentMode == PICK) {
1724 if (!found) lastPickP1 = pt;
1725 else lastPickP2 = pt;
1726 }
1727}
1728
1729//=======================================================================
1730//function : Draw
1731//purpose :
1732//=======================================================================
1733
1734void Draw_Display::Draw (const gp_Pnt& p1, const gp_Pnt& p2)
1735{
1736 if (Draw_Batch) return;
1737 MoveTo(p1);
1738 DrawTo(p2);
1739}
1740
1741//=======================================================================
1742//function : Draw
1743//purpose :
1744//=======================================================================
1745
1746void Draw_Display::Draw(const gp_Pnt2d& p1, const gp_Pnt2d& p2)
1747{
1748 if (Draw_Batch) return;
1749 MoveTo(p1);
1750 DrawTo(p2);
1751}
1752
1753
1754//=======================================================================
1755//function : ViewId
1756//purpose :
1757//=======================================================================
1758
1759Standard_Integer Draw_Display::ViewId() const
1760{
1761 if (Draw_Batch) return 0;
1762 return curviewId;
1763}
1764
1765
1766//=======================================================================
1767//function : HasPicked
1768//purpose :
1769//=======================================================================
1770
1771Standard_Boolean Draw_Display::HasPicked() const
1772{
1773 if (Draw_Batch) return Standard_False;
1774 return found;
1775}
1776