0025113: Mesh - Progress indication and user break functionality for BRepMesh component
[occt.git] / src / Draw / Draw_VariableCommands.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 #include <Draw.hxx>
19 #include <Draw_Appli.hxx>
20 #include <Draw_Axis2D.hxx>
21 #include <Draw_Axis3D.hxx>
22 #include <Draw_Display.hxx>
23 #include <Draw_Drawable3D.hxx>
24 #include <Draw_Grid.hxx>
25 #include <Draw_Number.hxx>
26 #include <Message.hxx>
27 #include <Draw_ProgressIndicator.hxx>
28 #include <Draw_SequenceOfDrawable3D.hxx>
29 #include <Message.hxx>
30 #include <NCollection_Map.hxx>
31 #include <Standard_SStream.hxx>
32 #include <Standard_Stream.hxx>
33 #include <TCollection_AsciiString.hxx>
34
35 #include <ios>
36 #ifdef _WIN32
37 extern Draw_Viewer dout;
38 #endif
39
40 #include <tcl.h>
41 #include <errno.h>
42
43 #include <OSD_Environment.hxx>
44 #include <OSD_OpenFile.hxx>
45
46 Standard_Boolean Draw_ParseFailed;
47
48 static Standard_Boolean autodisp = Standard_True;
49 static Standard_Boolean repaint2d,repaint3d;
50
51 //===============================================
52 // dictionnary of variables
53 // Variables are stored in a map Integer, Transient
54 // The Integer Value is the content of the TCl variable 
55 //===============================================
56
57 static NCollection_Map<Handle(Draw_Drawable3D)> theVariables;
58
59 //=======================================================================
60 //function : FindVariable
61 //purpose  : 
62 //=======================================================================
63
64 static Standard_Integer p_id;
65 static Standard_Integer p_X;
66 static Standard_Integer p_Y;
67 static Standard_Integer p_b;
68 static const char* p_Name = "";
69
70
71 static Draw_SaveAndRestore* Draw_First = NULL;
72
73 //=======================================================================
74 //function : Draw_SaveAndRestore
75 //purpose  : 
76 //=======================================================================
77
78 Draw_SaveAndRestore::Draw_SaveAndRestore
79   (const char* name,
80    Standard_Boolean (*test)(const Handle(Draw_Drawable3D)&),
81   void (*save)(const Handle(Draw_Drawable3D)&, std::ostream&),
82   Handle(Draw_Drawable3D) (*restore) (std::istream&),
83   Standard_Boolean display) :
84   myName(name),
85   myTest(test),
86   mySave(save), 
87   myRestore(restore),
88   myDisplay(display),
89   myNext(Draw_First)
90 {
91   Draw_First = this;
92 }
93
94 Standard_Boolean Draw_SaveAndRestore::Test(const Handle(Draw_Drawable3D)&d)
95 {return (*myTest) (d);}
96
97 void Draw_SaveAndRestore::Save(const Handle(Draw_Drawable3D)& d, 
98                                std::ostream& os) const
99 { (*mySave) (d,os);}
100
101 Handle(Draw_Drawable3D) Draw_SaveAndRestore::Restore(std::istream& is) const
102 {return (*myRestore) (is);}
103
104 //=======================================================================
105 // numeric save and restore
106 //=======================================================================
107
108 static Standard_Boolean numtest(const Handle(Draw_Drawable3D)& d) 
109 {
110   return d->IsInstance(STANDARD_TYPE(Draw_Number));
111 }
112
113 static void numsave (const Handle(Draw_Drawable3D)& theDrawable,
114                      std::ostream&                       theStream)
115 {
116   Handle(Draw_Number) aNum = Handle(Draw_Number)::DownCast (theDrawable);
117   std::ios::fmtflags aFlags = theStream.flags();
118   theStream.setf      (std::ios::scientific);
119   theStream.precision (15);
120   theStream.width     (30);
121   theStream << aNum->Value() << "\n";
122   theStream.setf      (aFlags);
123 }
124
125 static Handle(Draw_Drawable3D) numrestore (std::istream& is)
126 {
127   Standard_Real val;
128   is >> val;
129   Handle(Draw_Number) N = new Draw_Number(val);
130   return N;
131 }
132
133
134 static Draw_SaveAndRestore numsr("Draw_Number",
135                                  numtest,numsave,numrestore,
136                                  Standard_False);
137
138 //=======================================================================
139 // save
140 //=======================================================================
141
142 static Standard_Integer save(Draw_Interpretor& di, Standard_Integer n, const char** a)
143 {
144   if (n <= 2) return 1;
145
146   const char* name = a[2];
147   std::ofstream os;
148   os.precision(15);
149   OSD_OpenStream(os, name, std::ios::out);
150   if (!os.is_open() || !os.good())
151   {
152     di << "Cannot open file for writing "<<name;
153     return 1;
154   }
155
156   Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
157   if (!D.IsNull()) {
158     // find a tool
159     Draw_SaveAndRestore* tool = Draw_First;
160     Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
161
162     while (tool) {
163       if (tool->Test(D)) break;
164       tool = tool->Next();
165     }
166     if (tool) {
167       os << tool->Name() << "\n";
168       Draw::SetProgressBar(progress);
169       tool->Save(D,os);
170       os << "\n";
171     }
172     else {
173       di << "No method for saving " << a[1];
174       return 1;
175     }
176     Draw::SetProgressBar( 0 );
177   }
178   
179   os << "0\n\n";
180
181   Standard_Boolean res = Standard_False;
182
183   errno = 0;
184
185   res = os.good() && !errno;
186   if( !res )
187   {
188     di<<"File has not been written";
189     return 1;
190   }
191
192   di << a[1];
193   return 0;
194 }
195
196 //=======================================================================
197 // read
198 //=======================================================================
199
200 static Standard_Integer restore(Draw_Interpretor& di, Standard_Integer n, const char** a)
201 {
202
203   if (n <= 2) return 1;
204
205   const char* fname = a[1];
206   const char* name  = a[2];
207   
208   std::filebuf fic;
209   std::istream in(&fic);
210   OSD_OpenStream (fic, fname, std::ios::in);
211   if (!fic.is_open()) {
212     di << "Cannot open file for reading : "<<fname;
213     return 1;
214   }
215   
216   char typ[255];
217   in >> typ;
218   if (!in.fail()) {
219     // search a tool
220     Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
221     Draw::SetProgressBar(progress);
222
223     Draw_SaveAndRestore* tool = Draw_First;
224     Draw_SaveAndRestore* aDBRepTool = NULL;
225     while (tool) {
226       const char* toolName = tool->Name();
227       if (!strcmp(typ,toolName)) break;
228       if (!strcmp("DBRep_DrawableShape",toolName))
229         aDBRepTool = tool;
230       tool = tool->Next();
231     }
232
233     if (!tool)
234     {
235       //assume that this file stores a DBRep_DrawableShape variable
236       tool = aDBRepTool;
237       in.seekg(0, std::ios::beg);
238     }
239
240     if (tool)
241     {
242       Handle(Draw_Drawable3D) D = tool->Restore(in);
243       Draw::Set(name,D,tool->Disp() && autodisp);
244     }
245
246     else {
247       di << "Cannot restore a  " << typ;
248       return 1;
249     }
250     Draw::SetProgressBar( 0 );
251   }
252   
253   di << name;
254   return 0;
255 }
256
257 //=======================================================================
258 // display
259 //=======================================================================
260
261 static Standard_Integer display(Draw_Interpretor& di, Standard_Integer n, const char** a)
262 {
263   if (n <= 1) return 1;
264   else {
265     for (Standard_Integer i = 1; i < n; i++) {
266       Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
267       if (!D.IsNull()) {
268         if (!D->Visible()) {
269           dout << D;
270           di << a[i] << " ";
271         }
272       }
273     }
274   }
275   return 0;
276 }
277
278 //=======================================================================
279 // erase, clear, donly
280 //=======================================================================
281
282 static Standard_Integer erase(Draw_Interpretor& di, Standard_Integer n, const char** a)
283 {
284   static Standard_Boolean draw_erase_mute = Standard_False;
285   if (n == 2) {
286     if (!strcasecmp(a[1],"-mute")) {
287       draw_erase_mute = Standard_True;
288       return 0;
289     }
290   }
291
292   Standard_Boolean donly = !strcasecmp(a[0],"donly");
293   
294   if (n <= 1 || donly) {
295     // clear, 2dclear, donly, erase (without arguments)
296     Standard_Integer i;
297     
298     // solve the names for "." before erasing
299     if (donly) {
300       for (i = 1; i < n; i++) {
301         Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
302         if (D.IsNull()) {
303           if ((a[i][0] == '.') && (a[i][1] == '\0'))
304             std::cout << "Missed !!!" << std::endl;
305           return 0;
306         }
307       }
308     }
309     
310     // sauvegarde des proteges visibles
311     Draw_SequenceOfDrawable3D prot;
312     NCollection_Map<Handle(Draw_Drawable3D)>::Iterator aMapIt (theVariables);
313     for (; aMapIt.More(); aMapIt.Next()) {
314       const Handle(Draw_Drawable3D)& D = aMapIt.Key();
315       if (!D.IsNull()) {
316         if (D->Protected() && D->Visible())
317           prot.Append(D);
318       }
319     }
320   
321     // effacement de toutes les variables
322     Standard_Integer erasemode = 1;
323     if (a[0][0] == '2') erasemode = 2;
324     if (a[0][0] == 'c') erasemode = 3;
325     
326     // effacement des graphiques non variables
327     if (erasemode == 2) 
328       dout.Clear2D();
329     else if (erasemode == 3)
330       dout.Clear3D();
331     else
332       dout.Clear();
333     
334     // affichage pour donly
335     if (donly) {
336       for (i = 1; i < n; i++) {
337         Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
338         if (!D.IsNull()) {
339           if (!D->Visible()) {
340             dout << D;
341             if (!draw_erase_mute) di << a[i] << " ";
342           }
343         }
344       }
345     }
346     
347   // afficahge des proteges
348     for (i = 1; i <= prot.Length(); i++)
349       dout << prot(i);
350     
351     
352   }
353   else {
354     for (Standard_Integer i = 1; i < n; i++) {
355       Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
356       if (!D.IsNull()) {
357         if (D->Visible()) {
358             dout.RemoveDrawable(D);
359             if (!draw_erase_mute) di << D->Name() << " ";
360           }
361       }
362     }
363     dout.Repaint2D();
364     dout.Repaint3D();
365   }
366   draw_erase_mute = Standard_False;
367   repaint2d = Standard_False;
368   repaint3d = Standard_False;
369   dout.Flush();
370   return 0;
371 }
372
373
374
375 //=======================================================================
376 // draw
377 //=======================================================================
378
379 static Standard_Integer draw(Draw_Interpretor& , Standard_Integer n, const char** a)
380 {
381   if (n < 3) return 1;
382   Standard_Integer id = Draw::Atoi(a[1]);
383   if (!dout.HasView(id)) {
384     Message::SendFail() << "bad view number in draw";
385     return 1;
386   }
387   Standard_Integer mo = Draw::Atoi(a[2]);
388   Draw_Display d = dout.MakeDisplay(id);
389   d.SetMode(mo);
390   Standard_Integer i;
391   for (i = 3; i < n; i++) {
392     Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
393     if (!D.IsNull()) D->DrawOn(d);
394   }
395   d.Flush();
396   return 0;
397 }
398
399 //=======================================================================
400 // protect, unprotect
401 //=======================================================================
402
403 static Standard_Integer protect(Draw_Interpretor& di, Standard_Integer n, const char** a)
404 {
405   if (n <= 1) return 1;
406   Standard_Boolean prot = *a[0] != 'u';
407   for (Standard_Integer i = 1; i < n; i++) {
408     Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
409     if (!D.IsNull()) {
410       D->Protected(prot);
411       di << a[i] << " ";
412     }
413   }
414   return 0;
415 }
416
417 //=======================================================================
418 // autodisplay
419 //=======================================================================
420
421 static Standard_Integer autodisplay(Draw_Interpretor& di, Standard_Integer n, const char** a)
422 {
423   if (n <= 1)
424     autodisp = !autodisp;
425   else 
426     autodisp = !(!strcasecmp(a[1],"0"));
427
428   if (autodisp)
429     di << "1";
430   else
431     di << "0";
432
433   return 0;
434 }
435
436
437 //=======================================================================
438 // whatis
439 //=======================================================================
440
441 static Standard_Integer whatis(Draw_Interpretor& di, Standard_Integer n, const char** a)
442 {
443   if (n <= 1) return 1;
444   for (Standard_Integer i = 1; i < n; i++) {
445     Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
446     if (!D.IsNull()) {
447       D->Whatis(di);
448     }
449   }
450   return 0;
451 }
452
453
454 //=======================================================================
455 // value
456 //=======================================================================
457
458 static Standard_Integer value(Draw_Interpretor& di, Standard_Integer n, const char** a)
459 {
460   if (n != 2) return 1;
461   di << Draw::Atof(a[1]);
462
463   return 0;
464 }
465
466 //=======================================================================
467 //function : dname
468 //purpose  : 
469 //=======================================================================
470 static Standard_Integer dname(Draw_Interpretor& di, Standard_Integer n, const char** a)
471 {
472   if (n <= 1) {
473     return 1;
474   }
475   //
476   Standard_PCharacter pC;
477   Standard_Integer i;
478   Handle(Draw_Drawable3D) aD;
479   //
480   for (i = 1; i < n; ++i) {
481     aD = Draw::Get(a[i]);
482     if (!aD.IsNull()) {
483       //modified by NIZNHY-PKV Tue Jun 10 10:18:13 2008f
484       //di << a[i];
485       pC=(Standard_PCharacter)aD->Name();
486       di << pC;
487       //modified by NIZNHY-PKV Tue Jun 10 10:18:18 2008t
488     }
489   }
490   return 0;
491 }
492
493 //=======================================================================
494 // dump
495 //=======================================================================
496
497
498 static Standard_Integer dump(Draw_Interpretor& DI, Standard_Integer n, const char** a)
499 {
500   if(n < 2) return 1;
501   Standard_Integer i;
502   for (i = 1; i < n; i++) {
503     Handle(Draw_Drawable3D) D = Draw::Get(a[i]);
504     if (!D.IsNull()) {
505       Standard_SStream sss;
506       sss.precision(15);
507       sss << "\n\n*********** Dump of " << a[i] << " *************\n";
508       D->Dump(sss);
509       DI << sss;
510     }
511   }
512   return 0;
513 }
514
515 //=======================================================================
516 // copy
517 //=======================================================================
518
519 static Standard_Integer copy(Draw_Interpretor& , Standard_Integer n, const char** a)
520 {
521   if (n < 3) return 1;
522   Standard_Boolean cop = !strcasecmp(a[0],"copy");
523
524   Handle(Draw_Drawable3D) D;
525   for (Standard_Integer i = 1; i < n; i += 2) {
526     if (i+1 >= n) return 0;
527     D = Draw::Get(a[i]);
528     if (!D.IsNull()) {
529       if (cop) 
530         D = D->Copy();
531       else 
532         // clear old name
533         Draw::Set(a[i],Handle(Draw_Drawable3D)());
534
535       Draw::Set(a[i+1],D);
536     }
537   }
538   return 0;
539 }
540
541 //=======================================================================
542 //function : repaint
543 //purpose  : 
544 //=======================================================================
545
546 static Standard_Integer repaintall(Draw_Interpretor& , Standard_Integer , const char** )
547 {
548   if (repaint2d) dout.Repaint2D();
549   repaint2d = Standard_False;
550   if (repaint3d) dout.Repaint3D();
551   repaint3d = Standard_False;
552   dout.Flush();
553   return 0;
554 }
555
556 //=======================================================================
557 //function : set
558 //purpose  : 
559 //=======================================================================
560
561 static Standard_Integer set(Draw_Interpretor& di, Standard_Integer n, const char** a)
562 {
563   if (n < 2) return 1;
564   Standard_Integer i = 1;
565   Standard_Real val=0;
566   for (i = 1; i < n; i += 2) {
567     val = 0;
568     if (i+1 < n) val = Draw::Atof(a[i+1]);
569     Draw::Set(a[i],val);
570   }
571   di << val;
572   return 0;
573 }
574
575 //=======================================================================
576 //function : dsetenv
577 //purpose  : 
578 //=======================================================================
579
580 static Standard_Integer dsetenv(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
581 {
582   if (argc < 2) {
583     Message::SendFail() << "Use: " << argv[0] << " {varname} [value]";
584     return 1;
585   }
586
587   OSD_Environment env (argv[1]);
588   if (argc > 2 && argv[2][0] != '\0')
589   {
590     env.SetValue (argv[2]);
591     env.Build();
592   }
593   else
594     env.Remove();
595   return env.Failed();
596 }
597
598 //=======================================================================
599 //function : dgetenv
600 //purpose  : 
601 //=======================================================================
602
603 static Standard_Integer dgetenv(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
604 {
605   if (argc < 2) {
606     Message::SendFail() << "Use: " << argv[0] << " {varname}";
607     return 1;
608   }
609
610   const char* val = getenv (argv[1]);
611   di << ( val ? val : "" );
612   return 0;
613 }
614
615 //=======================================================================
616 //function : isdraw
617 //purpose  : 
618 //=======================================================================
619
620 static Standard_Integer isdraw(Draw_Interpretor& di, Standard_Integer n, const char** a)
621 {
622   if (n != 2) return 1;
623   Handle(Draw_Drawable3D) D = Draw::Get (a[1]);
624   if (D.IsNull())
625     di << "0";
626   else
627     di << "1";
628   return 0;
629 }
630
631 //=======================================================================
632 //function : isprot
633 //purpose  : 
634 //=======================================================================
635
636 Standard_Integer isprot(Draw_Interpretor& di, Standard_Integer n, const char** a)
637 {
638   if (n != 2) return 1;
639   Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
640   if (D.IsNull())
641     di << "0";
642   else {
643     if (D->Protected())
644       di << "1";
645     else
646       di << "0";
647   }
648   return 0;
649 }
650
651
652 //=======================================================================
653 //function : pick
654 //purpose  : 
655 //=======================================================================
656
657 static Standard_Integer pick(Draw_Interpretor& , Standard_Integer n, const char** a)
658 {
659   if (n < 6) return 1;
660   Standard_Integer id;
661   Standard_Integer X,Y,b;
662   Standard_Boolean wait = (n == 6);
663   if (!wait) id = Draw::Atoi(a[1]);
664   dout.Select(id,X,Y,b,wait);
665   Standard_Real z = dout.Zoom(id);
666   gp_Pnt P((Standard_Real)X /z,(Standard_Real)Y /z,0);
667   gp_Trsf T;
668   dout.GetTrsf(id,T);
669   T.Invert();
670   P.Transform(T);
671   Draw::Set(a[1],id);
672   Draw::Set(a[2],P.X());
673   Draw::Set(a[3],P.Y());
674   Draw::Set(a[4],P.Z());
675   Draw::Set(a[5],b);
676   return 0;
677 }
678
679
680 //=======================================================================
681 //function : lastrep
682 //purpose  : 
683 //=======================================================================
684
685 static Standard_Integer lastrep(Draw_Interpretor& di, Standard_Integer n, const char** a)
686 {
687   if (n < 5) return 1;
688
689   Draw::Set(a[1],p_id);
690   if (n == 5) {
691     Draw::Set(a[2],p_X);
692     Draw::Set(a[3],p_Y);
693   }
694   else if (n == 6) {
695     Standard_Real z = dout.Zoom(p_id);
696     gp_Pnt P((Standard_Real)p_X /z,(Standard_Real)p_Y /z,0);
697     gp_Trsf T;
698     dout.GetTrsf(p_id,T);
699     T.Invert();
700     P.Transform(T);
701     Draw::Set(a[2],P.X());
702     Draw::Set(a[3],P.Y());
703     Draw::Set(a[4],P.Z());
704   }
705   else {
706     di << "Too many args";
707     return 1;
708   }
709   Draw::Set(a[n-1],p_b);
710   di << p_Name;
711   return 0;
712 }
713
714
715 //=======================================================================
716 //function : Set
717 //purpose  : 
718 //=======================================================================
719 void Draw::Set(const Standard_CString name, 
720                const Handle(Draw_Drawable3D)& D)
721 {
722  Draw::Set(name,D,autodisp);
723 }
724
725 // MKV 29.03.05
726 static char* tracevar(ClientData CD, Tcl_Interp*,const char* name,const char*, int)
727 {
728   // protect if the map was destroyed before the interpretor
729   if (theVariables.IsEmpty()) return NULL;
730
731   Draw_Interpretor& aCommands = Draw::GetInterpretor();
732
733   // MSV 9.10.14 CR25344
734   Handle(Draw_Drawable3D) D(reinterpret_cast<Draw_Drawable3D*>(CD));
735   if (D.IsNull()) {
736     Tcl_UntraceVar(aCommands.Interp(),name,TCL_TRACE_UNSETS | TCL_TRACE_WRITES,
737                    tracevar,CD);
738     return NULL;
739   }
740   if (D->Protected()) {
741     D->Name(Tcl_SetVar(aCommands.Interp(),name,name,0));
742     return (char*) "variable is protected";
743   } else {
744     if (D->Visible()) {
745       dout.RemoveDrawable(D);
746       if (D->Is3D()) 
747           repaint3d = Standard_True;
748       else
749           repaint2d = Standard_True;
750     }
751     Tcl_UntraceVar(aCommands.Interp(),name,TCL_TRACE_UNSETS | TCL_TRACE_WRITES,
752                    tracevar,CD);
753     theVariables.Remove(D);
754     return NULL;
755   }
756 }
757
758 //=======================================================================
759 //function : Set
760 //purpose  : 
761 //=======================================================================
762 void Draw::Set(const Standard_CString name, 
763                const Handle(Draw_Drawable3D)& D,
764                const Standard_Boolean displ)
765 {
766   Draw_Interpretor& aCommands = Draw::GetInterpretor();
767
768   if ((name[0] == '.') && (name[1] == '\0')) {
769     if (!D.IsNull()) {
770       dout.RemoveDrawable(D);
771       if (displ) dout << D;
772     }
773   }
774   else {
775     // Check if the variable with the same name exists
776     ClientData aCD =
777       Tcl_VarTraceInfo(aCommands.Interp(),name,TCL_TRACE_UNSETS | TCL_TRACE_WRITES,
778                        tracevar, NULL);
779     Handle(Draw_Drawable3D) anOldD(reinterpret_cast<Draw_Drawable3D*>(aCD));
780     if (!anOldD.IsNull()) {
781       if (theVariables.Contains(anOldD) && anOldD->Protected()) {
782         std::cout << "variable is protected" << std::endl;
783         return;
784       }
785       anOldD.Nullify();
786     }
787
788     Tcl_UnsetVar(aCommands.Interp(),name,0);
789
790     if (!D.IsNull()) {
791       theVariables.Add(D);
792       D->Name(Tcl_SetVar(aCommands.Interp(),name,name,0));
793     
794       // set the trace function
795       Tcl_TraceVar(aCommands.Interp(),name,TCL_TRACE_UNSETS | TCL_TRACE_WRITES,
796                    tracevar,reinterpret_cast<ClientData>(D.operator->()));
797       if (displ) {
798         if (!D->Visible())
799           dout << D;
800       }
801       else if (D->Visible())
802         dout.RemoveDrawable(D);
803     }
804   }
805 }
806 //=======================================================================
807 //function : Set
808 //purpose  : 
809 //=======================================================================
810 void Draw::Set(const Standard_CString theName, const Standard_Real theValue)
811 {
812   if (Handle(Draw_Number) aNumber = Handle(Draw_Number)::DownCast (Draw::GetExisting (theName)))
813   {
814     aNumber->Value (theValue);
815   }
816   else
817   {
818     aNumber = new Draw_Number (theValue);
819     Draw::Set (theName, aNumber, Standard_False);
820   }
821 }
822
823 //=======================================================================
824 //function : getDrawable
825 //purpose  :
826 //=======================================================================
827 Handle(Draw_Drawable3D) Draw::getDrawable (Standard_CString& theName,
828                                            Standard_Boolean theToAllowPick)
829 {
830   const Standard_Boolean toPick = ((theName[0] == '.') && (theName[1] == '\0'));
831   if (!toPick)
832   {
833     ClientData aCD = Tcl_VarTraceInfo (Draw::GetInterpretor().Interp(), theName, TCL_TRACE_UNSETS | TCL_TRACE_WRITES, tracevar, NULL);
834     Handle(Draw_Drawable3D) aDrawable = reinterpret_cast<Draw_Drawable3D*>(aCD);
835     return theVariables.Contains (aDrawable)
836          ? aDrawable
837          : Handle(Draw_Drawable3D)();
838   }
839   else if (!theToAllowPick)
840   {
841     return Handle(Draw_Drawable3D)();
842   }
843
844   std::cout << "Pick an object" << std::endl;
845   Handle(Draw_Drawable3D) aDrawable;
846   dout.Select (p_id, p_X, p_Y, p_b);
847   dout.Pick (p_id, p_X, p_Y, 5, aDrawable, 0);
848   if (!aDrawable.IsNull()
849     && aDrawable->Name() != NULL)
850   {
851     theName = p_Name = aDrawable->Name();
852   }
853   return aDrawable;
854 }
855
856 //=======================================================================
857 //function : Get
858 //purpose  : 
859 //=======================================================================
860 Standard_Boolean Draw::Get (const Standard_CString theName,
861                             Standard_Real& theValue)
862 {
863   if (Handle(Draw_Number) aNumber = Handle(Draw_Number)::DownCast (Draw::GetExisting (theName)))
864   {
865     theValue = aNumber->Value();
866     return Standard_True;
867   }
868   return Standard_False;
869 }
870
871 //=======================================================================
872 //function : LastPick
873 //purpose  : 
874 //=======================================================================
875 void  Draw::LastPick(Standard_Integer& view, 
876                      Standard_Integer& X, 
877                      Standard_Integer& Y, 
878                      Standard_Integer& button)
879 {
880   view = p_id;
881   X = p_X;
882   Y = p_Y;
883   button = p_b;
884 }
885 //=======================================================================
886 //function : Repaint
887 //purpose  : 
888 //=======================================================================
889 void  Draw::Repaint()
890 {
891   repaint2d = Standard_True;
892   repaint3d = Standard_True;
893 }
894
895 //=======================================================================
896 //function : trigonometric functions
897 //purpose  : 
898 //=======================================================================
899
900 //static Standard_Integer trigo (Draw_Interpretor& di, Standard_Integer n, const char** a)
901 static Standard_Integer trigo (Draw_Interpretor& di, Standard_Integer , const char** a)
902 {
903
904   Standard_Real x = Draw::Atof(a[1]);
905
906   if (!strcasecmp(a[0],"cos"))
907     di << Cos(x);
908   else if (!strcasecmp(a[0],"sin"))
909     di << Sin(x);
910   else if (!strcasecmp(a[0],"tan"))
911     di << Tan(x);
912   else if (!strcasecmp(a[0],"sqrt"))
913     di << Sqrt(x);
914   else if (!strcasecmp(a[0],"acos"))
915     di << ACos(x);
916   else if (!strcasecmp(a[0],"asin"))
917     di << ASin(x);
918   else if (!strcasecmp(a[0],"atan2"))
919     di << ATan2(x,Draw::Atof(a[2]));
920
921   return 0;
922 }
923
924
925 //=======================================================================
926 // Atof and Atoi
927 //=======================================================================
928
929 static Standard_Boolean Numeric(char c)
930 {
931   return (c == '.' || (c >= '0' && c <= '9'));
932 }
933
934 static Standard_Boolean Alphabetic(char c)
935 {
936   return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'));
937 }
938
939 static Standard_Real Parse(char*&);
940
941 static Standard_Real ParseValue(char*& name)
942 {
943   while (*name == ' ' || *name == '\t') name++;
944   Standard_Real x = 0;
945   switch (*name) {
946
947   case '\0' :
948     break;
949
950   case '(' :
951     name++;
952     x = Parse(name);
953     if (*name != ')') 
954       std::cout << "Mismatched parenthesis" << std::endl;
955     name++;
956     break;
957
958   case '+' :
959     name++;
960     x = ParseValue(name);
961     break;
962
963   case '-' :
964     name++;
965     x = - ParseValue(name);
966     break;
967
968     default :
969       {
970         // process a string
971         
972         char* p = name;
973         while (Numeric(*p)) p++;
974         // process scientific notation
975         if ((*p == 'e') || (*p == 'E')) {
976           if (Numeric(*(p+1)) || *(p+1) == '+' || *(p+1) == '-')
977             p+= 2;
978         }
979         while (Numeric(*p) || Alphabetic(*p)) p++;
980         char c = *p;
981         *p = '\0';
982         
983         if (Numeric(*name))   // numeric litteral
984           x = Atof(name);
985         else if (!Draw::Get((Standard_CString) name,x)) {  // variable
986           
987           // search for a function ...
988           *p = c;
989           // count arguments
990           Standard_Integer argc = 1;
991           char* q = p;
992           while ((*q == ' ') || (*q == '\t')) q++;
993           if (*q == '(') {
994             Standard_Integer pc = 1;
995             argc = 2;
996             q++;
997             while ((pc > 0) && *q) {
998               if (*q == '(') pc++;
999               if (*q == ')') pc--;
1000               if ((pc == 1) && (*q == ',')) argc++;
1001               q++;
1002             }
1003             if (pc > 0) {
1004               std::cout << "Unclosed parenthesis"<< std::endl;
1005               x = 0;
1006             }
1007             else {
1008               // build function call 
1009               // replace , and first and last () by space
1010               if (argc > 1) {
1011                 Standard_Integer i = 2;
1012                 while (*p != '(') p++;
1013                 *p = ' ';
1014                 p++;
1015                 pc = 1;
1016                 while (pc > 0) {
1017                   if (*p == '(') pc++;
1018                   if (*p == ')') pc--;
1019                   if ((pc == 1) && (*p == ',')) {
1020                     *p = ' ';
1021                     p++;
1022                     i++;
1023                   }
1024                   else
1025                     p++;
1026                 }
1027                 *(p-1) = '\0';
1028                 c = *p;
1029
1030     Draw_Interpretor& aCommands = Draw::GetInterpretor();
1031
1032                 // call the function, save the current result
1033                 char* sv = 0;
1034                 if (*aCommands.Result()) {
1035                   sv = new char [strlen(aCommands.Result())];
1036                   strcpy(sv,aCommands.Result());
1037                   aCommands.Reset();
1038                 }
1039                 if (aCommands.Eval(name) != 0) {
1040                   std::cout << "Call of function " << name << " failed" << std::endl;
1041                   x = 0;
1042                 }
1043                 else
1044                   x = Atof(aCommands.Result());
1045                 aCommands.Reset();
1046                 if (sv) {
1047                   aCommands << sv;
1048                   delete [] sv;
1049                 }
1050               }
1051             }
1052           }
1053           else
1054             Draw_ParseFailed = Standard_True;
1055         }
1056         *p = c;
1057         name = p;
1058       }
1059     break;
1060     
1061   }
1062   while (*name == ' ' || *name == '\t') name++;
1063   return x;
1064 }
1065
1066
1067 static Standard_Real ParseFactor(char*& name)
1068 {
1069   Standard_Real x = ParseValue(name);
1070
1071   for(;;) {
1072     char c = *name;
1073     if (c == '\0') return x;
1074     name++;
1075     switch (c) {
1076
1077     case '*' :
1078       x *= ParseValue(name);
1079       break;
1080
1081     case '/' :
1082       x /= ParseValue(name);
1083       break;
1084
1085       default :
1086         name--;
1087         return x;
1088       
1089     }
1090   }
1091 }
1092
1093 static Standard_Real Parse(char*& name)
1094 {
1095   Standard_Real x = ParseFactor(name);
1096
1097   for(;;) {
1098     char c = *name;
1099     if (c == '\0') return x;
1100     name++;
1101     switch (c) {
1102
1103     case '+' :
1104       x += ParseFactor(name);
1105       break;
1106
1107     case '-' :
1108       x -= ParseFactor(name);
1109       break;
1110
1111       default :
1112   name--;
1113   return x;
1114       
1115     }
1116   }
1117 }
1118
1119 //=======================================================================
1120 // function : Atof
1121 // purpose  :
1122 //=======================================================================
1123 Standard_Real Draw::Atof(const Standard_CString name)
1124 {
1125   // copy the string
1126   char* n = new char[1+strlen(name)];
1127   char* b = n;
1128   strcpy(n,name);
1129   Draw_ParseFailed = Standard_False;
1130   Standard_Real x = Parse(n);
1131   while ((*n == ' ') || (*n == '\t')) n++;
1132   if (*n) Draw_ParseFailed = Standard_True;
1133   delete [] b;
1134   return x;
1135 }
1136
1137 //=======================================================================
1138 // function : ParseReal
1139 // purpose  :
1140 //=======================================================================
1141 bool Draw::ParseReal (const Standard_CString theExpressionString, Standard_Real& theParsedRealValue)
1142 {
1143   const Standard_Real aParsedRealValue = Atof (theExpressionString);
1144   if (Draw_ParseFailed)
1145   {
1146     Draw_ParseFailed = Standard_False;
1147     return false;
1148   }
1149   theParsedRealValue = aParsedRealValue;
1150   return true;
1151 }
1152
1153 //=======================================================================
1154 // function : Atoi
1155 // purpose  :
1156 //=======================================================================
1157 Standard_Integer Draw::Atoi(const Standard_CString name)
1158 {
1159   return (Standard_Integer) Draw::Atof(name);
1160 }
1161
1162 //=======================================================================
1163 // function : ParseInteger
1164 // purpose  :
1165 //=======================================================================
1166 bool Draw::ParseInteger (const Standard_CString theExpressionString, Standard_Integer& theParsedIntegerValue)
1167 {
1168   Standard_Real aParsedRealValue = 0.0;
1169   if (!ParseReal (theExpressionString, aParsedRealValue))
1170   {
1171     return false;
1172   }
1173   const Standard_Integer aParsedIntegerValue = static_cast<Standard_Integer> (aParsedRealValue);
1174   if (static_cast<Standard_Real> (aParsedIntegerValue) != aParsedRealValue)
1175   {
1176     return false;
1177   }
1178   theParsedIntegerValue = aParsedIntegerValue;
1179   return true;
1180 }
1181
1182 //=======================================================================
1183 //function : Set
1184 //purpose  : set a TCL var
1185 //=======================================================================
1186 void Draw::Set(const Standard_CString Name, const Standard_CString val)
1187 {
1188   Standard_PCharacter pName, pVal;
1189   //
1190   pName=(Standard_PCharacter)Name;
1191   pVal=(Standard_PCharacter)val;
1192   //
1193   Tcl_SetVar(Draw::GetInterpretor().Interp(), pName, pVal, 0);
1194 }
1195 //=======================================================================
1196 // Command management
1197 // refresh the screen
1198 //=======================================================================
1199
1200 static void before()
1201 {
1202   repaint2d = Standard_False;
1203   repaint3d = Standard_False;
1204 }
1205
1206 void Draw_RepaintNowIfNecessary()
1207 {
1208   if (repaint2d) dout.Repaint2D();
1209   if (repaint3d) dout.Repaint3D();
1210   repaint2d = Standard_False;
1211   repaint3d = Standard_False;
1212 }
1213
1214 static void  after(Standard_Integer)
1215 {
1216   Draw_RepaintNowIfNecessary();
1217 }
1218
1219 extern void (*Draw_BeforeCommand)();
1220 extern void (*Draw_AfterCommand)(Standard_Integer);
1221
1222
1223 //=======================================================================
1224 //function : Commands
1225 //purpose  : 
1226 //=======================================================================
1227 void  Draw::VariableCommands(Draw_Interpretor& theCommandsArg)
1228 {
1229   static Standard_Boolean Done = Standard_False;
1230   if (Done) return;
1231   Done = Standard_True;
1232
1233   // set up start and stop command
1234   Draw_BeforeCommand = &before;
1235   Draw_AfterCommand  = &after;
1236
1237   //  set up some variables
1238
1239   const char* n;
1240   Handle(Draw_Axis3D) theAxes3d = new Draw_Axis3D(gp_Pnt(0,0,0),Draw_bleu,20);
1241   n = "axes";
1242   Draw::Set(n,theAxes3d);
1243   theAxes3d->Protected(Standard_True);
1244
1245   Handle(Draw_Axis2D) theAxes2d = new Draw_Axis2D(gp_Pnt2d(0,0),Draw_bleu,20);
1246   n = "axes2d";
1247   Draw::Set(n,theAxes2d);
1248   theAxes2d->Protected(Standard_True);
1249
1250   n = "pi";
1251   Draw::Set(n,M_PI);
1252   Draw::Get(n)->Protected(Standard_True);
1253
1254   n = "pinf";
1255   Draw::Set(n,RealLast());
1256   Draw::Get(n)->Protected(Standard_True);
1257
1258   n = "minf";
1259   Draw::Set(n,RealFirst());
1260   Draw::Get(n)->Protected(Standard_True);
1261
1262   n = "grid";
1263   Handle(Draw_Grid) theGrid = new Draw_Grid();
1264   Draw::Set(n, theGrid);
1265   theGrid->Protected(Standard_True);
1266   
1267
1268   const char* g;
1269
1270   g = "DRAW Numeric functions";
1271
1272   theCommandsArg.Add("cos" ,"cos(x)" ,__FILE__,trigo,g);
1273   theCommandsArg.Add("sin" ,"sin(x)" ,__FILE__,trigo,g);
1274   theCommandsArg.Add("tan" ,"tan(x)" ,__FILE__,trigo,g);
1275   theCommandsArg.Add("acos" ,"acos(x)" ,__FILE__,trigo,g);
1276   theCommandsArg.Add("asin" ,"asin(x)" ,__FILE__,trigo,g);
1277   theCommandsArg.Add("atan2" ,"atan2(x,y)" ,__FILE__,trigo,g);
1278   theCommandsArg.Add("sqrt","sqrt(x)",__FILE__,trigo,g);
1279
1280   g = "DRAW Variables management";
1281
1282   theCommandsArg.Add("protect","protect name ...",__FILE__,protect,g);
1283   theCommandsArg.Add("unprotect","unprotect name ...",__FILE__,protect,g);
1284
1285   theCommandsArg.Add("bsave","bsave name filename",__FILE__,save,g);
1286   theCommandsArg.Add("brestore","brestore filename name",__FILE__,restore,g);
1287
1288   theCommandsArg.Add("isdraw","isdraw var, return 1 if Draw value",__FILE__,isdraw,g);
1289   theCommandsArg.Add("isprot","isprot var, return 1 if Draw var is protected",__FILE__,isprot,g);
1290   
1291   theCommandsArg.Add("autodisplay","toggle autodisplay [0/1]",__FILE__,autodisplay,g);
1292   theCommandsArg.Add("display","display [name1 name2 ...], no names display all",__FILE__,display,g);
1293   theCommandsArg.Add("donly","donly [name1 name2 ...], erase and display",__FILE__,erase,g);
1294   theCommandsArg.Add("erase","erase [name1 name2 ...], no names erase all",__FILE__,erase,g);
1295   theCommandsArg.Add("draw","draw view mode [name1 name2 ...], draw on view with mode",__FILE__,draw,g);
1296   theCommandsArg.Add("clear","clear display",__FILE__,erase,g);
1297   theCommandsArg.Add("2dclear","clear display (2d objects)",__FILE__,erase,g);
1298   theCommandsArg.Add("repaint","repaint, force redraw",__FILE__,repaintall,g);
1299
1300   theCommandsArg.Add("dtyp", "dtyp name1 name2",__FILE__,whatis,g);
1301   theCommandsArg.Add("dval", "dval name, return value",__FILE__,value,g);
1302   theCommandsArg.Add("dname", "dname name, print name",__FILE__,dname,g);
1303   theCommandsArg.Add("dump", "dump name1 name2 ...",__FILE__,dump,g);
1304   theCommandsArg.Add("copy",  "copy name1 toname1 name2 toname2 ...",__FILE__,copy,g);
1305   // san - 02/08/2002 - `rename` command changed to `renamevar` since it conflicts with 
1306   // the built-in Tcl command `rename`
1307   //theCommands.Add("rename","rename name1 toname1 name2 toname2 ...",__FILE__,copy,g);
1308   theCommandsArg.Add("renamevar","renamevar name1 toname1 name2 toname2 ...",__FILE__,copy,g);
1309   theCommandsArg.Add("dset","var1 value1 vr2 value2 ...",__FILE__,set,g);
1310
1311   // commands to access C environment variables; see Mantis issue #23197
1312   theCommandsArg.Add("dgetenv","var : get value of environment variable in C subsystem",__FILE__,dgetenv,g);
1313   theCommandsArg.Add("dsetenv","var [value] : set (unset if value is empty) environment variable in C subsystem",__FILE__,dsetenv,g);
1314
1315   theCommandsArg.Add("pick","pick id X Y Z b [nowait]",__FILE__,pick,g);
1316   theCommandsArg.Add("lastrep","lastrep id X Y [Z] b, return name",__FILE__,lastrep,g);
1317 }