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