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