983de89b3c3a7403d9a596d33925e64dea809511
[occt.git] / src / Draw / Draw_GraphicCommands.cxx
1 // Created on: 1995-02-23
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1995-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 // **************************************************************
18
19
20 // Modif : DFO 05/11/96
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <Draw.ixx>
26 #include <Draw_Appli.hxx>
27
28 #include <Draw_Drawable3D.hxx>
29 #include <Draw_Grid.hxx>
30 #include <Draw_Display.hxx>
31 #include <Draw_Text3D.hxx>
32 #include <Draw_Text2D.hxx>
33
34 #include <Standard_Stream.hxx>
35
36 #include <stdio.h>
37 #ifdef WNT
38 extern Draw_Viewer dout;
39 extern Standard_Boolean Draw_Batch;
40 #endif
41 #ifdef HAVE_STRINGS_H
42 # include <strings.h>
43 #endif
44
45 extern Standard_Boolean Draw_BlackBackGround;
46
47
48 #define DEFROTATE (5 * M_PI/ 180.)
49 #define DEFMAGNIFY 1.1
50 #define DEFPANNING 0.1
51 #define DEFFOCAL 1.1
52 #define DEFFRAME 10
53 #define DEFGRIDSTEP 100.0
54 static Standard_Real steprot = DEFROTATE;
55 static Standard_Real steppan = DEFPANNING;
56 static Standard_Real stepmagnify = DEFMAGNIFY;
57 static Standard_Real stepfocal = DEFFOCAL;
58 static Standard_Real frame = DEFFRAME;
59 static Standard_Real DefaultGridStep = DEFGRIDSTEP ;
60
61 #define FONTLENGTH
62 static char Draw_fontname[FONTLENGTH]="Helvetica";
63 static char Draw_fontsize[FONTLENGTH]="150";
64 static char Draw_fontnamedefault[FONTLENGTH]="Helvetica";
65 static char Draw_fontsizedefault[FONTLENGTH]="150";
66
67 // *******************************************************************
68 // Graphic commands
69 // *******************************************************************
70
71 static Standard_Integer ViewId(const Standard_CString a)
72 {
73   Standard_Integer id = Draw::Atoi(a);
74   if ((id < 0) || (id >= MAXVIEW)) {
75     cout << "Incorrect view-id, must be in 0.."<<MAXVIEW-1<<endl;
76     return -1;
77   }
78   if (!dout.HasView(id)) {
79     cout <<"View "<<id<<" does not exist."<<endl;
80     return -1;
81   }
82   return id;
83 }
84
85 static void SetTitle(const Standard_Integer id)
86 {
87   if (dout.HasView(id)) {
88     char title[255];
89     Sprintf(title,"%d : %s - Zoom %f",id,dout.GetType(id),dout.Zoom(id));
90     dout.SetTitle(id,title);
91   }
92 }
93
94 //=======================================================================
95 //function : zoom
96 //purpose  :
97 //=======================================================================
98
99 static Standard_Integer zoom(Draw_Interpretor& , Standard_Integer n, const char** a)
100 {
101   // one argument -> All Views
102   // two argument -> First is the view
103   Standard_Boolean z2d = !strcasecmp(a[0],"2dzoom");
104   if (n == 2) {
105     Standard_Real z = Draw::Atof(a[1]);
106     for (Standard_Integer id = 0; id < MAXVIEW; id++) {
107       if (dout.HasView(id)) {
108         if ((z2d && !dout.Is3D(id)) || (!z2d && dout.Is3D(id))) {
109           dout.SetZoom(id,z);
110           SetTitle(id);
111           dout.RepaintView(id);
112         }
113       }
114     }
115     return 0;
116   }
117   else if (n >= 3) {
118     Standard_Integer id = ViewId(a[1]);
119     if (id < 0) return 1;
120     Standard_Real z = Draw::Atof(a[2]);
121     dout.SetZoom(id,z);
122     dout.RepaintView(id);
123     SetTitle(id);
124     return 0;
125   }
126   else
127     return 1;
128 }
129
130 //=======================================================================
131 //function : wzoom
132 //purpose  :
133 //=======================================================================
134
135 static Standard_Integer wzoom(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
136 {
137   Standard_Integer id,X,Y,W,H,X1,Y1,X2 = 0,Y2 = 0,b;
138   Standard_Real dX1,dY1,dX2,dY2,zx,zy;
139   if(argc != 1 && argc != 6)
140   {
141     di<<"Usage : " << argv[0] << " [view-id X1 Y1 X2 Y2]\n";
142     return 1;
143   }
144   if(argc == 1)
145   {
146     di << "Pick first corner"<<"\n";
147     dout.Select(id,X1,Y1,b);
148
149     gp_Trsf T;
150     gp_Pnt P0(0,0,0);
151     dout.GetTrsf(id,T);
152     T.Invert();
153     P0.Transform(T);
154     Standard_Real z = dout.Zoom(id);
155
156     dX1=X1;       dY1=Y1;
157     dX1-=P0.X();  dY1-=P0.Y();
158     dX1/=z;       dY1/=z;
159
160     if (b != 1) return 0;
161     if (id < 0) return 0;
162     Draw_Display d = dout.MakeDisplay(id);
163     d.SetColor(Draw_blanc);
164     d.SetMode(10);
165     Standard_Real dOX2 = dX1;
166     Standard_Real dOY2 = dY1;
167     d.Draw(gp_Pnt2d(dX1,dY1),gp_Pnt2d(dX1,dOY2));
168     d.Draw(gp_Pnt2d(dX1,dOY2),gp_Pnt2d(dOX2,dOY2));
169     d.Draw(gp_Pnt2d(dOX2,dOY2),gp_Pnt2d(dOX2,dY1));
170     d.Draw(gp_Pnt2d(dOX2,dY1),gp_Pnt2d(dX1,dY1));
171     d.Flush();
172     dout.GetPosSize(id,X,Y,W,H);
173     di << "Pick second corner"<<"\n";
174     b = 0;
175     while (b == 0) {
176       dout.Select(id,X2,Y2,b,Standard_False);
177       dX2=X2;          dY2=Y2;
178       dX2-=P0.X();     dY2-=P0.Y();
179       dX2/=z;          dY2/=z;
180
181       d.Draw(gp_Pnt2d(dX1,dY1),gp_Pnt2d(dX1,dOY2));
182       d.Draw(gp_Pnt2d(dX1,dOY2),gp_Pnt2d(dOX2,dOY2));
183       d.Draw(gp_Pnt2d(dOX2,dOY2),gp_Pnt2d(dOX2,dY1));
184       d.Draw(gp_Pnt2d(dOX2,dY1),gp_Pnt2d(dX1,dY1));
185       d.Draw(gp_Pnt2d(dX1,dY1),gp_Pnt2d(dX1,dY2));
186       d.Draw(gp_Pnt2d(dX1,dY2),gp_Pnt2d(dX2,dY2));
187       d.Draw(gp_Pnt2d(dX2,dY2),gp_Pnt2d(dX2,dY1));
188       d.Draw(gp_Pnt2d(dX2,dY1),gp_Pnt2d(dX1,dY1));
189       d.Flush();
190       dOX2 = dX2;
191       dOY2 = dY2;
192     }
193     d.Draw(gp_Pnt2d(dX1,dY1),gp_Pnt2d(dX1,dOY2));
194     d.Draw(gp_Pnt2d(dX1,dOY2),gp_Pnt2d(dOX2,dOY2));
195     d.Draw(gp_Pnt2d(dOX2,dOY2),gp_Pnt2d(dOX2,dY1));
196     d.Draw(gp_Pnt2d(dOX2,dY1),gp_Pnt2d(dX1,dY1));
197     d.Flush();
198     if (b != 1) return 0;
199     d.SetMode(0);
200   }
201   else
202   {
203     id = atoi(argv[1]); 
204     if ((id < 0) || (id >= MAXVIEW)) 
205     {
206       cout << "Incorrect view-id, must be in 0.."<<MAXVIEW-1<<endl;
207       return 1;
208     }
209     if (!dout.HasView(id))
210     {
211       cout <<"View "<<id<<" does not exist."<<endl;
212       return 1;
213     }
214     X1 = atoi (argv [2]);
215     Y1 = atoi (argv [3]);
216     X2 = atoi (argv [4]);
217     Y2 = atoi (argv [5]);
218
219     dout.GetPosSize(id,X,Y,W,H);
220   }
221
222   if ((X1 == X2) || (Y1 == Y2)) return 0;
223   zx = (Standard_Real) Abs(X2-X1) / (Standard_Real) W;
224   zy = (Standard_Real) Abs(Y2-Y1) / (Standard_Real) H;
225   if (zy > zx) zx = zy;
226   zx = 1/zx;
227   if (X2 < X1) X1 = X2;
228   if (Y2 > Y1) Y1 = Y2;
229   X1 = (Standard_Integer ) (X1*zx);
230   Y1 = (Standard_Integer ) (Y1*zx);
231   dout.SetZoom(id,zx*dout.Zoom(id));
232   dout.SetPan(id,-X1,-Y1);
233   dout.RepaintView(id);
234   SetTitle(id);
235   return 0;
236 }
237
238 //=======================================================================
239 //function : wclick
240 //purpose  :
241 //=======================================================================
242
243 static Standard_Integer wclick(Draw_Interpretor& di, Standard_Integer, const char**)
244 {
245   Standard_Integer id1,X1,Y1,b;
246   dout.Flush();
247   di << "Just click."<<"\n";
248   dout.Select(id1,X1,Y1,b);
249   return 0;
250 }
251
252 //=======================================================================
253 //function : view
254 //purpose  :
255 //=======================================================================
256
257 static Standard_Integer view(Draw_Interpretor& di, Standard_Integer n, const char** a)
258 {
259   if (Draw_Batch) return 1;
260
261   if ((n >= 3) && (n != 4)) {
262     Standard_Integer id = Draw::Atoi(a[1]);
263     if ((id < 0) || (id >= MAXVIEW)) {
264       di <<"View-id must be in 0.."<<MAXVIEW-1<<"\n";
265       return 1;
266     }
267     Standard_Integer X = 0;
268     Standard_Integer Y = 0;
269     Standard_Integer W = 500;
270     Standard_Integer H = 500;
271     // if view exist, get old values
272     if (dout.HasView(id))
273       dout.GetPosSize(id,X,Y,W,H);
274     if (n >= 4)
275       X = Draw::Atoi(a[3]);
276     if (n >= 5)
277       Y = Draw::Atoi(a[4]);
278     if (n >= 6)
279       W = Draw::Atoi(a[5]);
280     if (n >= 7)
281       H = Draw::Atoi(a[6]);
282     dout.MakeView(id,a[2],X,Y,W,H);
283     if (!dout.HasView(id)) {
284       di << "View creation failed"<<"\n";
285       return 1;
286     }
287     SetTitle(id);
288     dout.DisplayView(id);
289     return 0;
290   }
291   else if (n == 4) {
292     // create a view on a given window
293     Standard_Integer id = Draw::Atoi(a[1]);
294     if ((id < 0) || (id >= MAXVIEW)) {
295       di <<"View-id must be in 0.."<<MAXVIEW-1<<"\n";
296       return 1;
297     }
298     dout.MakeView(id,a[2],a[3]);
299     if (!dout.HasView(id)) {
300       di << "View creation failed"<<"\n";
301       return 1;
302     }
303     SetTitle(id);
304     dout.DisplayView(id);
305     return 0;
306   }
307   else
308     return 1;
309 }
310
311 //=======================================================================
312 //function : delview
313 //purpose  :
314 //=======================================================================
315
316 static Standard_Integer delview(Draw_Interpretor& , Standard_Integer n, const char** a)
317 {
318   if (n == 1) {
319     for (Standard_Integer id = 0; id < MAXVIEW; id++)
320       dout.DeleteView(id);
321     return 0;
322   }
323   else if (n >= 2) {
324     Standard_Integer id = ViewId(a[1]);
325     if (id < 0) return 1;
326     dout.DeleteView(id);
327     return 0;
328   }
329   else
330     return 1;
331 }
332
333 //=======================================================================
334 //function : fit
335 //purpose  :
336 //=======================================================================
337
338 static Standard_Integer fit(Draw_Interpretor& , Standard_Integer n, const char** a)
339 {
340   Standard_Boolean f2d = !strcasecmp(a[0],"2dfit");
341   if (n == 1) {
342     Standard_Real zoom = RealLast();
343     Standard_Integer id;
344     for ( id = 0; id < MAXVIEW; id++) {
345       if (dout.HasView(id)) {
346         if ((f2d && !dout.Is3D(id)) || (!f2d && dout.Is3D(id))) {
347 //        dout.FitView(id,frame);
348           dout.FitView(id,(Standard_Integer ) frame);
349           if (dout.Zoom(id) < zoom) zoom = dout.Zoom(id);
350         }
351       }
352     }
353     for (id = 0; id < MAXVIEW; id++) {
354       if (dout.HasView(id)) {
355         if ((f2d && !dout.Is3D(id)) || (!f2d && dout.Is3D(id))) {
356           dout.SetZoom(id,zoom);
357           dout.RepaintView(id);
358           SetTitle(id);
359         }
360       }
361     }
362     return 0;
363   }
364   else if (n >= 2) {
365     Standard_Integer id = ViewId(a[1]);
366     if (id < 0) return 1;
367 //    dout.FitView(id,frame);
368     dout.FitView(id,(Standard_Integer ) frame);
369     dout.RepaintView(id);
370     SetTitle(id);
371     return 0;
372   }
373   else
374     return 1;
375 }
376
377 //=======================================================================
378 //function : focal
379 //purpose  :
380 //=======================================================================
381
382 static Standard_Integer focal(Draw_Interpretor& , Standard_Integer n, const char** a)
383 {
384   Standard_Integer start = 0;
385   Standard_Integer end = MAXVIEW-1;
386   if (n >= 2) {
387     Standard_Integer anid = ViewId(a[1]);
388     if (anid < 0) return 1;
389     start = end = anid;
390   }
391   Standard_Real df = 1.;
392   if (!strcasecmp(a[0],"fu"))
393     df = stepfocal;
394   if (!strcasecmp(a[0],"fd"))
395     df = 1./stepfocal;
396
397   for (Standard_Integer id = start; id <= end; id++) {
398     if (!strcasecmp(dout.GetType(id),"PERS")) {
399       dout.SetFocal(id,dout.Focal(id) * df);
400       dout.RepaintView(id);
401     }
402   }
403   return 0;
404 }
405
406 //=======================================================================
407 //function : setfocal
408 //purpose  :
409 //=======================================================================
410
411 static Standard_Integer setfocal(Draw_Interpretor& di, Standard_Integer n, const char** a)
412 {
413   if (n == 1) {
414     for (Standard_Integer id = 0; id < MAXVIEW; id++) {
415       if (!strcasecmp(dout.GetType(id),"PERS"))
416         di << "Focal view "<<id<<" is "<<dout.Focal(id)<<"\n";
417     }
418   }
419   else {
420     Standard_Real f = Draw::Atof(a[1]);
421     for (Standard_Integer id = 0; id < MAXVIEW; id++) {
422       if (!strcasecmp(dout.GetType(id),"PERS"))
423         dout.SetFocal(id,f);
424     }
425     dout.RepaintAll();
426   }
427   return 0;
428 }
429
430 //=======================================================================
431 //function : magnify
432 //purpose  :
433 //=======================================================================
434
435 //static Standard_Integer magnify(Draw_Interpretor& di, Standard_Integer n, const char** a)
436 static Standard_Integer magnify(Draw_Interpretor& , Standard_Integer n, const char** a)
437 {
438   Standard_Integer start = 0;
439   Standard_Integer end = MAXVIEW-1;
440   if (n >= 2) {
441     Standard_Integer anid = ViewId(a[1]);
442     if (anid < 0) return 1;
443     start = end = anid;
444   }
445   Standard_Boolean v2d = (a[0][0] == '2');   // 2dmu, 2dmd
446   const char* com = a[0];
447   if (v2d) com += 2;
448   Standard_Real dz = 1.;
449   if (!strcasecmp(com,"mu"))      // mu, 2dmu
450     dz = stepmagnify;
451   else                            // md, 2dmd
452     dz = 1/stepmagnify;
453
454   for (Standard_Integer id = start; id <= end; id++) {
455     if (dout.HasView(id)) {
456       if ((v2d && !dout.Is3D(id)) || (!v2d && dout.Is3D(id))) {
457         dout.SetZoom(id,dout.Zoom(id) * dz);
458         SetTitle(id);
459         dout.RepaintView(id);
460       }
461     }
462   }
463   return 0;
464 }
465
466 Standard_EXPORT Standard_Integer Draw_magnify(Draw_Interpretor& di, Standard_Integer n, const char** a)
467 {
468   return magnify(di,n,a);
469 }
470
471 //=======================================================================
472 //function : rotate
473 //purpose  :
474 //=======================================================================
475
476 static Standard_Integer rotate(Draw_Interpretor& , Standard_Integer n, const char** a)
477 {
478   Standard_Integer start = 0;
479   Standard_Integer end = MAXVIEW-1;
480   if (n >= 2) {
481     Standard_Integer anid = ViewId(a[1]);
482     if (anid < 0) return 1;
483     start = end = anid;
484   }
485
486   gp_Dir2d D;
487   Standard_Real ang=0;
488   if (!strcasecmp(a[0],"u")) {
489     D.SetCoord(1.,0.);
490     ang = -steprot;
491   }
492   if (!strcasecmp(a[0],"d")) {
493     D.SetCoord(1.,0.);
494     ang = steprot;
495   }
496   if (!strcasecmp(a[0],"l")) {
497     D.SetCoord(0.,1.);
498     ang = -steprot;
499   }
500   if (!strcasecmp(a[0],"r")) {
501     D.SetCoord(0.,1.);
502     ang = steprot;
503   }
504
505   for (Standard_Integer id = start; id <= end; id++) {
506     if ((!strcasecmp(dout.GetType(id),"AXON")) ||
507         (!strcasecmp(dout.GetType(id),"PERS"))) {
508       dout.RotateView(id,D,ang);
509       dout.RepaintView(id);
510     }
511   }
512   return 0;
513 }
514
515 //=======================================================================
516 //function : panning
517 //purpose  :
518 //=======================================================================
519
520 static Standard_Integer panning(Draw_Interpretor& , Standard_Integer n, const char** a)
521 {
522   Standard_Integer start = 0;
523   Standard_Integer end = MAXVIEW-1;
524   if (n >= 2) {
525     Standard_Integer anid = ViewId(a[1]);
526     if (anid < 0) return 1;
527     start = end = anid;
528   }
529   Standard_Integer DX = 0;
530   Standard_Integer DY = 0;
531   Standard_Integer X,Y,W,H;
532
533   Standard_Boolean v2d = (a[0][0] == '2');     // pu2d, pd2d, pr2d, pl2d
534   const char* com = a[0];
535   if (v2d) com += 2;
536
537   if (!strcasecmp(com,"pu"))    // pu , 2dpu
538     DY = 1;
539   if (!strcasecmp(com,"pd"))    // pd , 2dpd
540     DY = -1;
541   if (!strcasecmp(com,"pl"))    // pl , 2dpl
542     DX = -1;
543   if (!strcasecmp(com,"pr"))    // pr , 2dpr
544     DX = 1;
545
546   for (Standard_Integer id = start; id <= end; id++) {
547     if (dout.HasView(id)) {
548       if ((v2d && !dout.Is3D(id)) || (!v2d && dout.Is3D(id))) {
549         dout.GetPosSize(id,X,Y,W,H);
550 //      dout.PanView(id,W * DX * steppan, H * DY * steppan);
551         dout.PanView(id,(Standard_Integer )( W * DX * steppan),(Standard_Integer )( H * DY * steppan));
552         dout.RepaintView(id);
553       }
554     }
555   }
556   return 0;
557 }
558
559 //=======================================================================
560 //function : ptv
561 //purpose  :
562 //=======================================================================
563
564 static Standard_Integer ptv(Draw_Interpretor& , Standard_Integer n, const char** a)
565 {
566   Standard_Real X,Y,Z;
567   Standard_Integer start = 0;
568   Standard_Integer end = MAXVIEW-1;
569   if (n < 4) return 1;
570   if (n >= 5) {
571     Standard_Integer anid = ViewId(a[1]);
572     if (anid < 0) return 1;
573     start = end = anid;
574     X = Draw::Atof(a[2]);
575     Y = Draw::Atof(a[3]);
576     Z = Draw::Atof(a[4]);
577   }
578   else {
579     X = Draw::Atof(a[1]);
580     Y = Draw::Atof(a[2]);
581     Z = Draw::Atof(a[3]);
582   }
583
584   for (Standard_Integer id = start; id <= end; id++) {
585     gp_Trsf T;
586     dout.GetTrsf(id,T);
587     T.SetTranslationPart(gp_Vec(0,0,0));
588     gp_Trsf T1;
589     T1.SetTranslationPart(gp_Vec(-X,-Y,-Z));
590     gp_Trsf aLocalTrsf(T*T1);
591     dout.SetTrsf(id,aLocalTrsf);
592 //    dout.SetTrsf(id,T*T1);
593     dout.RepaintView(id);
594   }
595   return 0;
596 }
597
598 //=======================================================================
599 //function : dptv
600 //purpose  :
601 //=======================================================================
602
603 static Standard_Integer dptv(Draw_Interpretor& , Standard_Integer n, const char** a)
604 {
605   Standard_Real DX,DY,DZ;
606   Standard_Integer start = 0;
607   Standard_Integer end = MAXVIEW-1;
608   if (n < 4) return 1;
609   if (n >= 5) {
610     Standard_Integer anid = ViewId(a[1]);
611     if (anid < 0) return 1;
612     start = end = anid;
613     DX = Draw::Atof(a[2]);
614     DY = Draw::Atof(a[3]);
615     DZ = Draw::Atof(a[4]);
616   }
617   else {
618     DX = Draw::Atof(a[1]);
619     DY = Draw::Atof(a[2]);
620     DZ = Draw::Atof(a[3]);
621   }
622
623   for (Standard_Integer id = start; id <= end; id++) {
624     gp_Trsf T;
625     dout.GetTrsf(id,T);
626     gp_Trsf T1;
627     T1.SetTranslationPart(gp_Vec(-DX,-DY,-DZ));
628     gp_Trsf M = T*T1;
629     dout.SetTrsf(id,M);
630     dout.RepaintView(id);
631   }
632   return 0;
633 }
634
635
636 //=======================================================================
637 //function : color
638 //purpose  :
639 //=======================================================================
640
641 static Standard_Integer color(Draw_Interpretor& di, Standard_Integer n, const char** a)
642 {
643   if (n < 3) {
644     Draw_BlackBackGround = !Draw_BlackBackGround;
645   }
646   else if (!dout.DefineColor(Draw::Atoi(a[1]),a[2])) {
647     di << "Could not allocate color "<<a[2]<<"\n";
648     return 1;
649   }
650   return 0;
651 }
652
653
654
655 //=======================================================================
656 //function : hardcopy
657 //purpose  : hardcopy                  --> hardcopy of view 1
658 //                                                  in file a4.ps
659 //                                                  in format a4
660 //           hardcopy name view        --> hardcopy of view <view>
661 //                                                  in file <name>
662 //                                                  in format a4
663 //           hardcopy name view format --> hardcopy of view <view>
664 //                                                  in file <name>
665 //                                                  in format <a4,a3,a2,a1,a0>
666 //=======================================================================
667
668 static Standard_Integer hardcopy(Draw_Interpretor& ,
669                                  Standard_Integer n, const char** a)
670 {
671   // Inch = 25.40001969 mm.
672   // 28.4 pixels / mm.
673   // format par default papier a4 210 297 mm avec marge de 3 mm.
674
675   Standard_Real rap = 28.4;
676   Standard_Real cad = 3;
677   Standard_Real dx  = 210;
678   Standard_Real dy  = 210 * Sqrt(2.);
679
680   Standard_Integer iview = 1;
681   const char* file = "a4.ps";
682   if (n >= 2) {
683     file = a[1];
684     if (n >= 3) {
685       iview = ViewId(a[2]);
686       if (iview < 0) return 1;
687       if (n >= 4) {
688         if      (!strcmp(a[3],"a7")) {
689           cad = cad / (2 * Sqrt(2));
690           dx  = dx  / (2 * Sqrt(2));
691           dy  = dy  / (2 * Sqrt(2));
692         }
693         else if (!strcmp(a[3],"a6")) {
694           cad = cad / 2;
695           dx  = dx  / 2;
696           dy  = dy  / 2;
697         }
698         else if (!strcmp(a[3],"a5")) {
699           cad = cad / Sqrt(2);
700           dx  = dx  / Sqrt(2);
701           dy  = dy  / Sqrt(2);
702         }
703         else if (!strcmp(a[3],"a4")) {
704           // Do nothing
705           //cad == cad;
706           //dx  == dx;
707           //dy  == dy;
708         }
709         else if (!strcmp(a[3],"a3")) {
710           cad = cad * Sqrt(2);
711           dx  = dx  * Sqrt(2);
712           dy  = dy  * Sqrt(2);
713         }
714         else if (!strcmp(a[3],"a2")) {
715           cad = cad * 2;
716           dx  = dx  * 2;
717           dy  = dy  * 2;
718         }
719         else if (!strcmp(a[3],"a1")) {
720           cad = cad * 2 * Sqrt(2);
721           dx  = dx  * 2 * Sqrt(2);
722           dy  = dy  * 2 * Sqrt(2);
723         }
724         else if (!strcmp(a[3],"a0")) {
725           cad = cad * 4;
726           dx  = dx  * 4;
727           dy  = dy  * 4;
728         }
729       }
730     }
731   }
732
733   Standard_Integer pxmin = (Standard_Integer)(cad * rap);
734   Standard_Integer pymin = (Standard_Integer)(cad * rap);
735   Standard_Integer pxmax = (Standard_Integer)((dx - cad) * rap);
736   Standard_Integer pymax = (Standard_Integer)((dy - cad) * rap);
737
738   ofstream os(file);
739
740   Standard_Integer vxmin,vymin,vxmax,vymax;
741   if (dout.HasView(iview)) {
742     dout.GetFrame(iview,vxmin,vymin,vxmax,vymax);
743     Standard_Real kx = (Standard_Real) (pxmax - pxmin) / (vxmax - vxmin);
744     Standard_Real ky = (Standard_Real) (pymax - pymin) / (vymax - vymin);
745     Standard_Real k = Min(Abs(kx),Abs(ky));
746     kx = (kx > 0) ? k : -k;
747     ky = (ky > 0) ? k : -k;
748     pxmax = (Standard_Integer )( pxmin + kx * (vxmax - vxmin));
749     pymax = (Standard_Integer )( pymin + ky * (vymax - vymin));
750
751     // si on veut choisir l'orientation : 90 rotate
752
753     // ecriture du header
754
755     os << "%!PS-Adobe-3.0 EPSF-3.0\n";
756     os << "%%BoundingBox: " << pxmin << " " << pymin << " "
757       << pxmax << " " << pymax << "\n";
758     os << "%%Pages: 1\n";
759     os << "%%DocumentFonts: "<<Draw_fontname<<"\n";
760     os << "%%EndComments\n";
761
762     os << "/"<<Draw_fontname<<" findfont\n"<<Draw_fontsize<<" scalefont\nsetfont\n";
763     os << "/m {moveto} bind def\n";
764     os << "/l {lineto} bind def\n";
765     os <<".1 .1 scale\n";
766
767     // draw the frame
768
769     os <<"3 setlinewidth\n0 setgray\nnewpath\n";
770     os << pxmin << " " << pymin << " m\n";
771     os << pxmax << " " << pymin << " l\n";
772     os << pxmax << " " << pymax << " l\n";
773     os << pxmin << " " << pymax << " l\n";
774     os << "closepath\nstroke\n";
775
776     // frame the view
777
778     os <<"newpath\n";
779     os << pxmin << " " << pymin << " m\n";
780     os << pxmax << " " << pymin << " l\n";
781     os << pxmax << " " << pymax << " l\n";
782     os << pxmin << " " << pymax << " l\n";
783     os << "closepath\nclip\n";
784
785     dout.PostScriptView(iview,
786                         vxmin,vymin,vxmax,vymax,
787                         pxmin,pymin,pxmax,pymax,os);
788     os <<"showpage\n";
789     os <<"%%EOF\n";
790   }
791
792   return 0;
793 }
794
795 static Standard_Integer dfont(Draw_Interpretor& di,
796                               Standard_Integer n, const char** a)
797 {
798   if        ( n == 1 ) {
799     strcpy(Draw_fontname, Draw_fontnamedefault);
800     strcpy(Draw_fontsize, Draw_fontsizedefault);
801   } else if ( n == 2 ) {
802     strcpy(Draw_fontname, a[1]);
803   } else if ( n == 3 ) {
804     strcpy(Draw_fontname, a[1]);
805     strcpy(Draw_fontsize, a[2]);
806   }
807   di<<Draw_fontname<<" "<<Draw_fontsize<<"\n";
808   return 0;
809 } // dfont
810
811 //=======================================================================
812 //function : hcolor
813 //purpose  :
814 //=======================================================================
815
816 static Standard_Integer hcolor(Draw_Interpretor& di, Standard_Integer n, const char** a)
817 {
818   if (n < 4) {
819     di << "code de couleur (Draw.cxx) : " << "\n" ;
820     di << "0 = White,\t 1 = Red,\t 2 = Green,\t 3 = Blue" << "\n" ;
821     di << "4 = Cyan,\t 5 = Gold,\t 6 = Magenta,\t 7 = Maroon"  << "\n" ;
822     di << "8 = Orange,\t 9 = Pink,\t 10 = Salmon,\t 11 = Violet" << "\n" ;
823     di << "12 = Yellow,\t 13 = Khaki,\t 14 = Coral" << "\n" ;
824     di << "1 <= width <= 11,  0 (noir)  <= gray <= 1 (blanc)" << "\n" ;
825   } else {
826     dout.PostColor(Draw::Atoi(a[1]),Draw::Atoi(a[2]),Draw::Atof(a[3]));
827   }
828   return 0;
829 }
830
831 //=======================================================================
832 //function : xwd
833 //purpose  : xwd file from a view
834 //=======================================================================
835
836 extern void Draw_RepaintNowIfNecessary();
837
838 static Standard_Integer xwd(Draw_Interpretor& , Standard_Integer n, const char** a)
839 {
840   if (n < 2) return 1;
841
842   // enforce repaint if necessary
843   Draw_RepaintNowIfNecessary();
844
845   Standard_Integer id = 1;
846   const char* file = a[1];
847   if (n > 2) {
848     id  = Draw::Atoi(a[1]);
849     file = a[2];
850   }
851   if (!dout.SaveView(id,file))
852     return 1;
853
854   return 0;
855 }
856
857 //=======================================================================
858 //function : grid
859 //purpose  : Creation/Suppression d'une grille.
860 //=======================================================================
861
862 static Standard_Integer grid (Draw_Interpretor& , Standard_Integer NbArg, const char **Arg)
863 {
864   Standard_Real StepX, StepY, StepZ ;
865
866   switch (NbArg) {
867     case 1 :
868       StepX = DefaultGridStep ;
869       StepY = DefaultGridStep ;
870       StepZ = DefaultGridStep ;
871       break ;
872     case 2 :
873       StepX = Abs (Draw::Atof (Arg[1])) ;
874       StepY = Abs (Draw::Atof (Arg[1])) ;
875       StepZ = Abs (Draw::Atof (Arg[1])) ;
876       break ;
877     case 3 :
878       StepX = Abs (Draw::Atof (Arg[1])) ;
879       StepY = Abs (Draw::Atof (Arg[2])) ;
880       StepZ = Abs (Draw::Atof (Arg[2])) ;
881       break ;
882     case 4 :
883       StepX = Abs (Draw::Atof (Arg[1])) ;
884       StepY = Abs (Draw::Atof (Arg[2])) ;
885       StepZ = Abs (Draw::Atof (Arg[3])) ;
886       break ;
887     default :
888       return 1 ;
889   }
890
891 #ifdef HPUX
892   const char *temp = "grid";
893 #else
894   char temp1[] = "grid";
895   const char *temp = temp1;
896 #endif
897   Handle (Draw_Grid) Grille = Handle(Draw_Grid)::DownCast (Draw::Get(temp)) ;
898
899   Grille->Steps (StepX, StepY, StepZ) ;
900   dout.RepaintAll () ;
901
902   return 0 ;
903 }
904
905 //=======================================================================
906 //function : dflush
907 //purpose  :
908 //=======================================================================
909
910 static Standard_Integer dflush (Draw_Interpretor& , Standard_Integer, const char **)
911 {
912   dout.Flush();
913   return 0;
914 }
915
916 //=======================================================================
917 //function : dtext
918 //purpose  :
919 //=======================================================================
920
921 static Standard_Integer dtext(Draw_Interpretor& di, Standard_Integer n, const char** a)
922 {
923   gp_Pnt P;
924   Standard_Boolean is3d;
925   if (n == 2) {
926     Standard_Integer id,X,Y,b;
927     di << "Pick position with button 1, other button escape"<<"\n";
928     dout.Select(id,X,Y,b);
929     if (b != 1)
930       return 0;
931     Standard_Real z = dout.Zoom(id);
932     P.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0);
933     gp_Trsf T;
934     dout.GetTrsf(id,T);
935     T.Invert();
936     P.Transform(T);
937     is3d = dout.Is3D(id);
938   }
939   else if (n >= 4) {
940     is3d = n > 4;
941     P.SetCoord(Draw::Atof(a[1]),Draw::Atof(a[2]),is3d ? Draw::Atof(a[3]) : 0);
942   }
943   else
944     return 0;
945
946   if (is3d) {
947     Handle(Draw_Text3D) D = new Draw_Text3D(P,a[n-1],Draw_vert);
948     dout << D;
949   }
950   else {
951     Handle(Draw_Text2D) D = new Draw_Text2D(gp_Pnt2d(P.X(),P.Y()),
952                                             a[n-1],Draw_vert);
953     dout << D;
954   }
955   return 0;
956 }
957
958 void Draw::GraphicCommands(Draw_Interpretor& theCommands)
959 {
960   static Standard_Boolean Done = Standard_False;
961   if (Done) return;
962   Done = Standard_True;
963
964   const char* g =  "DRAW Graphic Commands";
965   theCommands.Add("wclick","wait for a mouse click",
966                   __FILE__,wclick,g);
967   theCommands.Add("zoom","zoom [view-id] z, or zoom z for all 3d views",
968                   __FILE__,zoom,g);
969   theCommands.Add("2dzoom","2dzoom [view-id] z, or zoom2d z for all 2d views",
970                   __FILE__,zoom,g);
971   theCommands.Add("wzoom","wzoom [view-id X1 Y1 X2 Y2]\n"
972       "- fits the contents of a given rectangle into a view window.\n"
973       "- The view window and rectangle corners are specified through the arguments\n"
974       "- or selected interactively by the user if no arguments are given",
975       __FILE__,wzoom,g);
976   theCommands.Add("view","view view-id type X(0) Y(0) W(500) H(500)",
977                   __FILE__,view,g);
978   theCommands.Add("delete","delete [view-id]",
979                   __FILE__,delview,g);
980   theCommands.Add("fit","fit [view-id]",
981                   __FILE__,fit,g);
982   theCommands.Add("2dfit","2dfit [view-id]",
983                   __FILE__,fit,g);
984   theCommands.Add("fu","fu [view-id], focal up",
985                   __FILE__,focal,g);
986   theCommands.Add("fd","fd [view-id], focal down",
987                   __FILE__,focal,g);
988   theCommands.Add("focal","focal [f]",
989                   __FILE__,setfocal,g);
990   theCommands.Add("mu","mu [view-id], magnify up",
991                   __FILE__,magnify,g);
992   theCommands.Add("2dmu","2dmu [view-id], magnify up",
993                   __FILE__,magnify,g);
994   theCommands.Add("md","md [view-id], magnify down",
995                   __FILE__,magnify,g);
996   theCommands.Add("2dmd","2dmd [view-id], magnify down",
997                   __FILE__,magnify,g);
998   theCommands.Add("u","u [view-id], rotate up",
999                   __FILE__,rotate,g);
1000   theCommands.Add("d","d [view-id], rotate down",
1001                   __FILE__,rotate,g);
1002   theCommands.Add("l","l [view-id], rotate left",__FILE__,rotate,g);
1003   theCommands.Add("r","r [view-id], rotate right",__FILE__,rotate,g);
1004   theCommands.Add("pu","pu [view-id], panning up",__FILE__,panning,g);
1005   theCommands.Add("pd","pd [view-id], panning down",__FILE__,panning,g);
1006   theCommands.Add("pl","pl [view-id], panning left",__FILE__,panning,g);
1007   theCommands.Add("pr","pr [view-id], panning right",__FILE__,panning,g);
1008   theCommands.Add("2dpu","2dpu [view-id], panning up",__FILE__,panning,g);
1009   theCommands.Add("2dpd","2dpd [view-id], panning down",__FILE__,panning,g);
1010   theCommands.Add("2dpl","2dpl [view-id], panning left",__FILE__,panning,g);
1011   theCommands.Add("2dpr","2dpr [view-id], panning right",__FILE__,panning,g);
1012   theCommands.Add("ptv","ptv [view-id], X , Y , Z",
1013                   __FILE__,ptv,g);
1014   theCommands.Add("dptv","dptv [view-id], dX , dY , dZ",
1015                   __FILE__,dptv,g);
1016   theCommands.Add("color","color i colorname, define color i",
1017                   __FILE__,color,g);
1018   theCommands.Add("hardcopy","hardcopy [file = a4.ps] [view-id = 1] [format = a4]", __FILE__,hardcopy,g);
1019   theCommands.Add("xwd","xwd [id = 1] <filename>.{png|bmp|jpg|gif}\n\t\t: Dump contents of viewer window to PNG, BMP, JPEG or GIF file",
1020                   __FILE__,xwd,g);
1021   theCommands.Add("hcolor","hcolor icol width gray (< 1, 0 black)",
1022                   __FILE__,hcolor,g);
1023   theCommands.Add("grid", "grid [stepX(100) [stepY [stepZ]]] / 0",
1024                   __FILE__,grid, g);
1025   theCommands.Add("dflush","dflush, flush the viewer",
1026                   __FILE__,dflush,g);
1027   theCommands.Add("dtext","dtext [x y [z]] string",
1028                   __FILE__,dtext,g);
1029   theCommands.Add("dfont","dfont [name size] : set name and size of Draw font, or reset to default",
1030                   __FILE__,dfont,g);
1031 }
1032