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