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