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