0032455: Data Exchange - replace OSD_OpenStream() usage with OSD_FileSystem::DefaultF...
[occt.git] / src / DBRep / DBRep.cxx
1 // Created on: 1993-07-21
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <DBRep.hxx>
18
19 #include <BRep_TEdge.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepGProp.hxx>
22 #include <BRepTools.hxx>
23 #include <BRepTools_ShapeSet.hxx>
24 #include <BRepTools_WireExplorer.hxx>
25 #include <BinTools.hxx>
26 #include <DBRep_DrawableShape.hxx>
27 #include <Draw.hxx>
28 #include <Draw_Appli.hxx>
29 #include <Draw_ProgressIndicator.hxx>
30 #include <Message_ProgressRange.hxx>
31 #include <Draw_Segment3D.hxx>
32 #include <gp_Ax2.hxx>
33 #include <GProp.hxx>
34 #include <GProp_GProps.hxx>
35 #include <NCollection_Vector.hxx>
36 #include <OSD_FileSystem.hxx>
37 #include <Precision.hxx>
38 #include <TColStd_Array1OfInteger.hxx>
39 #include <TColStd_Array1OfReal.hxx>
40 #include <TopAbs.hxx>
41 #include <TopExp.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopoDS.hxx>
44 #include <TopoDS_Compound.hxx>
45 #include <TopoDS_Iterator.hxx>
46 #include <TopTools_Array1OfShape.hxx>
47 #include <TopTools_ListOfShape.hxx>
48 #include <TopTools_MapOfShape.hxx>
49
50 #include <stdio.h>
51 // memory management
52 #ifdef _WIN32
53 extern Draw_Viewer dout;
54 #endif
55
56 #define Characters(IArg) (strspn (Arg[IArg], "0123456789.+-eE") != strlen (Arg[IArg]))
57 #define Float(IArg)      (strspn (Arg[IArg], "0123456789+-")    != strlen (Arg[IArg]))
58
59
60 //==========================================
61 // useful methods
62 //==========================================
63
64 Standard_EXPORT void DBRep_WriteColorOrientation ()
65 {
66   std::cout << "\nrouge  FORWARD";
67   std::cout << "\nbleu   REVERSED";
68   std::cout << "\nrose   EXTERNAL";
69   std::cout << "\norange INTERNAL"<<std::endl;
70 }
71
72 Standard_EXPORT Draw_Color DBRep_ColorOrientation (const TopAbs_Orientation Or) 
73 {
74   Draw_Color col;
75   switch (Or) {
76
77   case TopAbs_FORWARD :
78     col = Draw_rouge;
79     break;
80     
81   case TopAbs_REVERSED :
82     col = Draw_bleu;
83     break;
84     
85   case TopAbs_EXTERNAL :
86     col = Draw_rose;
87     break;
88     
89   case TopAbs_INTERNAL :
90     col = Draw_orange;
91     break;
92     
93   }
94   return col;
95 }
96
97 //=======================================================================
98 //function : Parameters
99 //purpose  :
100 //=======================================================================
101 DBRep_Params& DBRep::Parameters()
102 {
103   static DBRep_Params aParams;
104   return aParams;
105 }
106
107 //=======================================================================
108 // isos
109 //=======================================================================
110
111 static Standard_Integer isos(Draw_Interpretor& di, Standard_Integer NbArg, const char **Arg)
112 {
113   DBRep_Params& aParams = DBRep::Parameters();
114   NbArg-- ;
115   if (NbArg <= 0)
116   {
117     di << "Current number of isos : " << aParams.NbIsos << "\n" ;
118     return 0 ;
119   }
120
121   Standard_Integer aNbIsos = 0;
122   Standard_Boolean Change = Standard_False ;
123   if (!Characters (NbArg) && Float (NbArg)) return 1 ;
124   if (!Characters (NbArg))
125   {
126     aNbIsos = Draw::Atoi (Arg[NbArg]);
127     NbArg-- ;
128     Change = Standard_True ;
129   }
130
131   if (NbArg <= 0)
132   {
133     aParams.NbIsos = aNbIsos;
134     di << "New current number of isos : " << aParams.NbIsos << "\n";
135   }
136   else
137   {
138     for (Standard_Integer IArg = 1 ; IArg <= NbArg ; IArg++)
139     {
140       Handle (Draw_Drawable3D) Shape1 = Draw::Get (Arg[IArg]) ;
141       if (!Shape1.IsNull())
142       {
143         Handle (DBRep_DrawableShape) Shape2 = Handle (DBRep_DrawableShape)::DownCast (Shape1);
144         if (!Shape2.IsNull())
145         {
146           if (Change)
147           {
148             Shape2->ChangeNbIsos (aNbIsos);
149           }
150           else
151           {
152             di << "Number of isos for " << Arg[IArg] << " : " << Shape2->NbIsos() << "\n";
153           }
154         }
155       }
156     }
157     if (Change) dout.RepaintAll() ;
158   }
159
160   return 0 ;
161 }
162
163 //=======================================================================
164 // hlr
165 //=======================================================================
166
167 static Standard_Integer hlr (Draw_Interpretor& di, Standard_Integer n, const char **a)
168 {
169   DBRep_Params& aParams = DBRep::Parameters();
170   if (n <= 1)
171   {
172     if (aParams.WithHLR)
173     {
174       di << " HLR";
175       di << (aParams.WithRgN
176            ? " RgNLines"
177            : (aParams.WithRg1 ? " Rg1Lines" : " no RegLines"));
178       di << (aParams.WithHid ? " HiddenLines" : " no HiddenLines");
179       di << "\n";
180       if (aParams.WithHLR)
181       {
182         di << "Angle of discretization : ";
183         di << aParams.HLRAngle * 180 / M_PI << " degrees\n";
184       }
185     }
186     else di << " wireframe";
187     di << "\n";
188     return 0 ;
189   }
190
191   if (n == 2)
192   {
193     if (!strcasecmp(a[1], "nohlr"))
194     {
195       aParams.WithHLR = Standard_False;
196     }
197     else if (!strcasecmp (a[1], "hlr"))
198     {
199       aParams.WithHLR = Standard_True;
200     }
201     else if (!strcasecmp (a[1], "nohid"))
202     {
203       aParams.WithHid = Standard_False;
204     }
205     else if (!strcasecmp(a[1], "hid"))
206     {
207       aParams.WithHLR = Standard_True;
208       aParams.WithHid = Standard_True;
209     }
210     else if (!strcasecmp(a[1], "norg1"))
211     {
212       aParams.WithRg1 = Standard_False;
213       aParams.WithRgN = Standard_False;
214     }
215     else if (!strcasecmp (a[1], "rg1"))
216     {
217       aParams.WithHLR = Standard_True;
218       aParams.WithRg1 = Standard_True;
219       aParams.WithRgN = Standard_False;
220     }
221     else if (!strcasecmp (a[1], "norgn"))
222     {
223       aParams.WithRgN = Standard_False;
224     }
225     else if (!strcasecmp (a[1], "rgn"))
226     {
227       aParams.WithHLR = Standard_True;
228       aParams.WithRg1 = Standard_True;
229       aParams.WithRgN = Standard_True;
230     }
231     else if (!strcasecmp (a[1], "ang"))
232     {
233       di << "Angle de discretisation : ";
234       di << aParams.HLRAngle * 180 / M_PI << " degres\n";
235     }
236     else return 1;
237   }
238
239   Standard_Integer nFirst = 2;
240
241   if (n >= 3 && !strcasecmp (a[1], "ang"))
242   {
243     nFirst = 3;
244     if(n == 3)
245     {
246       Standard_Real ang = Draw::Atof(a[2]);
247       aParams.HLRAngle = ang * M_PI / 180;
248       if(aParams.HLRAngle < aParams.HAngMin)
249       {
250         aParams.HLRAngle = aParams.HAngMin;
251       }
252       if (aParams.HLRAngle > aParams.HAngMax)
253       {
254         aParams.HLRAngle = aParams.HAngMax;
255       }
256     }
257     di << "Angle of discretization : ";
258     di << aParams.HLRAngle * 180 / M_PI << " degrees\n";
259   }
260
261   for (Standard_Integer i = nFirst; i < n; i++)
262   {
263     Handle(Draw_Drawable3D) D = Draw::Get (a[i]);
264     Handle(DBRep_DrawableShape) S = Handle(DBRep_DrawableShape)::DownCast (D);
265     if (S.IsNull())
266     {
267       continue;
268     }
269
270     bool localHLR = false, localRg1 = false, localRgN = false, localHid = false;
271     Standard_Real localAng = 0.0;
272     S->GetDisplayHLR(localHLR, localRg1, localRgN, localHid, localAng);
273     if (!strcasecmp (a[1], "nohlr"))
274     {
275       localHLR = Standard_False;
276     }
277     else if (!strcasecmp (a[1], "hlr"))
278     {
279       localHLR = Standard_True;
280     }
281     else if (!strcasecmp (a[1], "nohid"))
282     {
283       localHid = Standard_False;
284     }
285     else if (!strcasecmp (a[1], "hid"))
286     {
287       localHLR = Standard_True;
288       localHid = Standard_True;
289     }
290     else if (!strcasecmp (a[1], "norg1"))
291     {
292       localRg1 = Standard_False;
293       localRgN = Standard_False;
294     }
295     else if (!strcasecmp (a[1], "rg1"))
296     {
297       localHLR = Standard_True;
298       localRg1 = Standard_True;
299       localRgN = Standard_False;
300     }
301     else if (!strcasecmp (a[1], "norgn"))
302     {
303       localRgN = Standard_False;
304     }
305     else if (!strcasecmp (a[1], "rgn"))
306     {
307       localHLR = Standard_True;
308       localRg1 = Standard_True;
309       localRgN = Standard_True;
310     }
311     else if (!strcasecmp (a[1], "ang"))
312     {
313       Standard_Real ang = Draw::Atof (a[2]);
314       localAng = ang * M_PI / 180;
315     }
316     else
317     {
318       di << "Syntax error";
319       return 1;
320     }
321
322     S->DisplayHLR (localHLR, localRg1, localRgN, localHid, localAng);
323   }
324   dout.RepaintAll();
325   return 0;
326 }
327
328
329 //=======================================================================
330 // dispor, dispcon
331 //=======================================================================
332
333 static Standard_Integer dispor (Draw_Interpretor&, Standard_Integer n, const char** a)
334 {
335   Standard_Boolean d = !strcasecmp(a[0],"vori");
336   if (d)
337   {
338     DBRep_WriteColorOrientation();
339   }
340
341   for (Standard_Integer i = 1; i < n; i++)
342   {
343     Handle(Draw_Drawable3D) d1 = Draw::Get (a[i]);
344     if (Handle(DBRep_DrawableShape) d2 = Handle(DBRep_DrawableShape)::DownCast(d1))
345     {
346       d2->DisplayOrientation (d);
347       Draw::Repaint();
348     }
349   }
350   return 0;
351 }
352
353 //=======================================================================
354 // discretisation
355 //=======================================================================
356
357 static Standard_Integer discretisation(Draw_Interpretor& di, Standard_Integer n, const char** a)
358 {
359   DBRep_Params& aParams = DBRep::Parameters();
360   if (n <= 1)
361   {
362     di << "Current number of points : "<< aParams.Discretization <<"\n";
363   }
364   else
365   {
366     aParams.Discretization = Draw::Atoi(a[1]);
367   }
368   return 0;
369 }
370
371
372 //=======================================================================
373 // triangles
374 //=======================================================================
375
376 static Standard_Integer triangles(Draw_Interpretor&, Standard_Integer n, const char** a)
377 {
378   DBRep_Params& aParams = DBRep::Parameters();
379   if (n < 1)
380   {
381     return 1;
382   }
383   if(n == 1)
384   {
385     aParams.DispTriangles = !aParams.DispTriangles;
386   }
387   else
388   {
389     for (Standard_Integer i = 1; i <= n-1; i++)
390     {
391       Handle(Draw_Drawable3D) d1 = Draw::Get(a[i]);
392       if (Handle(DBRep_DrawableShape) d2 = Handle(DBRep_DrawableShape)::DownCast(d1))
393       {
394         d2->DisplayTriangulation(!(d2->DisplayTriangulation()));
395       }
396     }
397   }
398
399   Draw::Repaint();
400   return 0;
401 }
402
403 //=======================================================================
404 // tclean
405 //=======================================================================
406
407 static Standard_Integer tclean(Draw_Interpretor& di,
408   Standard_Integer n, const char** a)
409 {
410   Standard_Boolean toRemoveGeometry = Standard_False;
411   Standard_Boolean isForceClean = Standard_False;
412
413   if (n <= 1)
414   {
415     di.PrintHelp(a[0]);
416     return 1;
417   }
418   TopoDS_Compound aCompound;
419   BRep_Builder().MakeCompound(aCompound);
420   for (Standard_Integer anArgIter = 1; anArgIter < n; ++anArgIter)
421   {
422     if (strcmp(a[anArgIter], "-geom") == 0)
423     {
424       toRemoveGeometry = Standard_True;
425     }
426     else if (strcmp(a[anArgIter], "-force") == 0)
427     {
428       isForceClean = Standard_True;
429     }
430     else
431     {
432       TopoDS_Shape aShape = DBRep::Get(a[anArgIter]);
433       if (aShape.IsNull())
434       {
435         di << "Syntax error : NULL shape '"<< a[anArgIter] << "'";
436         return 1;
437       }
438       BRep_Builder().Add(aCompound, aShape);
439     }
440   }
441   if (aCompound.NbChildren() == 0)
442   {
443     di << "Syntax error : wrong number of arguments";
444     di.PrintHelp(a[0]);
445     return 1;
446   }
447   if (isForceClean && toRemoveGeometry)
448   {
449     di << "Syntax error: wrong usage of arguments: do not use 'force' and 'geom' flags together";
450     return 1;
451   }
452
453   if (toRemoveGeometry)
454     BRepTools::CleanGeometry(aCompound);
455   else
456     BRepTools::Clean(aCompound, isForceClean);
457   return 0;
458 }
459
460 //=======================================================================
461 // polygons
462 //=======================================================================
463
464 static Standard_Integer polygons(Draw_Interpretor&, Standard_Integer n, const char** a)
465 {
466   DBRep_Params& aParams = DBRep::Parameters();
467   if (n < 1)
468   {
469     return 1;
470   }
471   if (n == 1)
472   {
473     aParams.DisplayPolygons = !aParams.DisplayPolygons;
474   }
475   else
476   {
477     for (Standard_Integer i = 1; i <= n-1; i++)
478     {
479       Handle(Draw_Drawable3D) d1 = Draw::Get(a[i]);
480       if (Handle(DBRep_DrawableShape) d2 = Handle(DBRep_DrawableShape)::DownCast(d1))
481       {
482         d2->DisplayPolygons(!(d2->DisplayPolygons()));
483       }
484     }
485   }
486   Draw::Repaint();
487   return 0;
488 }
489
490
491 //=======================================================================
492 // compound
493 //=======================================================================
494
495 static Standard_Integer compound(Draw_Interpretor& ,
496                                  Standard_Integer n, const char** a)
497 {
498   if (n <= 1) return 1;
499   BRep_Builder B;
500   TopoDS_Compound C;
501   B.MakeCompound(C);
502   for (Standard_Integer i = 1; i < n-1; i++) {
503     TopoDS_Shape S2 = DBRep::Get(a[i]);
504     if (!S2.IsNull()) B.Add(C,S2);
505   }
506   DBRep::Set(a[n-1],C);
507   return 0;
508 }
509
510 //=======================================================================
511 // emptycopy
512 //=======================================================================
513
514 static Standard_Integer emptycopy(Draw_Interpretor& ,
515                                   Standard_Integer n, const char** a)
516 {
517   if (n <= 1) return 1;
518   TopoDS_Shape S = DBRep::Get(a[(n == 2) ? 1 : 2]);
519   if (S.IsNull()) return 1;
520   S.EmptyCopy();
521   DBRep::Set(a[1],S);
522   return 0;
523 }
524
525 //=======================================================================
526 // add
527 //=======================================================================
528
529 static Standard_Integer add(Draw_Interpretor& ,
530                             Standard_Integer n, const char** a)
531 {
532   if (n < 3) return 1;
533   BRep_Builder B;
534   TopoDS_Shape S1 = DBRep::Get(a[1]);
535   if (S1.IsNull()) return 1;
536   TopoDS_Shape S2 = DBRep::Get(a[2]);
537   if (S2.IsNull()) return 1;
538   B.Add(S2,S1);
539   DBRep::Set(a[2],S2);
540   return 0;
541 }
542
543 //=======================================================================
544 // explode
545 //=======================================================================
546
547 static Standard_Integer explode(Draw_Interpretor& di,
548                                 Standard_Integer n, const char** a)
549 {
550   if (n <= 1) return 1;
551   TopoDS_Shape S = DBRep::Get(a[1]);
552   if (S.IsNull()) return 0;
553   char newname[1024];
554   strcpy(newname,a[1]);
555   char* p = newname;
556   while (*p != '\0') p++;
557   *p = '_';
558   p++;
559   Standard_Integer i = 0;
560   if (n == 2) {
561     TopoDS_Iterator itr(S);
562     while (itr.More()) {
563       i++;
564       Sprintf(p,"%d",i);
565       DBRep::Set(newname,itr.Value());
566       di.AppendElement(newname);
567       itr.Next();
568     }
569   }
570   else {
571     // explode a type
572     TopAbs_ShapeEnum typ;
573     switch (a[2][0]) {
574       
575     case 'C' :
576     case 'c' :
577       if ((a[2][1] == 'd')||(a[2][1] == 'D')) 
578         typ = TopAbs_COMPOUND;
579       else
580         typ = TopAbs_COMPSOLID;
581       break;
582       
583     case 'S' :
584     case 's' :
585       if ((a[2][1] == 'O')||(a[2][1] == 'o')) 
586         typ = TopAbs_SOLID;
587       else if ((a[2][1] == 'H')||(a[2][1] == 'h')) 
588         typ = TopAbs_SHELL;
589       else
590         return 1;
591       break;
592       
593     case 'F' :
594     case 'f' :
595       typ = TopAbs_FACE;
596       break;
597       
598     case 'W' :
599     case 'w' :
600       typ = TopAbs_WIRE;
601       break;
602       
603     case 'E' :
604     case 'e' :
605       typ = TopAbs_EDGE;
606       break;
607       
608     case 'V' :
609     case 'v' :
610       typ = TopAbs_VERTEX;
611       break;
612       
613       default :
614         return 1;
615     }
616     
617     TopTools_MapOfShape M;
618     M.Add(S);
619     TopExp_Explorer ex(S,typ);
620     for (; ex.More(); ex.Next()) {
621       const TopoDS_Shape& Sx = ex.Current();
622       Standard_Boolean added = M.Add(Sx);
623       if (added) {
624         i++;
625         Sprintf(p,"%d",i);
626         DBRep::Set(newname,Sx);
627         di.AppendElement(newname);
628       }
629     }
630   }
631   return 0;
632 }
633
634 //=======================================================================
635 // nexplode : stable numbered explode (from Serguey Nizhny)
636 //=======================================================================
637
638 static Standard_Integer nexplode(Draw_Interpretor& di, 
639                                  Standard_Integer n, const char** a)
640
641   if (n <= 2) return 1;
642   TopoDS_Shape S = DBRep::Get(a[1]);
643   if (S.IsNull()) return 0;
644   char newname[1024];
645   strcpy(newname,a[1]);
646   char* p = newname;
647   while (*p != '\0') p++;
648   *p = '_';
649   p++;
650   TopAbs_ShapeEnum typ;
651   // explode a type
652   switch (a[2][0]) {    
653   case 'F' :
654   case 'f' :
655     typ = TopAbs_FACE;
656     break;
657     
658   case 'E' :
659   case 'e' :
660     typ = TopAbs_EDGE;
661     break;
662     
663   case 'V' :
664   case 'v' :
665     typ = TopAbs_VERTEX;
666     break;
667     
668     default :
669       return 1;
670   }
671   TopTools_IndexedMapOfShape IMOStmp;
672   TopTools_MapOfShape MShape;
673   IMOStmp.Add(S);
674   TopExp::MapShapes(S,typ,IMOStmp);
675   TopExp_Explorer Exp(S,typ);
676   Standard_Integer MaxShapes, Index = 0;
677   MaxShapes = IMOStmp.Extent()-1;
678   TopTools_Array1OfShape aShapes(1,MaxShapes);
679   
680   // explode 
681   while (Exp.More()) {
682     if (MShape.Add(Exp.Current())) {
683       Index++;
684       aShapes.SetValue(Index,Exp.Current());
685     }
686     Exp.Next();
687   }
688   //
689   TColStd_Array1OfInteger OrderInd(1,MaxShapes);
690   gp_Pnt GPoint;
691   GProp_GProps GPr;
692   Standard_Integer aTemp;
693   TColStd_Array1OfReal MidXYZ(1,MaxShapes); //X,Y,Z;
694   Standard_Boolean NoSort = Standard_True;
695   //
696   // Computing of CentreOfMass for edge and face
697   // and for vertex use its point
698   for (Index=1; Index <= MaxShapes; Index++) {
699     OrderInd.SetValue(Index,Index);
700     const TopoDS_Shape& aS = aShapes(Index);
701     if (aS.ShapeType() != TopAbs_VERTEX) {
702       BRepGProp::LinearProperties(aS, GPr);
703       GPoint = GPr.CentreOfMass();
704     }
705     else {
706       GPoint = BRep_Tool::Pnt(TopoDS::Vertex(aS));
707     }
708     MidXYZ.SetValue(Index, GPoint.X()*999 + GPoint.Y()*99 +
709                     GPoint.Z()*0.9);
710   }   
711   // Sorting
712   while(NoSort) {
713     NoSort = Standard_False;
714     for (Index=1; Index < MaxShapes; Index++) {
715       if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1))) {
716         aTemp = OrderInd(Index);
717         OrderInd(Index) = OrderInd(Index+1);
718         OrderInd(Index+1) = aTemp;
719         NoSort = Standard_True;
720       }
721     }
722   }
723   // Check of equality of MidXYZ
724   for (Index=1; Index < MaxShapes; Index++) {
725     if (MidXYZ(OrderInd(Index+1)) == MidXYZ(OrderInd(Index)))
726       di<<"Warning! For this shape the results may be incorrect.\n";
727   }
728   
729   for (Index=1 ;Index <= MaxShapes; Index++) {
730     Sprintf(p,"%d",Index);
731     DBRep::Set(newname,aShapes(OrderInd(Index)));
732     di.AppendElement(newname);    
733   }
734   
735   return 0;
736 }
737
738 //=======================================================================
739 // exwire
740 //=======================================================================
741
742 static Standard_Integer exwire(Draw_Interpretor& ,
743                                Standard_Integer n, const char** a)
744 {
745   if (n <= 1) return 1;
746   TopoDS_Shape S = DBRep::Get(a[1]);
747   if (S.IsNull()) return 0;
748   if (S.ShapeType() != TopAbs_WIRE) return 0;
749   char newname[1024];
750   strcpy(newname,a[1]);
751   char* p = newname;
752   while (*p != '\0') p++;
753   *p = '_';
754   p++;
755   Standard_Integer i = 0;
756   BRepTools_WireExplorer ex(TopoDS::Wire(S));
757   while (ex.More()) {
758     i++;
759     Sprintf(p,"%d",i);
760     DBRep::Set(newname,ex.Current());
761     ex.Next();
762   }
763   return 0;
764 }
765
766 //=======================================================================
767 // invert
768 //=======================================================================
769
770 static Standard_Integer invert(Draw_Interpretor& ,
771                                Standard_Integer n, const char** a)
772 {
773   if (n <= 1) return 1;
774   TopoDS_Shape S = DBRep::Get(a[1]);
775   if (S.IsNull()) return 0;
776   
777   BRep_Builder B;
778   TopoDS_Shape NS = S.EmptyCopied();
779   NS.Closed (S.Closed());
780
781   TopoDS_Iterator itr(S);
782   while (itr.More()) {
783     B.Add(NS,itr.Value().Reversed());
784     itr.Next();
785   }
786   DBRep::Set(a[1],NS);
787   
788   return 0;
789 }
790
791 //=======================================================================
792 // orientation, reverse, complement
793 //=======================================================================
794
795 static Standard_Integer orientation(Draw_Interpretor& ,
796                                     Standard_Integer n, const char** a)
797 {
798   if (n <= 1) return 1;
799   Standard_Integer cas = 0;
800   TopAbs_Orientation ori=TopAbs_FORWARD;
801   Standard_Integer last = n;
802   if (!strcasecmp(a[0],"orientation")) {
803     if (n <= 2) return 1;
804     last--;
805     switch (*a[n-1]) {
806         
807       case 'F' :
808         ori = TopAbs_FORWARD;
809         break;
810         
811       case 'R' :
812         ori = TopAbs_REVERSED;
813         break;
814         
815       case 'I' :
816         ori = TopAbs_INTERNAL;
817         break;
818         
819       case 'E' :
820         ori = TopAbs_EXTERNAL;
821         break;
822       }
823   }
824
825   else if (!strcasecmp(a[0],"treverse")) {
826     cas = -1;
827   }
828
829   else if (!strcasecmp(a[0],"complement")) {
830     cas = -2;
831   }
832
833   for (Standard_Integer i = 1; i < last; i++) {
834     TopoDS_Shape S = DBRep::Get(a[i]);
835     if (!S.IsNull()) {
836       if (cas == -2)
837         S.Complement();
838       else if (cas == -1)
839         S.Reverse();
840       else
841         S.Orientation(ori);
842       DBRep::Set(a[i],S);
843     }
844   }
845   return 0;
846 }
847
848 #include <TCollection_AsciiString.hxx>
849
850 //=======================================================================
851 // numshapes same as nbshapes but the output is cout
852 //=======================================================================
853
854 static Standard_Integer numshapes(Draw_Interpretor& di,
855                                  Standard_Integer n, const char** a)
856 {
857   if (n < 2) return 1;
858
859   Standard_Integer i;
860   TopExp_Explorer ex;
861   for (i = 1; i < n; i++) {
862     TopoDS_Shape S = DBRep::Get(a[i]);
863     if (!S.IsNull()) {
864       BRepTools_ShapeSet BS;
865       BS.Add(S);
866       di <<"Number of shapes in "<<a[i]<<"\n";
867       TCollection_AsciiString Astr; 
868       BS.DumpExtent(Astr);
869       di <<Astr.ToCString();
870       di << "\n" ;
871     }
872   }
873
874   return 0;
875 }
876
877 //=======================================================================
878 // function : DumpExtent
879 // purpose  : Dumps the number of sub-shapes in <aStr>.
880 //=======================================================================
881 static void DumpExtent(const TopoDS_Shape& aS,
882                        TCollection_AsciiString& aStr)
883 {
884   const int aNbTypes=8;
885   const char *pNames[aNbTypes+1]={
886     " SHAPE     : ",
887     " COMPOUND  : ",
888     " COMPSOLID : ",
889     " SOLID     : ",
890     " SHELL     : ",
891     " FACE      : ",
892     " WIRE      : ",
893     " EDGE      : ",
894     " VERTEX    : "
895   };
896   Standard_Integer i, aNb, aNbSh;
897   TopAbs_ShapeEnum aType;
898   TopTools_IndexedMapOfShape aM;
899   //
900   aNbSh=0;
901   //
902   for (i=aNbTypes-1; i>=0; --i) {
903     aM.Clear();
904     aType=(TopAbs_ShapeEnum)i;
905     TopExp::MapShapes(aS, aType, aM);
906     aNb=aM.Extent();
907     aStr=aStr+pNames[i+1]+TCollection_AsciiString(aNb)+"\n";
908     aNbSh+=aNb;
909   }
910   aStr=aStr+pNames[0]+TCollection_AsciiString(aNbSh)+"\n";
911 }
912
913 //=======================================================================
914 // nbshapes
915 //=======================================================================
916
917 static Standard_Integer nbshapes(Draw_Interpretor& di,
918                                  Standard_Integer n, const char** a)
919 {
920   if (n < 2) return 1;
921
922   Standard_Integer i;
923   Standard_Boolean aTotal;
924   TopExp_Explorer ex;
925   //
926   aTotal = !strcmp(a[n-1], "-t") ? Standard_True : Standard_False;
927   //
928   for (i = 1; i < n; i++) {
929     TopoDS_Shape S = DBRep::Get(a[i]);
930     if (!S.IsNull()) {
931       di<<"Number of shapes in "<<a[i]<<"\n";
932       TCollection_AsciiString Astr; 
933       if (aTotal) {
934         DumpExtent(S, Astr);
935       } else {
936         BRepTools_ShapeSet BS;
937         BS.Add(S);
938         BS.DumpExtent(Astr);
939       }
940       di<<Astr.ToCString();
941     }
942   }
943
944   return 0;
945 }
946
947 //=======================================================================
948 // 
949 //=======================================================================
950
951 static Standard_Integer countshapes(Draw_Interpretor& di,
952                                     Standard_Integer n, const char** a)
953 {
954   if (n < 2) return 1;
955
956   Standard_Integer i;
957   TopExp_Explorer ex;
958   for (i = 1; i < n; i++) {
959     TopoDS_Shape Sh = DBRep::Get(a[i]);
960     Standard_Integer nbElem = 0;
961     if (!Sh.IsNull()) {
962       di <<"Number of shapes in "<<a[i]<<"\n";
963       TopTools_MapOfShape M;
964
965       for (ex.Init (Sh,TopAbs_VERTEX); ex.More(); ex.Next()) {
966         const TopoDS_Shape& S = ex.Current();
967         Standard_Boolean added = M.Add(S);
968         if (added) {
969           nbElem++;
970         }
971       }
972       di << " VERTEX     : " << nbElem << "\n";
973       nbElem = 0;
974     
975       for (ex.Init (Sh,TopAbs_EDGE); ex.More(); ex.Next()) {
976         const TopoDS_Shape& S = ex.Current();
977         Standard_Boolean added = M.Add(S);
978         if (added) {
979           nbElem++;
980         }
981       }
982       di << " EDGE       : " << nbElem << "\n";
983       nbElem = 0;
984
985       for (ex.Init (Sh,TopAbs_WIRE); ex.More(); ex.Next()) {
986         const TopoDS_Shape& S = ex.Current();
987         Standard_Boolean added = M.Add(S);
988         if (added) {
989           nbElem++;
990         }
991       }
992       di << " WIRE       : " << nbElem << "\n";
993       nbElem = 0;
994
995       for (ex.Init (Sh,TopAbs_FACE); ex.More(); ex.Next()) {
996         const TopoDS_Shape& S = ex.Current();
997         Standard_Boolean added = M.Add(S);
998         if (added) {
999           nbElem++;
1000         }
1001       }
1002       di << " FACE       : " << nbElem << "\n";
1003       nbElem = 0;
1004
1005       for (ex.Init (Sh,TopAbs_SHELL); ex.More(); ex.Next()) {
1006         const TopoDS_Shape& S = ex.Current();
1007         Standard_Boolean added = M.Add(S);
1008         if (added) {
1009           nbElem++;
1010         }
1011       }
1012       di << " SHELL      : " << nbElem << "\n";
1013       nbElem = 0;
1014
1015       for (ex.Init (Sh,TopAbs_SOLID); ex.More(); ex.Next()) {
1016         const TopoDS_Shape& S = ex.Current();
1017         Standard_Boolean added = M.Add(S);
1018         if (added) {
1019           nbElem++;
1020         }
1021       }
1022       di << " SOLID      : " << nbElem << "\n";
1023       nbElem = 0;
1024
1025       for (ex.Init (Sh,TopAbs_COMPSOLID); ex.More(); ex.Next()) {
1026         const TopoDS_Shape& S = ex.Current();
1027         Standard_Boolean added = M.Add(S);
1028         if (added) {
1029           nbElem++;
1030         }
1031       }
1032       di << " COMPSOLID  : " << nbElem << "\n";
1033       nbElem = 0;
1034       
1035       for (ex.Init (Sh,TopAbs_COMPOUND); ex.More(); ex.Next()) {
1036         const TopoDS_Shape& S = ex.Current();
1037         Standard_Boolean added = M.Add(S);
1038         if (added) {
1039           nbElem++;
1040         }
1041       }
1042       di << " COMPOUND   : " << nbElem << "\n";
1043       nbElem = 0;
1044
1045       di << " SHAPE      : " << M.Extent() << "\n";
1046       di << "\n" ;
1047     }
1048 }
1049
1050   return 0;
1051 }
1052
1053 //=======================================================================
1054 // 
1055 //=======================================================================
1056 void setProp(TopoDS_Shape Sh, const char** a, Standard_Integer n)
1057 {
1058   Standard_Integer i;
1059   for(i = 2; i < n; i++) {
1060     if (strstr ( a[i], "free" )) {
1061       if(a[i][0] == '-') {
1062         Sh.Free(Standard_False);
1063       }
1064       else {
1065         Sh.Free(Standard_True);
1066       }
1067     }
1068     if (strstr ( a[i], "modified" )) {
1069       if(a[i][0] == '-') {
1070         Sh.Modified(Standard_False);
1071       }
1072       else {
1073         Sh.Modified(Standard_True);
1074       }
1075     }
1076     if (strstr ( a[i], "checked" )) {
1077       if(a[i][0] == '-') {
1078         Sh.Checked(Standard_False);
1079       }
1080       else {
1081         Sh.Checked(Standard_True);
1082       }
1083     }
1084     if (strstr ( a[i], "orientable" )) {
1085       if(a[i][0] == '-') {
1086         Sh.Orientable(Standard_False);
1087       }
1088       else {
1089         Sh.Orientable(Standard_True);
1090       }
1091     }
1092     if (strstr ( a[i], "closed" )) {
1093       if(a[i][0] == '-') {
1094         Sh.Closed(Standard_False);
1095       }
1096       else {
1097         Sh.Closed(Standard_True);
1098       }
1099     }
1100     if (strstr ( a[i], "infinite" )) {
1101       if(a[i][0] == '-') {
1102         Sh.Infinite(Standard_False);
1103       }
1104       else {
1105         Sh.Infinite(Standard_True);
1106       }
1107     }
1108     if (strstr ( a[i], "convex" )) {
1109       if(a[i][0] == '-') {
1110         Sh.Convex(Standard_False);
1111       }
1112       else {
1113         Sh.Convex(Standard_True);
1114       }
1115     }
1116     if (strstr ( a[i], "locked" )) {
1117       if(a[i][0] == '-') {
1118         Sh.Locked(Standard_False);
1119       }
1120       else {
1121         Sh.Locked(Standard_True);
1122       }
1123     }
1124   }
1125 }
1126
1127 //=======================================================================
1128 // 
1129 //=======================================================================
1130 static Standard_Integer setFlags(Draw_Interpretor& ,
1131                                     Standard_Integer n, const char** a)
1132 {
1133   if (n < 3) return 1;
1134
1135   TopExp_Explorer ex;
1136   TopoDS_Shape Sh = DBRep::Get(a[1]);
1137
1138   if (Sh.IsNull()) return 1;
1139
1140   setProp(Sh, a, n);
1141   for (ex.Init (Sh,TopAbs_VERTEX); ex.More(); ex.Next()) {
1142     TopoDS_Shape S = ex.Current();
1143     setProp(S, a, n);
1144   }
1145
1146   for (ex.Init (Sh,TopAbs_EDGE); ex.More(); ex.Next()) {
1147     TopoDS_Shape S = ex.Current();
1148     setProp(S, a, n);
1149   }
1150
1151   for (ex.Init (Sh,TopAbs_FACE); ex.More(); ex.Next()) {
1152     TopoDS_Shape S = ex.Current();
1153     setProp(S, a, n);
1154   }
1155
1156   return 0;
1157 }
1158
1159 //=======================================================================
1160 //memory management
1161 //=======================================================================
1162 static Standard_Integer purgemmgt(Draw_Interpretor&, Standard_Integer , const char**) {
1163   Standard::Purge();
1164   return 0;
1165 }
1166 //=======================================================================
1167
1168 //=======================================================================
1169 // check
1170 //=======================================================================
1171
1172 static Standard_Integer check(Draw_Interpretor& ,
1173                               Standard_Integer n, const char** a)
1174 {
1175   if (n < 2) return 1;
1176
1177   Standard_Integer i;
1178   TopExp_Explorer ex;
1179   for (i = 1; i < n; i++) {
1180     TopoDS_Shape S = DBRep::Get(a[i]);
1181     TopoDS_Shape C;
1182     if (S.IsNull()) continue;
1183     for (ex.Init(S,TopAbs_FACE);ex.More();ex.Next()) {
1184       C = ex.Current();
1185       C.Checked(Standard_False);
1186       BRepTools::Update(C);
1187     }
1188   }
1189
1190   return 0;
1191 }
1192
1193 //=======================================================================
1194 // normals
1195 //=======================================================================
1196 static Standard_Integer normals (Draw_Interpretor& theDI,
1197                                  Standard_Integer  theArgNum,
1198                                  const char**      theArgs)
1199 {
1200   if (theArgNum < 2)
1201   {
1202     std::cout << "Syntax error: wrong number of arguments!\n";
1203     theDI.PrintHelp (theArgs[0]);
1204     return 1;
1205   }
1206
1207   TopoDS_Shape aShape = DBRep::Get (theArgs[1]);
1208   if (aShape.IsNull())
1209   {
1210     std::cout << "Error: shape with name " << theArgs[1] << " is not found\n";
1211     return 1;
1212   }
1213
1214   Standard_Boolean toUseMesh = Standard_False;
1215   Standard_Real    aLength   = 10.0;
1216   Standard_Integer aNbAlongU = 1, aNbAlongV = 1;
1217   Standard_Boolean bPrint = Standard_False;
1218   for (Standard_Integer anArgIter = 2; anArgIter< theArgNum; ++anArgIter)
1219   {
1220     TCollection_AsciiString aParam (theArgs[anArgIter]);
1221     aParam.LowerCase();
1222     if (anArgIter == 2
1223      && aParam.IsRealValue())
1224     {
1225       aLength = aParam.RealValue();
1226       if (Abs (aLength) <= gp::Resolution())
1227       {
1228         std::cout << "Syntax error: length should not be zero\n";
1229         return 1;
1230       }
1231     }
1232     else if (aParam == "-usemesh"
1233           || aParam == "-mesh")
1234     {
1235       toUseMesh = Standard_True;
1236     }
1237     else if (aParam == "-length"
1238           || aParam == "-len")
1239     {
1240       ++anArgIter;
1241       aLength = anArgIter < theArgNum ? Draw::Atof(theArgs[anArgIter]) : 0.0;
1242       if (Abs(aLength) <= gp::Resolution())
1243       {
1244         std::cout << "Syntax error: length should not be zero\n";
1245         return 1;
1246       }
1247     }
1248     else if (aParam == "-nbalongu"
1249           || aParam == "-nbu")
1250     {
1251       ++anArgIter;
1252       aNbAlongU = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
1253       if (aNbAlongU < 1)
1254       {
1255         std::cout << "Syntax error: NbAlongU should be >=1\n";
1256         return 1;
1257       }
1258     }
1259     else if (aParam == "-nbalongv"
1260           || aParam == "-nbv")
1261     {
1262       ++anArgIter;
1263       aNbAlongV = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
1264       if (aNbAlongV < 1)
1265       {
1266         std::cout << "Syntax error: NbAlongV should be >=1\n";
1267         return 1;
1268       }
1269     }
1270     else if (aParam == "-nbalong"
1271           || aParam == "-nbuv")
1272     {
1273       ++anArgIter;
1274       aNbAlongU = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
1275       aNbAlongV = aNbAlongU;
1276       if (aNbAlongU < 1)
1277       {
1278         std::cout << "Syntax error: NbAlong should be >=1\n";
1279         return 1;
1280       }
1281     }
1282     else if (aParam == "-print")
1283     {
1284       bPrint = Standard_True;
1285     }
1286     else
1287     {
1288       std::cout << "Syntax error: unknown argument '" << aParam << "'\n";
1289       return 1;
1290     }
1291   }
1292
1293   DBRep_WriteColorOrientation();
1294
1295   NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > aNormals;
1296   if (toUseMesh)
1297   {
1298     DBRep_DrawableShape::addMeshNormals (aNormals, aShape, aLength);
1299   }
1300   else
1301   {
1302     DBRep_DrawableShape::addSurfaceNormals (aNormals, aShape, aLength, aNbAlongU, aNbAlongV);
1303   }
1304
1305   for (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >::Iterator aFaceIt (aNormals); aFaceIt.More(); aFaceIt.Next())
1306   {
1307     Standard_Boolean bReverse = Standard_False;
1308     TopAbs_Orientation aFaceOri = aFaceIt.Key().Orientation();
1309     const Draw_Color aColor = DBRep_ColorOrientation (aFaceOri);
1310     if (aFaceOri == TopAbs_REVERSED)
1311       bReverse = Standard_True;
1312
1313     for (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >::Iterator aNormalsIt (aFaceIt.Value()); aNormalsIt.More(); aNormalsIt.Next())
1314     {
1315       const std::pair<gp_Pnt, gp_Pnt>& aVec = aNormalsIt.Value();
1316       Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(aVec.first, aVec.second, aColor);
1317       dout << aSeg;
1318       if (bPrint)
1319       {
1320         // Make the normal vector from the points
1321         gp_Vec aV(aVec.first, aVec.second);
1322         if (bReverse)
1323           aV.Reverse();
1324
1325         // Print values of the vector avoiding printing "-0" values
1326         theDI << "(" << (aV.X() == 0 ? 0 : aV.X()) << ", "
1327                      << (aV.Y() == 0 ? 0 : aV.Y()) << ", "
1328                      << (aV.Z() == 0 ? 0 : aV.Z()) << ")\n";
1329       }
1330     }
1331   }
1332
1333   return 0;
1334 }
1335
1336 //=======================================================================
1337 //function : Set
1338 //purpose  : 
1339 //=======================================================================
1340 void DBRep::Set (const Standard_CString theName, const TopoDS_Shape& theShape)
1341 {
1342   DBRep_Params& aParams = DBRep::Parameters();
1343   Handle(DBRep_DrawableShape) aDrawShape =
1344     new DBRep_DrawableShape (theShape, Draw_vert, Draw_jaune, Draw_rouge, Draw_bleu,
1345                              aParams.Size, aParams.NbIsos, aParams.Discretization);
1346   aDrawShape->DisplayTriangulation (aParams.DispTriangles);
1347   aDrawShape->DisplayPolygons (aParams.DisplayPolygons);
1348   aDrawShape->DisplayHLR (aParams.WithHLR, aParams.WithRg1, aParams.WithRgN, aParams.WithHid, aParams.HLRAngle);
1349   Draw::Set (theName, aDrawShape);
1350 }
1351 //=======================================================================
1352 //function : getShape
1353 //purpose  :
1354 //=======================================================================
1355 TopoDS_Shape DBRep::getShape (Standard_CString& theName,
1356                               TopAbs_ShapeEnum theType,
1357                               Standard_Boolean theToComplain)
1358 {
1359   const Standard_Boolean toPick = theName[0] == '.';
1360   Handle(DBRep_DrawableShape) aDrawable = Handle(DBRep_DrawableShape)::DownCast (Draw::Get (theName));
1361   if (aDrawable.IsNull())
1362   {
1363     return TopoDS_Shape();
1364   }
1365
1366   TopoDS_Shape aShape = aDrawable->Shape();
1367   if (theType != TopAbs_SHAPE
1368    && theType != aShape.ShapeType()
1369    && toPick)
1370   {
1371     // try to find prom pick
1372     Standard_Real u, v;
1373     DBRep_DrawableShape::LastPick (aShape, u, v);
1374   }
1375   if (theType != TopAbs_SHAPE
1376    && theType != aShape.ShapeType())
1377   {
1378     if (theToComplain)
1379     {
1380       std::cout << theName << " is not a ";
1381       TopAbs::Print (theType, std::cout);
1382       std::cout << " but a ";
1383       TopAbs::Print (aShape.ShapeType(), std::cout);
1384       std::cout << std::endl;
1385     }
1386     return TopoDS_Shape();
1387   }
1388   return aShape;
1389 }
1390
1391 static Standard_Integer XProgress (Draw_Interpretor& di, Standard_Integer argc, const char **argv)
1392 {
1393   for ( Standard_Integer i=1; i < argc; i++ )
1394   {
1395     Standard_Boolean turn = Standard_True;
1396     if ( argv[i][0] == '-' ) turn = Standard_False;
1397     else if ( argv[i][0] != '+' ) continue;
1398
1399     TCollection_AsciiString anArgCase (argv[i]);
1400     anArgCase.LowerCase();
1401     if ( argv[i][1] == 't' ) Draw_ProgressIndicator::DefaultTclMode() = turn;
1402     else if (argv[i][1] == 'c') Draw_ProgressIndicator::DefaultConsoleMode() = turn;
1403     else if ( argv[i][1] == 'g' ) Draw_ProgressIndicator::DefaultGraphMode() = turn;
1404     else if ( ! strcmp ( argv[i], "-stop" ) && i+1 < argc )
1405     {
1406       Standard_Address aPtr = 0;
1407       if (sscanf (argv[++i], "%p", &aPtr) == 1)
1408         Draw_ProgressIndicator::StopIndicator() = aPtr;
1409       return 0;
1410     }
1411   }
1412   di << "Progress Indicator defaults: tcl mode is ";
1413   if ( Draw_ProgressIndicator::DefaultTclMode() ) {
1414     di<<"ON";
1415   } else {
1416     di<<"OFF";
1417   }
1418   di<<", console mode is ";
1419   if (Draw_ProgressIndicator::DefaultConsoleMode()) {
1420     di << "ON";
1421   }
1422   else {
1423     di << "OFF";
1424   }
1425   di << ", graphical mode is ";
1426   if ( Draw_ProgressIndicator::DefaultGraphMode() ) {
1427     di<<"ON";
1428   } else {
1429     di<<"OFF";
1430   }
1431   di<< "\n";
1432   return 0;
1433 }
1434
1435 //=======================================================================
1436 // writebrep
1437 //=======================================================================
1438 static Standard_Integer writebrep (Draw_Interpretor& theDI,
1439                                    Standard_Integer theNbArgs,
1440                                    const char** theArgVec)
1441 {
1442   Standard_Integer aVersion = -1;
1443   TCollection_AsciiString aShapeName, aFileName;
1444   TopoDS_Shape aShape;
1445   Standard_Boolean isBinaryFormat(Standard_False);
1446   Standard_Boolean isWithTriangles(Standard_True);
1447   Standard_Boolean isWithNormals(Standard_False);
1448   if (!strcasecmp (theArgVec[0], "binsave"))
1449   {
1450     isBinaryFormat = Standard_True;
1451   }
1452
1453   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
1454   {
1455     TCollection_AsciiString aParam (theArgVec[anArgIter]);
1456     aParam.LowerCase();
1457     if (aParam == "-binary")
1458     {
1459       isBinaryFormat = Standard_True;
1460       if (anArgIter + 1 < theNbArgs
1461        && Draw::ParseOnOff (theArgVec[anArgIter + 1], isBinaryFormat))
1462       {
1463         ++anArgIter;
1464       }
1465     }
1466     else if (aParam == "-version"
1467           && anArgIter + 1 < theNbArgs)
1468     {
1469       aVersion = Draw::Atoi (theArgVec[++anArgIter]);
1470       if (aVersion <= 0)
1471       {
1472         theDI << "Syntax error: unknown version";
1473         return 1;
1474       }
1475     }
1476     else if (aParam == "-notriangles"
1477           || aParam == "-triangles")
1478     {
1479       isWithTriangles = Standard_True;
1480       if (anArgIter + 1 < theNbArgs
1481        && Draw::ParseOnOff (theArgVec[anArgIter + 1], isWithTriangles))
1482       {
1483         ++anArgIter;
1484       }
1485       if (aParam == "-notriangles")
1486       {
1487         isWithTriangles = !isWithTriangles;
1488       }
1489     }
1490     else if (aParam == "-nonormals"
1491           || aParam == "-normals")
1492     {
1493       isWithNormals = Standard_True;
1494       if (anArgIter + 1 < theNbArgs
1495        && Draw::ParseOnOff (theArgVec[anArgIter + 1], isWithNormals))
1496       {
1497         ++anArgIter;
1498       }
1499       if (aParam == "-nonormals")
1500       {
1501         isWithNormals = !isWithNormals;
1502       }
1503     }
1504     else if (aShapeName.IsEmpty())
1505     {
1506       aShapeName = theArgVec[anArgIter];
1507       aShape = DBRep::Get (aShapeName);
1508       if (aShape.IsNull())
1509       {
1510         theDI << "Syntax error: " << aShapeName << " is not a shape";
1511         return 1;
1512       }
1513     }
1514     else if (aFileName.IsEmpty())
1515     {
1516       aFileName = theArgVec[anArgIter];
1517     }
1518     else
1519     {
1520       theDI << "Syntax error: unknown argument '" << aParam << "'";
1521       return 1;
1522     }
1523   }
1524   if (aFileName.IsEmpty())
1525   {
1526     theDI << "Syntax error: wrong number of arguments";
1527     return 1;
1528   }
1529
1530   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI);
1531   if (isBinaryFormat)
1532   {
1533     if (aVersion > BinTools_FormatVersion_VERSION_3)
1534     {
1535       theDI << "Syntax error: unknown format version";
1536       return 1;
1537     }
1538
1539     BinTools_FormatVersion aBinToolsVersion = aVersion > 0
1540                                             ? static_cast<BinTools_FormatVersion> (aVersion)
1541                                             : BinTools_FormatVersion_CURRENT;
1542     if (!BinTools::Write (aShape, aFileName.ToCString(), isWithTriangles, isWithNormals, aBinToolsVersion, aProgress->Start()))
1543     {
1544       theDI << "Cannot write to the file " << aFileName;
1545       return 1;
1546     }
1547   }
1548   else
1549   {
1550     if (aVersion > TopTools_FormatVersion_VERSION_2)
1551     {
1552       theDI << "Syntax error: unknown format version";
1553       return 1;
1554     }
1555
1556     TopTools_FormatVersion aTopToolsVersion = aVersion > 0
1557                                             ? static_cast<TopTools_FormatVersion> (aVersion)
1558                                             : TopTools_FormatVersion_CURRENT;
1559     if (!BRepTools::Write (aShape, aFileName.ToCString(), isWithTriangles, isWithNormals, aTopToolsVersion, aProgress->Start()))
1560     {
1561       theDI << "Cannot write to the file " << aFileName;
1562       return 1;
1563     }
1564   }
1565   theDI << aShapeName;
1566   return 0;
1567 }
1568
1569 //=======================================================================
1570 // readbrep
1571 //=======================================================================
1572 static Standard_Integer readbrep (Draw_Interpretor& theDI,
1573                                   Standard_Integer theNbArgs,
1574                                   const char** theArgVec)
1575 {
1576   if (theNbArgs != 3)
1577   {
1578     theDI << "Syntax error: wrong number of arguments";
1579     return 1;
1580   }
1581
1582   Standard_CString aFileName  = theArgVec[1];
1583   Standard_CString aShapeName = theArgVec[2];
1584   bool isBinaryFormat = true;
1585   {
1586     // probe file header to recognize format
1587     const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
1588     opencascade::std::shared_ptr<std::istream> aFile = aFileSystem->OpenIStream (aFileName, std::ios::in | std::ios::binary);
1589     if (aFile.get() == NULL)
1590     {
1591       theDI << "Error: cannot read the file '" << aFileName << "'";
1592       return 1;
1593     }
1594
1595     char aStringBuf[255] = {};
1596     aFile->read (aStringBuf, 255);
1597     if (aFile->fail())
1598     {
1599       theDI << "Error: cannot read the file '" << aFileName << "'";
1600       return 1;
1601     }
1602     isBinaryFormat = !(::strncmp (aStringBuf, "DBRep_DrawableShape", 19) == 0);
1603   }
1604
1605   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI);
1606   TopoDS_Shape aShape;
1607   if (isBinaryFormat)
1608   {
1609     if (!BinTools::Read (aShape, aFileName, aProgress->Start()))
1610     {
1611       theDI << "Error: cannot read from the file '" << aFileName << "'";
1612       return 1;
1613     }
1614   }
1615   else
1616   {
1617     if (!BRepTools::Read (aShape, aFileName, BRep_Builder(), aProgress->Start()))
1618     {
1619       theDI << "Error: cannot read from the file '" << aFileName << "'";
1620       return 1;
1621     }
1622   }
1623
1624   DBRep::Set (aShapeName, aShape);
1625   theDI << aShapeName;
1626   return 0;
1627 }
1628
1629 //=======================================================================
1630 // removeinternals
1631 //=======================================================================
1632 static Standard_Integer removeInternals (Draw_Interpretor& di,
1633                                          Standard_Integer n,
1634                                          const char** a)
1635 {
1636   if (n < 2)
1637   {
1638     di.PrintHelp (a[0]);
1639     return 1;
1640   }
1641
1642   TopoDS_Shape aShape = DBRep::Get (a[1]);
1643   if (aShape.IsNull())
1644   {
1645     di << a[1] << "is a null shape\n";
1646     return 1;
1647   }
1648
1649   Standard_Boolean isForce = Standard_False;
1650   if (n > 2)
1651   {
1652     isForce = (Draw::Atoi (a[2]) != 0);
1653   }
1654
1655   BRepTools::RemoveInternals (aShape, isForce);
1656
1657   DBRep::Set (a[1], aShape);
1658
1659   return 0;
1660 }
1661
1662 //=======================================================================
1663 //function : BasicCommands
1664 //purpose  : 
1665 //=======================================================================
1666
1667 static Standard_Boolean done = Standard_False;
1668 void  DBRep::BasicCommands(Draw_Interpretor& theCommands)
1669 {
1670   if (done) return;
1671   done = Standard_True;
1672   Draw::Commands(theCommands);
1673
1674   // Register save/restore tools
1675   DBRep_DrawableShape::RegisterFactory();
1676
1677   const char* g = "Basic shape commands";
1678
1679   theCommands.Add("isos","isos [name1 ...] [nbisos]",__FILE__,isos,g);
1680   theCommands.Add("hlr" ,"[no]hlr, rg1, rgn, hid, ang",__FILE__,hlr ,g);
1681   theCommands.Add("vori","vori [name1 ...], edges are colored by orientation (see vconn)",__FILE__,dispor,g);
1682   theCommands.Add("triangles", "triangles [name1]..., display triangles of shapes if exists",__FILE__, triangles, g);
1683   theCommands.Add("tclean", "tclean [-force] [-geom] [name1]..., depending on using or not key -geom, \n" 
1684                    "\t\t -geom  : erase geometry\n"
1685                    "\t\t          if [-geom] is omitted - erase triangulations and \n"
1686                    "\t\t          polygons on triangulations from shapes \n"
1687                    "\t\t -force : force delete all representations not relevant to the given shape \n",
1688                     __FILE__, tclean, g); 
1689   theCommands.Add("polygons", "polygons [name1]..., display polygons of shapes if exists",__FILE__, polygons, g);
1690   theCommands.Add("vconn","vconn [name1 ...] , edges are colored by number of faces (see vori)",__FILE__,dispor,g);
1691   theCommands.Add("discretisation","discretisation [nbpoints]",__FILE__,discretisation,g);
1692   theCommands.Add("compound","compound [name1 name2 ..] compound",__FILE__,compound,g);
1693   theCommands.Add("add",
1694                   "add what where"
1695                   "\n  adds shape \"what\" to shape \"where\" ",
1696                   __FILE__,add,g);
1697   theCommands.Add("explode","explode name [Cd/C/So/Sh/F/W/E/V]",__FILE__,explode,g);
1698   theCommands.Add("nexplode","stable numbered explode for vertex, edge and face: nexplode name [V/E/F]",__FILE__,nexplode,g);
1699   theCommands.Add("exwire","exwire wirename",__FILE__,exwire,g);
1700   theCommands.Add("emptycopy","emptycopy [copyshape] originalshape",__FILE__,emptycopy,g);
1701   theCommands.Add("check","check shape1 shape2 ...",__FILE__,check,g);
1702
1703   theCommands.Add("orientation","orientation name1 name2.. F/R/E/I",__FILE__,orientation,g);
1704   theCommands.Add("treverse","treverse name1 name2 ...",__FILE__,orientation,g);
1705   theCommands.Add("complement","complement name1 name2 ...",__FILE__,orientation,g);
1706   theCommands.Add("invert","invert name, reverse subshapes",__FILE__,invert,g);
1707   theCommands.Add("normals","normals shape [Length {10}] [-NbAlongU {1}] [-NbAlongV {1}] [-UseMesh] [-print], display normals",__FILE__,normals,g);
1708   theCommands.Add("nbshapes",
1709                   "\n nbshapes s - shows the number of sub-shapes in <s>;\n nbshapes s -t - shows the number of sub-shapes in <s> counting the same sub-shapes with different location as different sub-shapes.",
1710                   __FILE__,nbshapes,g);
1711   theCommands.Add("numshapes","numshapes s; size of shape",__FILE__,numshapes,g);
1712   theCommands.Add("countshapes","countshapes s; count of shape",__FILE__,countshapes,g);
1713   theCommands.Add("setflags",
1714                   "setflags shape_name flag1[flag2...]\n sets flags for shape(free, modified, checked, orientable, closed, infinite, convex, locked), for example <setflags a free> or <setflags a -free> if necessary unflag ",
1715                   __FILE__,setFlags,g);
1716
1717 //  theCommands.Add("dumpmmgt",
1718 //                "dump le contenu du gestionnaire de memoire",__FILE__,dumpmmgt,g);
1719   theCommands.Add("purgemmgt",
1720                   "returns the free memory from the system to the memory manager",
1721                   __FILE__,purgemmgt,g);
1722   
1723   // Add command for DRAW-specific ProgressIndicator
1724   theCommands.Add ( "XProgress",
1725                     "XProgress [+|-t] [+|-c] [+|-g]"
1726                     "\n\t\t The options are:"
1727                     "\n\t\t   +|-t :  switch on/off output to tcl of Progress Indicator"
1728                     "\n\t\t   +|-c :  switch on/off output to cout of Progress Indicator"
1729                     "\n\t\t   +|-g :  switch on/off graphical mode of Progress Indicator",
1730                     XProgress,"DE: General");
1731   theCommands.Add("writebrep",
1732                   "writebrep shape filename [-binary=off] [-version Version=4] [-noTriangles=off]"
1733                   "\n\t\t: Save the shape in the ASCII (default) or binary format file."
1734                   "\n\t\t:  -binary  write into the binary format (ASCII when unspecified)"
1735                   "\n\t\t:  -version a number of format version to save;"
1736                   "\n\t\t:           ASCII  versions: 1, 2 and 3    (3 for ASCII  when unspecified);"
1737                   "\n\t\t:           Binary versions: 1, 2, 3 and 4 (4 for Binary when unspecified)."
1738                   "\n\t\t:  -noTriangles skip triangulation data (OFF when unspecified)."
1739                   "\n\t\t:           Ignored (always written) if face defines only triangulation (no surface).",
1740                   __FILE__, writebrep, g);
1741   theCommands.Add("readbrep",
1742                   "readbrep filename shape"
1743                   "\n\t\t: Restore the shape from the binary or ASCII format file.",
1744                   __FILE__, readbrep, g);
1745   theCommands.Add("binsave", "binsave shape filename", __FILE__, writebrep, g);
1746   theCommands.Add("binrestore",
1747                   "alias to readbrep command",
1748                   __FILE__, readbrep, g);
1749
1750   theCommands.Add ("removeinternals", "removeinternals shape [force flag {0/1}]"
1751                    "\n\t\t             Removes sub-shapes with internal orientation from the shape.\n"
1752                    "\n\t\t             Force flag disables the check on topological connectivity and"
1753                                        "removes all internal sub-shapes\n",
1754                   __FILE__, removeInternals, g);
1755 }