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