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