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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Draw_Viewer.hxx>
18 #include <Draw_View.hxx>
19
20 #include <gp_Pnt.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Draw_Window.hxx>
23 #include <Draw_Display.hxx>
24 #include <TCollection_AsciiString.hxx>
25
26 #define precpers 0.95
27 #define ButtonPress 4
28 #define MotionNotify 6
29 static const Standard_Real DRAWINFINITE = 1e50;
30 Standard_EXPORT Standard_Boolean Draw_Bounds = Standard_True;
31 extern Standard_Boolean Draw_Batch;
32 const Standard_Integer MAXSEGMENT = 1000;
33 Draw_XSegment segm[MAXSEGMENT];
34 static int nbseg=0;
35 static Draw_View* curview = NULL;
36 static Standard_Integer curviewId = 0;
37 static char blank[2] = "";
38 static Standard_Real xmin,xmax,ymin,ymax;
39 static Standard_Boolean found = Standard_False;
40 static Standard_Integer xpick, ypick, precpick;
41 static gp_Pnt lastPickP1;
42 static gp_Pnt lastPickP2;
43 static Standard_Real lastPickParam;
44 static Draw_Color highlightcol;
45 static Draw_Color currentcolor;
46 static Standard_Boolean highlight = Standard_False;
47 static Standard_Integer ps_vx, ps_vy;
48 static Standard_Real ps_kx, ps_ky;
49 static Standard_Integer ps_px, ps_py;
50 static std::ostream* ps_stream;
51 static Standard_Integer ps_width[MAXCOLOR];
52 static Standard_Real ps_gray[MAXCOLOR];
53
54 enum DrawingMode {DRAW, PICK, POSTSCRIPT};
55 static DrawingMode CurrentMode = DRAW;
56
57 //=======================================================================
58 //function : Create
59 //purpose :
60 //=======================================================================
61
Draw_Viewer()62 Draw_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
DefineColor(const Standard_Integer i,const char * colname)78 Standard_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
MakeView(const Standard_Integer id,const char * typ,const Standard_Integer X,const Standard_Integer Y,const Standard_Integer W,const Standard_Integer H)90 void 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
102 myViews[id]->SetDx(W / 2);
103 myViews[id]->SetDy(- H / 2);
104
105 if (!myViews[id]->Init(typ))
106 DeleteView(id);
107
108 RepaintView(id);
109 }
110 }
111
112 #ifdef _WIN32
113 //=======================================================================
114 //function : MakeView
115 //purpose :
116 //=======================================================================
117
MakeView(const Standard_Integer id,const char * typ,const Standard_Integer X,const Standard_Integer Y,const Standard_Integer W,const Standard_Integer H,HWND win,Standard_Boolean useBuffer)118 void 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
132 myViews[id]->SetDx( W / 2);
133 myViews[id]->SetDy(-H / 2);
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
MakeView(const Standard_Integer id,const char * typ,const char * window)147 void 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
158 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
159 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
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
SetTitle(const Standard_Integer id,const char * name)174 void Draw_Viewer::SetTitle (const Standard_Integer id, const char* name)
175 {
176 if (Draw_Batch) return;
177 if(myViews[id]) myViews[id]->SetTitle (name);
178 }
179
180 //=======================================================================
181 //function : ResetView
182 //purpose : reset view zoom and axes
183 //=======================================================================
184
ResetView(const Standard_Integer id)185 void Draw_Viewer::ResetView(const Standard_Integer id)
186 {
187 if (Draw_Batch) return;
188 if (myViews[id]) {
189 myViews[id]->Init(myViews[id]->Type());
190 ConfigView(id);
191 }
192 }
193
194 //=======================================================================
195 //function : SetZoom
196 //purpose :
197 //=======================================================================
198
SetZoom(const Standard_Integer id,const Standard_Real z)199 void Draw_Viewer::SetZoom (const Standard_Integer id, const Standard_Real z)
200 {
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);
209 Standard_Integer X,Y,W,H;
210 GetPosSize(id,X,Y,W,H);
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);
222 }
223 }
224
225 //=======================================================================
226 //function : RotateView
227 //purpose :
228 //=======================================================================
229
RotateView(const Standard_Integer id,const gp_Dir2d & D,const Standard_Real A)230 void 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]) {
236 gp_Trsf T = myViews[id]->GetMatrix();
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
RotateView(const Standard_Integer id,const gp_Pnt & P,const gp_Dir & D,const Standard_Real A)252 void 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);
261 myViews[id]->Transform(T);
262 }
263 }
264
265
266 //=======================================================================
267 //function : SetFocal
268 //purpose :
269 //=======================================================================
270
SetFocal(const Standard_Integer id,const Standard_Real F)271 void Draw_Viewer::SetFocal (const Standard_Integer id, const Standard_Real F)
272 {
273 if (Draw_Batch) return;
274 if (myViews[id])
275 myViews[id]->SetFocalDistance(F);
276 }
277
278 //=======================================================================
279 //function : GetType
280 //purpose :
281 //=======================================================================
282
GetType(const Standard_Integer id) const283 char* Draw_Viewer::GetType (const Standard_Integer id) const
284 {
285 if (Draw_Batch) return blank;
286 if (myViews[id])
287 return const_cast<char*>(myViews[id]->Type());
288 else
289 return blank;
290 }
291
292 //=======================================================================
293 //function : Zoom
294 //purpose :
295 //=======================================================================
296
Zoom(const Standard_Integer id) const297 Standard_Real Draw_Viewer::Zoom (const Standard_Integer id) const
298 {
299 if (Draw_Batch) return Standard_False;
300 if (myViews[id])
301 return myViews[id]->GetZoom();
302 else
303 return 0.0;
304 }
305
306 //=======================================================================
307 //function : Focal
308 //purpose :
309 //=======================================================================
310
Focal(const Standard_Integer id) const311 Standard_Real Draw_Viewer::Focal (const Standard_Integer id) const
312 {
313 if (Draw_Batch) return 1.;
314 if (myViews[id])
315 return myViews[id]->GetFocalDistance();
316 else
317 return 0;
318 }
319
320 //=======================================================================
321 //function : GetTrsf
322 //purpose :
323 //=======================================================================
324
GetTrsf(const Standard_Integer id,gp_Trsf & T) const325 void Draw_Viewer::GetTrsf (const Standard_Integer id,gp_Trsf& T) const
326 {
327 if (Draw_Batch) return;
328 if (myViews[id])
329 T = myViews[id]->GetMatrix();
330 }
331
332 //=======================================================================
333 //function : Is3D
334 //purpose :
335 //=======================================================================
336
Is3D(const Standard_Integer id) const337 Standard_Boolean Draw_Viewer::Is3D (const Standard_Integer id) const
338 {
339 if (Draw_Batch) return Standard_False;
340 if (myViews[id])
341 return !myViews[id]->Is2D();
342 else
343 return Standard_False;
344 }
345
346 //=======================================================================
347 //function : SetTrsf
348 //purpose :
349 //=======================================================================
350
SetTrsf(const Standard_Integer id,gp_Trsf & T)351 void Draw_Viewer::SetTrsf (const Standard_Integer id,gp_Trsf& T)
352 {
353 if (Draw_Batch) return;
354 if (myViews[id])
355 myViews[id]->SetMatrix(T);
356 }
357
358 //=======================================================================
359 //function : GetPosSize
360 //purpose :
361 //=======================================================================
362
GetPosSize(const Standard_Integer id,Standard_Integer & X,Standard_Integer & Y,Standard_Integer & W,Standard_Integer & H)363 void 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
GetFrame(const Standard_Integer id,Standard_Integer & xminf,Standard_Integer & yminf,Standard_Integer & xmaxf,Standard_Integer & ymaxf)380 void 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);
388 xminf = - myViews[id]->GetDx();
389 xmaxf = W - myViews[id]->GetDx();
390 yminf = - myViews[id]->GetDy() - H;
391 ymaxf = - myViews[id]->GetDy();
392 }
393 }
394
395 //=======================================================================
396 //function : FitView
397 //purpose :
398 //=======================================================================
399
FitView(const Standard_Integer id,const Standard_Integer frame)400 void 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
406 Standard_Boolean is2d = myViews[id]->Is2D();
407 Standard_Integer i,nbviews = 0;
408 for (i = 1; i < MAXVIEW; i++) {
409 if (myViews[i]) {
410 if (myViews[i]->Is2D() == is2d)
411 ++nbviews;
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;
442 umin = umin / curview->GetZoom();
443 vmin = vmin / curview->GetZoom();
444 umax = umax / curview->GetZoom();
445 vmax = vmax / curview->GetZoom();
446 if ((umax - umin) < 1.e-6) {
447 if ((vmax - vmin) < 1.e-6)
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 }
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) );
462 }
463 }
464
465 //=======================================================================
466 //function : PanView
467 //purpose :
468 //=======================================================================
469
PanView(const Standard_Integer id,const Standard_Integer DX,const Standard_Integer DY)470 void 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]) {
475 myViews[id]->SetDx(myViews[id]->GetDx() + DX);
476 myViews[id]->SetDy(myViews[id]->GetDy() + DY);
477 }
478 }
479
480
481 //=======================================================================
482 //function : SetPan
483 //purpose :
484 //=======================================================================
485
SetPan(const Standard_Integer id,const Standard_Integer DX,const Standard_Integer DY)486 void 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]) {
491 myViews[id]->SetDx(DX);
492 myViews[id]->SetDy(DY);
493 }
494 }
495
496 //=======================================================================
497 //function : GetPan
498 //purpose :
499 //=======================================================================
500
GetPan(const Standard_Integer id,Standard_Integer & DX,Standard_Integer & DY)501 void Draw_Viewer::GetPan(const Standard_Integer id,
502 Standard_Integer& DX, Standard_Integer& DY)
503 {
504 if (Draw_Batch) return;
505 if (myViews[id]) {
506 DX = myViews[id]->GetDx();
507 DY = myViews[id]->GetDy();
508 }
509 }
510
511 //=======================================================================
512 //function : HasView
513 //purpose :
514 //=======================================================================
515
HasView(const Standard_Integer id) const516 Standard_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
DisplayView(const Standard_Integer id) const528 void 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
HideView(const Standard_Integer id) const539 void 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
ClearView(const Standard_Integer id) const552 void 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
RemoveView(const Standard_Integer id)563 void 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 //=======================================================================
RepaintView(const Standard_Integer id) const576 void 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
588 #ifdef _WIN32
589 //=======================================================================
590 //function : ResizeView
591 //purpose : WNT re-drawing optimization
592 //=======================================================================
ResizeView(const Standard_Integer id) const593 void 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 //=======================================================================
UpdateView(const Standard_Integer id,const Standard_Boolean forced) const606 void 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
ConfigView(const Standard_Integer id) const624 void Draw_Viewer::ConfigView (const Standard_Integer id) const
625 {
626 if (Draw_Batch) return;
627 if (myViews[id])
628 {
629 myViews[id]->SetDx(myViews[id]->WidthWin() / 2);
630 myViews[id]->SetDy(-myViews[id]->HeightWin() / 2);
631 }
632 }
633
634 //=======================================================================
635 //function : PostScriptView
636 //purpose :
637 //=======================================================================
638
PostScriptView(const Standard_Integer id,const Standard_Integer VXmin,const Standard_Integer VYmin,const Standard_Integer VXmax,const Standard_Integer VYmax,const Standard_Integer PXmin,const Standard_Integer PYmin,const Standard_Integer PXmax,const Standard_Integer PYmax,std::ostream & sortie) const639 void Draw_Viewer::PostScriptView (const Standard_Integer id,
640 const Standard_Integer VXmin,
641 const Standard_Integer VYmin,
642 const Standard_Integer VXmax,
643 const Standard_Integer VYmax,
644 const Standard_Integer PXmin,
645 const Standard_Integer PYmin,
646 const Standard_Integer PXmax,
647 const Standard_Integer PYmax,
648 std::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);
663 Standard_Boolean view2d = myViews[id]->Is2D();
664 for (Standard_Integer i = 1; i <= n; i++)
665 if (myDrawables(i)->Is3D()) {
666 if (!view2d) myDrawables(i)->DrawOn(DF);
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
PostColor(const Standard_Integer icol,const Standard_Integer width,const Standard_Real gray)681 void 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
SaveView(const Standard_Integer id,const char * filename)696 Standard_Boolean Draw_Viewer::SaveView(const Standard_Integer id,
697 const char* filename)
698 {
699 if (Draw_Batch)
700 {
701 return Standard_False;
702 }
703 Flush();
704 if (myViews[id]) {
705 return myViews[id]->Save(filename);
706 }
707 else
708 {
709 std::cerr << "View " << id << " doesn't exists!\n";
710 return Standard_False;
711 }
712 }
713
714 //=======================================================================
715 //function : RepaintAll
716 //purpose :
717 //=======================================================================
718
RepaintAll() const719 void Draw_Viewer::RepaintAll () const
720 {
721 if (Draw_Batch) return;
722 for (Standard_Integer id = 0; id < MAXVIEW; id++)
723 RepaintView(id);
724 }
725
726 //=======================================================================
727 //function : Repaint2D
728 //purpose :
729 //=======================================================================
730
Repaint2D() const731 void Draw_Viewer::Repaint2D () const
732 {
733 if (Draw_Batch) return;
734 for (Standard_Integer id = 0; id < MAXVIEW; id++)
735 if (myViews[id]) {
736 if (myViews[id]->Is2D())
737 RepaintView(id);
738 }
739 }
740
741 //=======================================================================
742 //function : Repaint3D
743 //purpose :
744 //=======================================================================
745
Repaint3D() const746 void Draw_Viewer::Repaint3D () const
747 {
748 if (Draw_Batch) return;
749 for (Standard_Integer id = 0; id < MAXVIEW; id++)
750 if (myViews[id]) {
751 if (!myViews[id]->Is2D())
752 RepaintView(id);
753 }
754 }
755
756 //=======================================================================
757 //function : DeleteView
758 //purpose :
759 //=======================================================================
760
DeleteView(const Standard_Integer id)761 void Draw_Viewer::DeleteView(const Standard_Integer id)
762 {
763 if (Draw_Batch) return;
764 if (myViews[id] != NULL) {
765 delete myViews[id];
766 myViews[id] = NULL;
767 }
768 }
769
770 //=======================================================================
771 //function : Clear
772 //purpose :
773 //=======================================================================
774
Clear()775 void Draw_Viewer::Clear()
776 {
777 if (Draw_Batch) return;
778 for (Standard_Integer i = 1; i <= myDrawables.Length(); i++)
779 myDrawables(i)->Visible(Standard_False);
780 myDrawables.Clear();
781 for (Standard_Integer id = 0; id < MAXVIEW; id++)
782 ClearView(id);
783 }
784
785 //=======================================================================
786 //function : Clear2D
787 //purpose :
788 //=======================================================================
789
Clear2D()790 void Draw_Viewer::Clear2D()
791 {
792 if (Draw_Batch) return;
793 Standard_Integer i = 1;
794 while (i <= myDrawables.Length()) {
795 if (myDrawables(i)->Is3D())
796 i++;
797 else {
798 myDrawables(i)->Visible(Standard_False);
799 myDrawables.Remove(i);
800 }
801 }
802 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
803 if (myViews[id]) {
804 if (myViews[id]->Is2D())
805 ClearView(id);
806 }
807 }
808 }
809
810 //=======================================================================
811 //function : Clear3D
812 //purpose :
813 //=======================================================================
814
Clear3D()815 void Draw_Viewer::Clear3D()
816 {
817 if (Draw_Batch) return;
818 Standard_Integer i = 1;
819 while (i <= myDrawables.Length()) {
820 if (myDrawables(i)->Is3D()) {
821 myDrawables(i)->Visible(Standard_False);
822 myDrawables.Remove(i);
823 }
824 else
825 i++;
826 }
827 for (Standard_Integer id = 0; id < MAXVIEW; id++) {
828 if (myViews[id]) {
829 if (!myViews[id]->Is2D())
830 ClearView(id);
831 }
832 }
833 }
834
835 //=======================================================================
836 //function : Flush
837 //purpose :
838 //=======================================================================
839
Flush()840 void Draw_Viewer::Flush()
841 {
842 if (Draw_Batch) return;
843 Draw_Window::Flush();
844 }
845
846 //=======================================================================
847 //function : DrawOnView
848 //purpose :
849 //=======================================================================
850
DrawOnView(const Standard_Integer id,const Handle (Draw_Drawable3D)& D) const851 void Draw_Viewer::DrawOnView(const Standard_Integer id,
852 const Handle(Draw_Drawable3D)& D) const
853 {
854 if (Draw_Batch) return;
855 if (myViews[id]) {
856 Draw_Display d = MakeDisplay(id);
857 xmin = ymin = DRAWINFINITE;
858 xmax = ymax = -DRAWINFINITE;
859
860 Standard_Boolean view2d = myViews[id]->Is2D();
861 myViews[id]->ResetFrame();
862 if ((D->Is3D() && !view2d) || (!D->Is3D() && view2d))
863 {
864 D->DrawOn(d);
865 if (CurrentMode == DRAW)
866 D->SetBounds(xmin,xmax,ymin,ymax);
867 d.Flush();
868 }
869 }
870 }
871
872 //=======================================================================
873 //function : HighlightOnView
874 //purpose :
875 //=======================================================================
876
HighlightOnView(const Standard_Integer id,const Handle (Draw_Drawable3D)& D,const Draw_ColorKind C) const877 void Draw_Viewer::HighlightOnView (const Standard_Integer id,
878 const Handle(Draw_Drawable3D)& D,
879 const Draw_ColorKind C) const
880 {
881 if (Draw_Batch) return;
882 highlight = Standard_True;
883 highlightcol = C;
884 DrawOnView(id,D);
885 highlight = Standard_False;
886 }
887
888 //=======================================================================
889 //function : AddDrawable
890 //purpose :
891 //=======================================================================
892
AddDrawable(const Handle (Draw_Drawable3D)& D)893 void Draw_Viewer::AddDrawable (const Handle(Draw_Drawable3D)& D)
894 {
895 if (Draw_Batch) return;
896 if (!D.IsNull() && !D->Visible()) {
897 myDrawables.Append(D);
898 D->Visible(Standard_True);
899 }
900 }
901
902 //=======================================================================
903 //function : RemoveDrawable
904 //purpose :
905 //=======================================================================
906
RemoveDrawable(const Handle (Draw_Drawable3D)& D)907 void Draw_Viewer::RemoveDrawable (const Handle(Draw_Drawable3D)& D)
908 {
909 if (Draw_Batch) return;
910 if (!D.IsNull() && D->Visible()) {
911 Standard_Integer index;
912 for (index = 1; index <= myDrawables.Length(); index++) {
913 if (myDrawables(index) == D) {
914 D->Visible(Standard_False);
915 myDrawables.Remove(index);
916 return;
917 }
918 }
919 }
920 }
921
922 //=======================================================================
923 //function : MakeDisplay
924 //purpose : return a display on the view
925 //=======================================================================
926
MakeDisplay(const Standard_Integer id) const927 Draw_Display Draw_Viewer::MakeDisplay (const Standard_Integer id) const
928 {
929 if (Draw_Batch) {Draw_Display dis;return dis;}
930 curviewId = id;
931 curview = myViews[id];
932 nbseg = 0;
933 Draw_Color initcol(Draw_blanc);
934 // to force setting the color
935 currentcolor = Draw_Color(Draw_rouge);
936 Draw_Display dis;
937 dis.SetColor(initcol);
938 dis.SetMode(0x3 /*GXcopy*/);
939 return dis;
940 }
941
942 //=======================================================================
943 //function : Select
944 //purpose :
945 //=======================================================================
Select(Standard_Integer & theId,Standard_Integer & theX,Standard_Integer & theY,Standard_Integer & theButton,Standard_Boolean theToWait)946 void Draw_Viewer::Select (Standard_Integer& theId,
947 Standard_Integer& theX, Standard_Integer& theY,
948 Standard_Integer& theButton,
949 Standard_Boolean theToWait)
950 {
951 if (Draw_Batch)
952 {
953 return;
954 }
955
956 theId = theX = theY = theButton = 0;
957 Standard_Boolean hasView = Standard_False;
958 for (int aViewIter = 0; aViewIter < MAXVIEW; ++aViewIter)
959 {
960 if (myViews[aViewIter] != NULL
961 && myViews[aViewIter]->IsMapped())
962 {
963 hasView = Standard_True;
964 break;
965 }
966 }
967 if (!hasView)
968 {
969 std::cerr << "No selection is possible with no open views\n";
970 return;
971 }
972 Flush();
973
974 #ifdef _WIN32
975 HANDLE hWnd = NULL;
976
977 theId = MAXVIEW; //:abv 29.05.02: cycle for working in console mode
978 while (theId >= MAXVIEW)
979 {
980 if (theToWait)
981 {
982 Draw_Window::SelectWait (hWnd, theX, theY, theButton);
983 }
984 else
985 {
986 Draw_Window::SelectNoWait (hWnd, theX, theY, theButton);
987 }
988
989 // Recherche du numero de la vue grace au HANDLE
990 for (int aViewIter = 0; aViewIter < MAXVIEW; ++aViewIter)
991 {
992 if (myViews[aViewIter] != NULL
993 && myViews[aViewIter]->IsEqualWindows (hWnd))
994 {
995 theId = aViewIter;
996 }
997 }
998 }
999 theX = theX - myViews[theId]->GetDx();
1000 theY = -theY - myViews[theId]->GetDy();
1001 #elif defined(HAVE_XLIB)
1002 if (!theToWait)
1003 {
1004 if (theId >= 0 && theId < MAXVIEW)
1005 {
1006 if (myViews[theId] != NULL)
1007 {
1008 myViews[theId]->Wait (theToWait);
1009 }
1010 }
1011 }
1012 else
1013 {
1014 for (int aViewIter = 0; aViewIter < MAXVIEW; ++aViewIter)
1015 {
1016 if (myViews[aViewIter] != NULL)
1017 {
1018 myViews[aViewIter]->Wait (theToWait);
1019 }
1020 }
1021 }
1022
1023 Standard_Boolean again = Standard_True;
1024 while (again)
1025 {
1026 Draw_Window::Draw_XEvent ev;
1027 ev.type = 0;
1028 Draw_Window::GetNextEvent (ev);
1029 switch (ev.type)
1030 {
1031 case ButtonPress:
1032 {
1033 Standard_Integer aViewIter = 0;
1034 for (; aViewIter < MAXVIEW; ++aViewIter)
1035 {
1036 if (myViews[aViewIter] != NULL
1037 && myViews[aViewIter]->IsEqualWindows (ev.window))
1038 {
1039 break;
1040 }
1041 }
1042 if (theToWait || theId == aViewIter)
1043 {
1044 if (aViewIter < MAXVIEW)
1045 {
1046 theId = aViewIter;
1047 theX = ev.x;
1048 theY = ev.y;
1049 theButton = ev.button;
1050 }
1051 else
1052 {
1053 theId = -1;
1054 }
1055 again = Standard_False;
1056 }
1057 break;
1058 }
1059 case MotionNotify:
1060 {
1061 if (theToWait)
1062 {
1063 break;
1064 }
1065 theX = ev.x;
1066 theY = ev.y;
1067 theButton = 0;
1068 again = Standard_False;
1069 break;
1070 }
1071 }
1072 }
1073
1074 if (theId != -1)
1075 {
1076 theX = theX - myViews[theId]->GetDx();
1077 theY = -theY - myViews[theId]->GetDy();
1078 }
1079 if (!theToWait)
1080 {
1081 myViews[theId]->Wait (!theToWait);
1082 }
1083 #elif defined(__APPLE__)
1084 theId = MAXVIEW;
1085 while (theId >= MAXVIEW)
1086 {
1087 Standard_Integer aWindowNumber = 0;
1088 Draw_Window::GetNextEvent (theToWait, aWindowNumber, theX, theY, theButton);
1089 if (theY < 0)
1090 {
1091 continue; // mouse clicked on window title
1092 }
1093
1094 for (Standard_Integer aViewIter = 0; aViewIter < MAXVIEW; ++aViewIter)
1095 {
1096 if (myViews[aViewIter] != NULL
1097 && myViews[aViewIter]->IsEqualWindows (aWindowNumber))
1098 {
1099 theId = aViewIter;
1100 }
1101 }
1102 }
1103
1104 theX = theX - myViews[theId]->GetDx();
1105 theY = -theY - myViews[theId]->GetDy();
1106 #else
1107 // not implemented
1108 (void )theToWait;
1109 #endif
1110 }
1111
1112 //=======================================================================
1113 //function : Pick
1114 //purpose :
1115 //=======================================================================
1116
Pick(const Standard_Integer id,const Standard_Integer X,const Standard_Integer Y,const Standard_Integer Prec,Handle (Draw_Drawable3D)& D,const Standard_Integer first) const1117 Standard_Integer Draw_Viewer::Pick(const Standard_Integer id,
1118 const Standard_Integer X, const Standard_Integer Y, const Standard_Integer Prec,
1119 Handle(Draw_Drawable3D)& D,
1120 const Standard_Integer first) const
1121 {
1122 if (Draw_Batch) return 0;
1123 if (myViews[id] == NULL)
1124 return 0;
1125
1126 // is this the only view in its category
1127 Standard_Boolean is2d = myViews[id]->Is2D();
1128 Standard_Integer i,nbviews = 0;
1129 for (i = 0; i < MAXVIEW; i++)
1130 {
1131 if (myViews[i])
1132 if (myViews[i]->Is2D() == is2d)
1133 ++nbviews;
1134 }
1135 Standard_Boolean only = (nbviews == 1);
1136
1137 CurrentMode = PICK;
1138 xpick = X;
1139 ypick = Y;
1140 precpick = Prec;
1141 found = Standard_False;
1142 Standard_Real x1,x2,y1,y2;
1143 for (i = first+1; i <= myDrawables.Length(); i++) {
1144 Standard_Boolean reject = Standard_False;
1145 // rejection if only view
1146 if (only) {
1147 myDrawables(i)->Bounds(x1,x2,y1,y2);
1148 if ((xpick+Prec < x1) || (xpick-Prec > x2) ||
1149 (ypick+Prec < y1) || (ypick-Prec > y2))
1150 reject = Standard_True;
1151 }
1152 if (!reject) {
1153 DrawOnView(id,myDrawables(i));
1154 if (found)
1155 break;
1156 }
1157 }
1158 CurrentMode = DRAW;
1159 found = Standard_False;
1160 if (i <= myDrawables.Length())
1161 D = myDrawables(i);
1162 else
1163 i = 0;
1164 return i;
1165 }
1166
1167 //=======================================================================
1168 //function : LastPick
1169 //purpose :
1170 //=======================================================================
1171
LastPick(gp_Pnt & P1,gp_Pnt & P2,Standard_Real & Param)1172 void Draw_Viewer::LastPick(gp_Pnt& P1, gp_Pnt& P2, Standard_Real& Param)
1173 {
1174 if (Draw_Batch) return;
1175 P1 = lastPickP1;
1176 P2 = lastPickP2;
1177 Param = lastPickParam;
1178 }
1179
1180 //=======================================================================
1181 //function : ~Draw_Viewer
1182 //purpose :
1183 //=======================================================================
1184
~Draw_Viewer()1185 Draw_Viewer::~Draw_Viewer()
1186 {
1187 if (Draw_Batch) return;
1188 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1189 DeleteView(id);
1190 }
1191
1192 //=======================================================================
1193 //function : operator<<
1194 //purpose :
1195 //=======================================================================
1196
operator <<(const Handle (Draw_Drawable3D)& d3d)1197 Draw_Viewer& Draw_Viewer::operator<<(const Handle(Draw_Drawable3D)& d3d)
1198 {
1199 if (Draw_Batch) return *this;
1200 if (!d3d.IsNull()) {
1201 AddDrawable(d3d);
1202 for (Standard_Integer id = 0; id < MAXVIEW; id++)
1203 DrawOnView(id,d3d);
1204 }
1205 return *this;
1206 }
1207
1208 //=======================================================================
1209 //function : GetDrawables
1210 //purpose :
1211 //=======================================================================
GetDrawables()1212 const Draw_SequenceOfDrawable3D& Draw_Viewer::GetDrawables()
1213 {
1214 return myDrawables;
1215 }
1216
1217 // *******************************************************************
1218 // DISPLAY methods
1219 // *******************************************************************
1220
1221
Draw_Flush()1222 void Draw_Flush()
1223 {
1224 if (Draw_Batch) return;
1225 if (highlight) curview->SetColor(highlightcol.ID());
1226 curview->DrawSegments(segm,nbseg);
1227 nbseg = 0;
1228 }
1229
1230 //=======================================================================
1231 //function : SetColor
1232 //purpose :
1233 //=======================================================================
1234
SetColor(const Draw_Color & col) const1235 void Draw_Display::SetColor (const Draw_Color& col) const
1236 {
1237 if (Draw_Batch) return;
1238 if (col.ID() == currentcolor.ID()) return;
1239
1240 currentcolor = col;
1241 switch (CurrentMode) {
1242
1243 case DRAW :
1244 Draw_Flush();
1245 curview->SetColor(col.ID());
1246 break;
1247
1248 case POSTSCRIPT :
1249 (*ps_stream) << "stroke\nnewpath\n";
1250 (*ps_stream) << ps_width[col.ID()]<<" setlinewidth\n";
1251 (*ps_stream) << ps_gray[col.ID()]<<" setgray\n";
1252
1253 case PICK :
1254 break;
1255 }
1256 }
1257
1258 //=======================================================================
1259 //function : SetMode
1260 //purpose :
1261 //=======================================================================
1262
SetMode(const Standard_Integer M) const1263 void Draw_Display::SetMode (const Standard_Integer M) const
1264 {
1265 if (Draw_Batch) return;
1266 switch (CurrentMode) {
1267
1268 case DRAW :
1269 Draw_Flush();
1270 curview->SetMode(M);
1271 break;
1272
1273 case PICK :
1274 case POSTSCRIPT :
1275 break;
1276 }
1277 }
1278
1279 //=======================================================================
1280 //function : Zoom
1281 //purpose :
1282 //=======================================================================
1283
Zoom() const1284 Standard_Real Draw_Display::Zoom() const
1285 {
1286 if (Draw_Batch) return 1.;
1287 return curview->GetZoom();
1288 }
1289
1290 //=======================================================================
1291 //function : Flush
1292 //purpose :
1293 //=======================================================================
1294
Flush() const1295 void Draw_Display::Flush () const
1296 {
1297 if (Draw_Batch) return;
1298 Draw_Flush();
1299 }
1300
1301 //=======================================================================
1302 //function : DrawString
1303 //purpose :
1304 //=======================================================================
1305
DrawString(const gp_Pnt2d & ppt,const Standard_CString S,const Standard_Real moveX,const Standard_Real moveY)1306 void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1307 const Standard_CString S,
1308 const Standard_Real moveX,
1309 const Standard_Real moveY)
1310 {
1311 if (Draw_Batch) return;
1312 if (ppt.X() > 1.e09 || ppt.X() < -1.e09 ) return;
1313 if (ppt.Y() > 1.e09 || ppt.Y() < -1.e09 ) return;
1314
1315 gp_Pnt2d pt(ppt.X()*curview->GetZoom(),ppt.Y()*curview->GetZoom());
1316
1317 if (pt.X() > 1.e09 || pt.X() < -1.e09 ) return;
1318 if (pt.Y() > 1.e09 || pt.Y() < -1.e09 ) return;
1319
1320 switch (CurrentMode) {
1321
1322 case DRAW :
1323 {
1324 int X = (int) ( pt.X() + moveX + curview->GetDx());
1325 int Y = (int) (-pt.Y() + moveY - curview->GetDy());
1326 curview->DrawString(X,Y,(char *)S);
1327 if (Draw_Bounds) {
1328 if (pt.X() + moveX > xmax) xmax = pt.X();
1329 if (pt.X() + moveX < xmin) xmin = pt.X();
1330 if (-pt.Y() - moveY > ymax) ymax = -pt.Y();
1331 if (-pt.Y() - moveY < ymin) ymin = -pt.Y();
1332 }
1333 }
1334 break;
1335
1336 case POSTSCRIPT :
1337 {
1338 Standard_Integer x = (Standard_Integer )( (pt.X() + moveX - ps_vx) * ps_kx + ps_px);
1339 Standard_Integer y = (Standard_Integer )( (pt.Y() + moveY - ps_vy) * ps_ky + ps_py);
1340 (*ps_stream) <<"stroke\n";
1341 (*ps_stream) << x << " " << y << " m\n";
1342 (*ps_stream) <<"("<<S<<") show\nnewpath\n";
1343 }
1344 break;
1345
1346 case PICK :
1347 break;
1348 }
1349 }
1350
1351 //=======================================================================
1352 //function : DrawString
1353 //purpose :
1354 //=======================================================================
1355
DrawString(const gp_Pnt2d & ppt,const Standard_CString S)1356 void Draw_Display::DrawString(const gp_Pnt2d& ppt,
1357 const Standard_CString S)
1358 {
1359 if (Draw_Batch) return;
1360 DrawString(ppt,S,0.0,0.0);
1361 }
1362
1363 //=======================================================================
1364 //function : DrawString
1365 //purpose :
1366 //=======================================================================
1367
DrawString(const gp_Pnt & pt,const Standard_CString S,const Standard_Real moveX,const Standard_Real moveY)1368 void Draw_Display::DrawString(const gp_Pnt& pt,
1369 const Standard_CString S,
1370 const Standard_Real moveX,
1371 const Standard_Real moveY)
1372 {
1373 if (Draw_Batch) return;
1374 DrawString(Project(pt),S,moveX,moveY);
1375 }
1376
1377 //=======================================================================
1378 //function : DrawString
1379 //purpose :
1380 //=======================================================================
1381
DrawString(const gp_Pnt & pt,const Standard_CString S)1382 void Draw_Display::DrawString(const gp_Pnt& pt,
1383 const Standard_CString S)
1384 {
1385 if (Draw_Batch) return;
1386 DrawString(Project(pt),S,0.0,0.0);
1387 }
1388
1389
1390 // *******************************************************************
1391 // Drawing data static variables
1392 // *******************************************************************
1393 static gp_Pnt2d PtCur; // current 2D point
1394 static gp_Pnt PtPers; // current 3D point for Pers
1395
1396 //=======================================================================
1397 //function : Project
1398 //purpose :
1399 //=======================================================================
1400
Project(const gp_Pnt & p,gp_Pnt2d & p2d) const1401 void Draw_Display::Project(const gp_Pnt& p, gp_Pnt2d& p2d) const
1402 {
1403 if (Draw_Batch) return;
1404 gp_Pnt pt = p;
1405 pt.Transform(curview->GetMatrix());
1406 Standard_Real xp,yp,zp;
1407 pt.Coord(xp,yp,zp);
1408 if (curview->IsPerspective()) {
1409 const Standard_Real aDistance = curview->GetFocalDistance();
1410 xp = xp * aDistance / (aDistance-zp);
1411 yp = yp * aDistance / (aDistance-zp);
1412 }
1413 p2d.SetCoord(xp,yp);
1414 }
1415
1416 //=======================================================================
1417 //function : Draw_Display
1418 //purpose :
1419 //=======================================================================
1420
Draw_Display()1421 Draw_Display::Draw_Display ()
1422 {
1423 if (Draw_Batch) return;
1424 if (curview) {
1425 PtPers.SetCoord(0., 0., 0.);
1426 PtPers.Transform(curview->GetMatrix());
1427 PtCur.SetCoord(PtPers.X()*curview->GetZoom(),PtPers.Y()*curview->GetZoom());
1428 }
1429 }
1430
1431 //=======================================================================
1432 //function : MoveTo 2D
1433 //purpose :
1434 //=======================================================================
1435
MoveTo(const gp_Pnt2d & pp)1436 void Draw_Display::MoveTo (const gp_Pnt2d& pp)
1437 {
1438 if (Draw_Batch) return;
1439 const Standard_Real aZoom = curview->GetZoom();
1440 gp_Pnt2d pt(pp.X() * aZoom, pp.Y() * aZoom);
1441 switch (CurrentMode) {
1442
1443 case DRAW :
1444 PtCur = pt;
1445 if (Draw_Bounds) {
1446 if (pt.X() > xmax) xmax = pt.X();
1447 if (pt.X() < xmin) xmin = pt.X();
1448 if (pt.Y() > ymax) ymax = pt.Y();
1449 if (pt.Y() < ymin) ymin = pt.Y();
1450 }
1451 break;
1452
1453 case PICK :
1454 PtCur = pt;
1455 break;
1456
1457 case POSTSCRIPT :
1458 {
1459 Standard_Integer x = (Standard_Integer )( (pt.X() - ps_vx) * ps_kx + ps_px);
1460 Standard_Integer y = (Standard_Integer )( (pt.Y() - ps_vy) * ps_ky + ps_py);
1461 (*ps_stream) <<"stroke\nnewpath\n"<< x << " " << y << " m\n";
1462 }
1463 break;
1464 }
1465 }
1466
1467 //=======================================================================
1468 //function : DrawTo 2D
1469 //purpose :
1470 //=======================================================================
CalculRegion(const Standard_Real x,const Standard_Real y,const Standard_Real x1,const Standard_Real y1,const Standard_Real x2,const Standard_Real y2)1471 inline Standard_Integer CalculRegion(const Standard_Real x,
1472 const Standard_Real y,
1473 const Standard_Real x1,
1474 const Standard_Real y1,
1475 const Standard_Real x2,
1476 const Standard_Real y2) {
1477 Standard_Integer r;
1478 if(x<x1) { r=1; } else { if(x>x2) { r=2; } else { r=0; } }
1479 if(y<y1) { r|=4; } else { if(y>y2) { r|=8; } }
1480 return(r);
1481 }
1482
Trim(gp_Pnt2d & P1,gp_Pnt2d & P2,Standard_Real x0,Standard_Real y0,Standard_Real x1,Standard_Real y1)1483 Standard_Boolean Trim(gp_Pnt2d& P1,gp_Pnt2d& P2,
1484 Standard_Real x0,
1485 Standard_Real y0,
1486 Standard_Real x1,
1487 Standard_Real y1) {
1488 Standard_Real xa=P1.X(),ya=P1.Y(),xb=P2.X(),yb=P2.Y();
1489
1490 Standard_Integer regiona=0,regionb=0;
1491 regiona = CalculRegion(xa,ya,x0,y0,x1,y1);
1492 regionb = CalculRegion(xb,yb,x0,y0,x1,y1);
1493 if((regiona & regionb)==0) {
1494 Standard_Real dx=xb-xa;
1495 Standard_Real dy=yb-ya;
1496 Standard_Real dab=sqrt(dx*dx+dy*dy);
1497 if(dab<1e-10) return(Standard_False);
1498 dx/=dab;
1499 dy/=dab;
1500
1501 Standard_Real xm,ym,mfenx,mfeny;
1502 mfenx=xm=0.5*(x0+x1);
1503 mfeny=ym=0.5*(y0+y1);
1504 x1-=x0; y1-=y0;
1505 Standard_Real d=sqrt(x1*x1+y1*y1) * 2;
1506
1507 Standard_Real p=(xm-xa)*dx+(ym-ya)*dy;
1508 xm=xa+p*dx;
1509 ym=ya+p*dy;
1510 gp_Pnt2d Pm(xm,ym);
1511
1512 gp_Pnt2d MFen(mfenx,mfeny);
1513 if(MFen.SquareDistance(Pm) > d*d) return(Standard_False);
1514
1515 Standard_Real PmDistP1 = Pm.Distance(P1);
1516 Standard_Real PmDistP2 = Pm.Distance(P2);
1517
1518 Standard_Real amab = (xm-xa)*(xb-xa)+(ym-ya)*(yb-ya);
1519
1520 if(amab > 0) { //-- M est compris entre A et B
1521 if(PmDistP1 > d) {
1522 P1.SetCoord(xm-d*dx,ym-d*dy);
1523 }
1524 if(PmDistP2 >d) {
1525 P2.SetCoord(xm+d*dx,ym+d*dy);
1526 }
1527 }
1528 else if(PmDistP1 < PmDistP2) { //-- On a M P1 P2
1529 if(PmDistP2 > d) {
1530 P2.SetCoord(xm+d*dx,ym+d*dy);
1531 }
1532 }
1533 else { //-- On a P1 P2 M
1534 if(PmDistP1 > d) {
1535 P1.SetCoord(xm-d*dx,ym-d*dy);
1536 }
1537 }
1538 return(Standard_True);
1539 }
1540 else return(Standard_False);
1541 }
1542
1543
1544
1545
DrawTo(const gp_Pnt2d & pp2)1546 void Draw_Display::DrawTo (const gp_Pnt2d& pp2)
1547 {
1548 if (Draw_Batch) return;
1549 if (pp2.X() > 1.e09 || pp2.X() < -1.e09 ) return;
1550 if (pp2.Y() > 1.e09 || pp2.Y() < -1.e09 ) return;
1551
1552 gp_Pnt2d p2(pp2.X() * curview->GetZoom(), pp2.Y() * curview->GetZoom());
1553
1554 if (p2.X() > 1.e09 || p2.X() < -1.e09 ) return;
1555 if (p2.Y() > 1.e09 || p2.Y() < -1.e09 ) return;
1556
1557 gp_Pnt2d p1 = PtCur;
1558 if (p1.X() > 1.e09 || p1.X() < -1.e09 ) return;
1559 if (p1.Y() > 1.e09 || p1.Y() < -1.e09 ) return;
1560
1561 PtCur = p2;
1562
1563 switch (CurrentMode) {
1564
1565 case DRAW : {
1566
1567 #if 1
1568 Standard_Integer x0,y0,x1,y1;
1569 curview->GetFrame(x0,y0,x1,y1);
1570
1571
1572 //Standard_Integer qx0,qy0,qx1,qy1;
1573 //curview->viewer->GetFrame(curview->id,qx0,qy0,qx1,qy1);
1574 //if(qx0!=x0 || qx1!=x1 || qy0!=y0 || qy1!=y1) {
1575 // x0=qx0; x1=qx1; y0=qy0; y1=qy1;
1576 //}
1577
1578
1579
1580 gp_Pnt2d PI1(p1);
1581 gp_Pnt2d PI2(p2);
1582
1583 if(Trim(PI1,PI2,x0,y0,x1,y1))
1584 {
1585 segm[nbseg].Init(static_cast<Standard_Integer>( PI1.X() + curview->GetDx()),
1586 static_cast<Standard_Integer>(-PI1.Y() - curview->GetDy()),
1587 static_cast<Standard_Integer>( PI2.X() + curview->GetDx()),
1588 static_cast<Standard_Integer>(-PI2.Y() - curview->GetDy()));
1589 ++nbseg;
1590 }
1591 #else
1592 segm[nbseg].Init(static_cast<Standard_Integer>( p1.X() + curview->GetDx()),
1593 static_cast<Standard_Integer>(-p1.Y() - curview->GetDy()),
1594 static_cast<Standard_Integer>( p2.X() + curview->GetDx()),
1595 static_cast<Standard_Integer>(-p2.Y() - curview->GetDy()));
1596 nbseg++;
1597 #endif
1598 if (nbseg == MAXSEGMENT) {
1599 Draw_Flush();
1600 }
1601 if (Draw_Bounds) {
1602 if (p2.X() > xmax) xmax = p2.X();
1603 if (p2.X() < xmin) xmin = p2.X();
1604 if (p2.Y() > ymax) ymax = p2.Y();
1605 if (p2.Y() < ymin) ymin = p2.Y();
1606 }
1607 }
1608 break;
1609
1610 case PICK :
1611 if (!found) {
1612 Standard_Integer x1 = (int) p1.X() ;
1613 Standard_Integer y1 = (int) p1.Y() ;
1614 Standard_Integer x2 = (int) p2.X() ;
1615 Standard_Integer y2 = (int) p2.Y() ;
1616 if ((x1 >= xpick + precpick) && (x2 >= xpick + precpick)) break;
1617 if ((x1 <= xpick - precpick) && (x2 <= xpick - precpick)) break;
1618 if ((y1 >= ypick + precpick) && (y2 >= ypick + precpick)) break;
1619 if ((y1 <= ypick - precpick) && (y2 <= ypick - precpick)) break;
1620
1621 Standard_Boolean inside = Standard_True;
1622 if ((x1 > xpick + precpick) || (x2 > xpick + precpick)) {
1623 Standard_Real y = (Standard_Real) y1 +
1624 (Standard_Real) (y2-y1) * (Standard_Real) (xpick+precpick-x1) /
1625 (Standard_Real) (x2 - x1);
1626 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1627 found = Standard_True;
1628 lastPickParam = (Standard_Real) (xpick - x1) /
1629 (Standard_Real) (x2 - x1);
1630 break;
1631 }
1632 else
1633 inside = Standard_False;
1634 }
1635
1636 if ((x1 < xpick - precpick) || (x2 < xpick - precpick)) {
1637 Standard_Real y = (Standard_Real) y1 +
1638 (Standard_Real) (y2-y1) * (Standard_Real) (xpick-precpick-x1) /
1639 (Standard_Real) (x2 - x1);
1640 if ( (y < ypick+precpick) && (y > ypick - precpick)) {
1641 found = Standard_True;
1642 lastPickParam = (Standard_Real) (xpick - x1) /
1643 (Standard_Real) (x2 - x1);
1644 break;
1645 }
1646 else
1647 inside = Standard_False;
1648 }
1649
1650
1651 if ((y1 > ypick + precpick) || (y2 > ypick + precpick)) {
1652 Standard_Real x = (Standard_Real) x1 +
1653 (Standard_Real) (x2-x1) * (Standard_Real) (ypick+precpick-y1) /
1654 (Standard_Real) (y2 - y1);
1655 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1656 found = Standard_True;
1657 lastPickParam = (Standard_Real) (ypick - y1) /
1658 (Standard_Real) (y2 - y1);
1659 break;
1660 }
1661 else
1662 inside = Standard_False;
1663 }
1664
1665
1666 if ((y1 < ypick - precpick) || (y2 < ypick - precpick)) {
1667 Standard_Real x = (Standard_Real) x1 +
1668 (Standard_Real) (x2-x1) * (Standard_Real) (ypick-precpick-y1) /
1669 (Standard_Real) (y2 - y1);
1670 if ( (x < xpick+precpick) && (x > xpick - precpick)) {
1671 found = Standard_True;
1672 lastPickParam = (Standard_Real) (ypick - y1) /
1673 (Standard_Real) (y2 - y1);
1674 break;
1675 }
1676 else
1677 inside = Standard_False;
1678 }
1679 found = found || inside;
1680 if (found) {
1681 if (Abs(x2-x1) > Abs(y2-y1)) {
1682 if (Abs(x2-x1) < 1e-5) lastPickParam = 0;
1683 else
1684 lastPickParam = (Standard_Real)(xpick - x1) /
1685 (Standard_Real)(x2 - x1);
1686 }
1687 else {
1688 if (Abs(y2-y1) < 1e-5) lastPickParam = 0;
1689 else
1690 lastPickParam = (Standard_Real)(ypick - y1) /
1691 (Standard_Real)(y2 - y1);
1692 }
1693 }
1694 }
1695 break;
1696
1697 case POSTSCRIPT :
1698 {
1699 Standard_Integer x = (Standard_Integer )( (p2.X() - ps_vx) * ps_kx + ps_px);
1700 Standard_Integer y = (Standard_Integer )( (p2.Y() - ps_vy) * ps_ky + ps_py);
1701 (*ps_stream) << x << " " << y << " l\n";
1702 }
1703 break;
1704 }
1705
1706 }
1707
1708 //=======================================================================
1709 //function : MoveTo
1710 //purpose :
1711 //=======================================================================
1712
MoveTo(const gp_Pnt & pt)1713 void Draw_Display::MoveTo (const gp_Pnt& pt)
1714 {
1715 if (Draw_Batch) return;
1716 if (CurrentMode == PICK) {
1717 if (!found) lastPickP1 = pt;
1718 else return;
1719 }
1720 PtPers = pt;
1721 PtPers.Transform(curview->GetMatrix());
1722 Standard_Real xp = PtPers.X();
1723 Standard_Real yp = PtPers.Y();
1724 if (curview->IsPerspective())
1725 {
1726 Standard_Real ZPers = PtPers.Z();
1727 const Standard_Real aDistance = curview->GetFocalDistance();
1728 if (ZPers < aDistance * precpers)
1729 {
1730 xp=xp * aDistance / (aDistance-ZPers);
1731 yp=yp * aDistance / (aDistance-ZPers);
1732 }
1733 }
1734 MoveTo(gp_Pnt2d(xp,yp));
1735 }
1736
1737 //=======================================================================
1738 //function : DrawTo
1739 //purpose :
1740 //=======================================================================
1741
DrawTo(const gp_Pnt & pt)1742 void Draw_Display::DrawTo (const gp_Pnt& pt)
1743 {
1744 if (Draw_Batch) return;
1745 if ((CurrentMode == PICK) && found) return;
1746
1747 gp_Pnt pt2 = pt.Transformed(curview->GetMatrix());
1748 Standard_Real xp2 = pt2.X();
1749 Standard_Real yp2 = pt2.Y();
1750
1751 if (curview->IsPerspective())
1752 {
1753 const Standard_Real aZoom = curview->GetZoom();
1754 const Standard_Real aDistance = curview->GetFocalDistance();
1755
1756 Standard_Real xp1 = PtPers.X();
1757 Standard_Real yp1 = PtPers.Y();
1758 Standard_Real zp1 = PtPers.Z();
1759 Standard_Real zp2 = pt2.Z();
1760 PtPers = pt2;
1761 if ((zp1 >= aDistance*precpers) && (zp2 >= aDistance*precpers) )
1762 {
1763 return; // segment is not visible in perspective (behind the eye)
1764 }
1765 else if (zp1 >= aDistance*precpers)
1766 {
1767 xp1=xp1+(xp2-xp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1768 yp1=yp1+(yp2-yp1)*(aDistance*precpers-zp1)/(zp2-zp1);
1769 zp1=aDistance*precpers;
1770 xp1=xp1*aDistance/(aDistance-zp1);
1771 yp1=yp1*aDistance/(aDistance-zp1);
1772 MoveTo( gp_Pnt2d(xp1 * aZoom, yp1 * aZoom) );
1773 }
1774 else if (zp2 >= aDistance*precpers)
1775 {
1776 xp2=xp2+(xp1-xp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1777 yp2=yp2+(yp1-yp2)*(aDistance*precpers-zp2)/(zp1-zp2);
1778 zp2=aDistance*precpers;
1779 }
1780 xp2 = xp2 * aDistance / (aDistance - zp2);
1781 yp2 = yp2 * aDistance / (aDistance - zp2);
1782 }
1783 DrawTo(gp_Pnt2d(xp2,yp2));
1784 if (CurrentMode == PICK) {
1785 if (!found) lastPickP1 = pt;
1786 else lastPickP2 = pt;
1787 }
1788 }
1789
1790 //=======================================================================
1791 //function : Draw
1792 //purpose :
1793 //=======================================================================
1794
Draw(const gp_Pnt & p1,const gp_Pnt & p2)1795 void Draw_Display::Draw (const gp_Pnt& p1, const gp_Pnt& p2)
1796 {
1797 if (Draw_Batch) return;
1798 MoveTo(p1);
1799 DrawTo(p2);
1800 }
1801
1802 //=======================================================================
1803 //function : Draw
1804 //purpose :
1805 //=======================================================================
1806
Draw(const gp_Pnt2d & p1,const gp_Pnt2d & p2)1807 void Draw_Display::Draw(const gp_Pnt2d& p1, const gp_Pnt2d& p2)
1808 {
1809 if (Draw_Batch) return;
1810 MoveTo(p1);
1811 DrawTo(p2);
1812 }
1813
1814
1815 //=======================================================================
1816 //function : ViewId
1817 //purpose :
1818 //=======================================================================
1819
ViewId() const1820 Standard_Integer Draw_Display::ViewId() const
1821 {
1822 if (Draw_Batch) return 0;
1823 return curviewId;
1824 }
1825
1826
1827 //=======================================================================
1828 //function : HasPicked
1829 //purpose :
1830 //=======================================================================
1831
HasPicked() const1832 Standard_Boolean Draw_Display::HasPicked() const
1833 {
1834 if (Draw_Batch) return Standard_False;
1835 return found;
1836 }
1837
1838