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