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