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