8a52e995da7097db39da59376b07635f975cb7cc
[occt.git] / src / BOPTest / BOPTest_LowCommands.cxx
1 // File:        BOPTest_LowCommands.cxx
2 // Created:     Wed Mar 28 16:46:22 2001
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6 #include <BOPTest.ixx>
7
8 #include <stdio.h>
9
10 #include <gp_Vec2d.hxx>
11 #include <gp_Pnt2d.hxx>
12 #include <gp_Pnt.hxx>
13
14 #include <Geom2d_Curve.hxx>
15 #include <Geom_Surface.hxx>
16
17 #include <BRep_Tool.hxx>
18 #include <BRep_Builder.hxx>
19 #include <BRep_GCurve.hxx>
20 #include <BRep_TEdge.hxx>
21 #include <BRep_CurveRepresentation.hxx>
22 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
23
24 #include <BRepClass3d_SolidClassifier.hxx>
25 #include <BRepClass_FaceClassifier.hxx>
26
27 #include <TopoDS.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <TopoDS_Iterator.hxx>
33
34 #include <TopTools_MapOfShape.hxx>
35
36 #include <TopLoc_Location.hxx>
37
38 #include <TopExp_Explorer.hxx>
39
40 #include <TopAbs.hxx>
41 #include <TopAbs_State.hxx>
42
43 #include <DBRep.hxx>
44
45 #include <DrawTrSurf.hxx>
46
47 #include <BOPTools_Tools2D.hxx>
48 #include <BOPTools_Tools3D.hxx>
49
50 #include <IntTools_Tools.hxx>
51
52 #include <BOP_Refiner.hxx>
53
54 #include <TCollection_AsciiString.hxx>
55 #include <IntTools_Context.hxx>
56 #include <IntTools_FClass2d.hxx>
57 #include <gp_Pnt2d.hxx>
58 #include <OSD_Chronometer.hxx>
59
60 #include <BRepTools.hxx>
61 #include <BOPTColStd_CArray1OfInteger.hxx>
62
63 static
64   Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
65                                       const TopoDS_Face& F,
66                                       Standard_Real& First,
67                                       Standard_Real& Last);
68 static
69   Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
70                                       const Handle(Geom_Surface)& S,
71                                       const TopLoc_Location& L,
72                                       Standard_Real& First,
73                                       Standard_Real& Last);
74 static
75   void PrintState (Draw_Interpretor& aDI,
76                    const TopAbs_State& aState);
77
78 //modified by NIZNHY-PKV Thu Nov 10 12:11:15 2011f
79 static
80   void DumpArray(const BOPTColStd_CArray1OfInteger& aC,
81                Draw_Interpretor& aDI);
82 //modified by NIZNHY-PKV Thu Nov 10 12:11:18 2011t
83
84 static  Standard_Integer bhaspc      (Draw_Interpretor& , Standard_Integer , const char** );
85 static  Standard_Integer baddve      (Draw_Interpretor& , Standard_Integer , const char** );
86 static  Standard_Integer bisclosed   (Draw_Interpretor& , Standard_Integer , const char** );
87 static  Standard_Integer bexplode    (Draw_Interpretor& , Standard_Integer , const char** );
88 static  Standard_Integer bupdateedge (Draw_Interpretor& , Standard_Integer , const char**);
89 static  Standard_Integer bremovesim  (Draw_Interpretor& , Standard_Integer , const char** );
90 static  Standard_Integer bopsetdisp  (Draw_Interpretor& , Standard_Integer , const char** );
91 static  Standard_Integer bfaceprepare(Draw_Interpretor& , Standard_Integer , const char** );
92 static  Standard_Integer brefine     (Draw_Interpretor& , Standard_Integer , const char** );
93 static  Standard_Integer bclassify   (Draw_Interpretor& , Standard_Integer , const char** );
94 static  Standard_Integer b2dclassify (Draw_Interpretor& , Standard_Integer , const char** );
95
96 static  Standard_Integer bhole       (Draw_Interpretor& , Standard_Integer , const char** );
97 static  Standard_Integer bxhole      (Draw_Interpretor& , Standard_Integer , const char** );
98 //=======================================================================
99 //function : LowCommands
100 //purpose  : 
101 //=======================================================================
102   void  BOPTest::LowCommands(Draw_Interpretor& theCommands)
103 {
104   static Standard_Boolean done = Standard_False;
105   if (done) return;
106   done = Standard_True;
107   // Chapter's name
108   const char* g = "CCR commands";
109   //
110   // Whether Edge has PCurve on Face
111   theCommands.Add("bhaspc"       , "Use >bhaspc Edge Face"    , __FILE__, bhaspc      , g);
112   theCommands.Add("baddve"       , "Use >addve  E V1 V2 p1 p2", __FILE__, baddve      , g);
113   theCommands.Add("bisclosed"    , "Use >bisclosed Edge Face" , __FILE__, bisclosed   , g);
114   theCommands.Add("bexplode"     , ""                         , __FILE__, bexplode    , g);
115   theCommands.Add("bupdateedge"  , "Use bupdateedge Edge Face", __FILE__, bupdateedge , g);
116   theCommands.Add("bremovesim"   , "Use bremovesim Face"      , __FILE__, bremovesim  , g);
117   theCommands.Add("bopsetdisp"   , "Use bopsetdisp"           , __FILE__, bopsetdisp  , g);
118   
119
120   theCommands.Add("bfaceprepare" , "Use bfaceprepare F1 "     , __FILE__, bfaceprepare, g);
121
122   theCommands.Add("brefine"      , "Use brefine Shape "       , __FILE__, brefine     , g);
123   theCommands.Add("bclassify"    , "Use >bclassify Solid Point [Tolerance=1.e-7]",
124                                                                 __FILE__, bclassify   , g);
125   theCommands.Add("b2dclassify"  , "Use >bclassify Face Point2d [Tol2D=Tol(Face)] ",
126                                                                 __FILE__, b2dclassify , g);
127   theCommands.Add("bhole"   , "Use bhole"                     , __FILE__, bhole       , g);
128   theCommands.Add("bxhole"  , "Use bxhole"                    , __FILE__, bxhole      , g);
129 }
130
131 //=======================================================================
132 //function : brefine
133 //purpose  : 
134 //=======================================================================
135 Standard_Integer  brefine (Draw_Interpretor& di,
136                            Standard_Integer n, 
137                            const char** a)
138 {
139   if (n<2) {
140     di << " Use >brefine Shape1\n";
141     return 1;
142   }
143
144   TopoDS_Shape aS = DBRep::Get(a[1]);
145  
146   
147   if (aS.IsNull()) {
148     di << " Null shape is not allowed \n";
149     return 1;
150   }
151
152   Standard_Boolean bIsDone;
153   BOP_Refiner aRefiner;
154   aRefiner.SetShape(aS);
155
156   aRefiner.Do();
157
158   bIsDone=aRefiner.IsDone();
159   
160   if (bIsDone) {
161     Standard_Integer aNbRemovedVertices, aNbRemovedEdges, iFlag=0;
162     aNbRemovedVertices=aRefiner.NbRemovedVertices();
163     aNbRemovedEdges=aRefiner.NbRemovedEdges();
164
165     if (aNbRemovedVertices) {
166       di << " Vertices removed=" << aNbRemovedVertices << "%d\n";
167       iFlag++;
168     }
169
170     if (aNbRemovedEdges) {
171       di << " Edges    removed=" << aNbRemovedEdges << "\n";
172       iFlag++;
173     }
174
175     // REFRESH
176     if (iFlag) {
177       TCollection_AsciiString aNm(a[1]);
178       Standard_CString pstr;
179       
180       pstr=aNm.ToCString();
181       DBRep::Set(pstr, aS);
182     }
183   }
184
185   else {
186     di << "Not Done, err=" << aRefiner.ErrorStatus() << "\n";
187   }
188   return 0;
189 }
190 //=======================================================================
191 //function : bfaceprepare
192 //purpose  : 
193 //=======================================================================
194 Standard_Integer  bfaceprepare(Draw_Interpretor& di, Standard_Integer n, const char** a)
195 {
196   if (n<2) {
197     di << " Use bfaceprepare> F1\n";
198     return 1;
199   }
200
201   TopoDS_Shape S1 = DBRep::Get(a[1]);
202  
203   
204   if (S1.IsNull()) {
205     di << " Null shape is not allowed \n";
206     return 1;
207   }
208   if (S1.ShapeType()!=TopAbs_FACE) {
209     di << " Type mismatch\n";
210     return 1;
211   }
212
213   const TopoDS_Face& aF1=TopoDS::Face(S1);
214
215   TopAbs_Orientation anOr;
216   anOr=aF1.Orientation();
217   if (anOr==TopAbs_FORWARD) {
218     return 0;
219   }
220   //
221   Standard_Real aTol;
222   TopoDS_Face newFace;
223   BRep_Builder aBB;
224   
225   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
226   Handle(Geom_Surface) aS=Handle(Geom_Surface)::DownCast(aS1->Copy());
227   aS->VReverse();
228
229   aTol=BRep_Tool::Tolerance(aF1);
230
231   aBB.MakeFace (newFace, aS, aTol);
232
233   TopExp_Explorer anExp(aF1, TopAbs_WIRE);
234   for (; anExp.More(); anExp.Next()) {
235     const TopoDS_Shape& newWire=anExp.Current();
236     aBB.Add(newFace, newWire);
237   }
238
239   TCollection_AsciiString aNm(a[1]), aNmNew("_r");
240   aNm=aNm+aNmNew;
241   Standard_CString an=aNm.ToCString();
242   di << an << "\n";
243   DBRep::Set(an, newFace); 
244   return 0;
245 }
246 //=======================================================================
247 //function : bopsetdisp
248 //purpose  : 
249 //=======================================================================
250 Standard_Integer bopsetdisp (Draw_Interpretor& di, Standard_Integer , const char** )
251 {
252   Standard_Integer aFlag;
253   
254   char* xr=getenv("MDISP");
255   if (xr==NULL) {
256     aFlag=putenv((char*)"MDISP=yes");
257     di << " MDISP=yes. Return code=" << aFlag << "\n";
258   }
259   else if (!strcmp (xr, "yes")) {
260     aFlag=putenv((char*)"MDISP=no");
261     di << " MDISP=no. Return code=" << aFlag << "\n";
262   }
263   else {
264     aFlag=putenv((char*)"MDISP=yes");
265     di << " MDISP=yes. Return code=" << aFlag << "\n";
266   }
267   
268
269   return 0;
270 }
271 //=======================================================================
272 //function : bremovesim
273 //purpose  : 
274 //=======================================================================
275 Standard_Integer bremovesim (Draw_Interpretor& di, Standard_Integer n, const char** a)
276 {
277   if (n<2) {
278     di << " Use bremovesim> Face\n";
279     return 1;
280   }
281
282   TopoDS_Shape S1 = DBRep::Get(a[1]);
283  
284   
285   if (S1.IsNull()) {
286     di << " Null shapes are not allowed \n";
287     return 1;
288   }
289   if (S1.ShapeType()!=TopAbs_FACE) {
290     di << " Type mismatch\n";
291     return 1;
292   }
293   
294
295   const TopoDS_Face& aF=TopoDS::Face(S1);
296   //
297   IntTools_Context aCtx;
298   BOPTools_Tools3D::RemoveSims (aF, aCtx);
299   //
300   di << " Ok\n";
301   return 0;
302 }
303 //=======================================================================
304 //function : bupdateedge
305 //purpose  : 
306 //=======================================================================
307 Standard_Integer bupdateedge (Draw_Interpretor& di, Standard_Integer n, const char** a)
308 {
309   if (n<3) {
310     di << " Use bupdateedge> Edge Face\n";
311     return 1;
312   }
313
314   TopoDS_Shape S1 = DBRep::Get(a[1]);
315   TopoDS_Shape S2 = DBRep::Get(a[2]);
316   
317   if (S1.IsNull() || S2.IsNull()) {
318     di << " Null shapes are not allowed \n";
319     return 1;
320   }
321   if (S1.ShapeType()!=TopAbs_EDGE || S2.ShapeType()!=TopAbs_FACE) {
322     di << " Type mismatch\n";
323     return 1;
324   }
325   
326   const TopoDS_Edge& aE=TopoDS::Edge(S1);
327   const TopoDS_Face& aF=TopoDS::Face(S2);
328   Handle(Geom2d_Curve) aC2D;
329
330   Standard_Real aTol;
331   aTol=BRep_Tool::Tolerance(aE);
332   BRep_Builder BB;
333   BB.UpdateEdge(aE, aC2D, aF, aTol);
334   di << " Ok\n";
335   return 0;
336 }
337
338 //=======================================================================
339 //function : bisclosed
340 //purpose  : 
341 //=======================================================================
342 Standard_Integer bisclosed (Draw_Interpretor& di, Standard_Integer n, const char** a)
343 {
344   if (n<3) {
345     di << " Use bisclosed> Edge Face\n";
346     return 1;
347   }
348
349   TopoDS_Shape S1 = DBRep::Get(a[1]);
350   TopoDS_Shape S2 = DBRep::Get(a[2]);
351   
352   if (S1.IsNull() || S2.IsNull()) {
353     di << " Null shapes are not allowed \n";
354     return 1;
355   }
356   if (S1.ShapeType()!=TopAbs_EDGE || S2.ShapeType()!=TopAbs_FACE) {
357     di << " Type mismatch\n";
358     return 1;
359   }
360   
361   const TopoDS_Edge& aE=TopoDS::Edge(S1);
362   const TopoDS_Face& aF=TopoDS::Face(S2);
363
364   Standard_Boolean anIsClosed;
365   anIsClosed=BRep_Tool::IsClosed(aE, aF); 
366
367   if (!anIsClosed) {
368     di << " Edge is not closed on this face\n";
369   }
370   else {
371     di << " Edge is closed on this face\n";
372   }
373   return 0;
374 }
375
376 //=======================================================================
377 //function : bhaspc
378 //purpose  : 
379 //=======================================================================
380 Standard_Integer bhaspc (Draw_Interpretor& di, Standard_Integer n, const char** a)
381 {
382   if (n<3) {
383     di << " Use bhaspc> Edge Face [do]\n";
384     return 1;
385   }
386
387   TopoDS_Shape S1 = DBRep::Get(a[1]);
388   TopoDS_Shape S2 = DBRep::Get(a[2]);
389   
390   if (S1.IsNull() || S2.IsNull()) {
391     di << " Null shapes are not allowed \n";
392     return 1;
393   }
394   if (S1.ShapeType()!=TopAbs_EDGE || S2.ShapeType()!=TopAbs_FACE) {
395     di << " Type mismatch\n";
396     return 1;
397   }
398
399   const TopoDS_Edge& aE=TopoDS::Edge(S1);
400   const TopoDS_Face& aF=TopoDS::Face(S2);
401   Standard_Real f2D, l2D; 
402
403   Handle(Geom2d_Curve) C2D=CurveOnSurface(aE, aF, f2D, l2D);
404   
405   if (C2D.IsNull()) {
406     di << " No 2D Curves detected\n";
407   }
408   else {
409     di << " Ok Edge has P-Curve on this Face\n";
410   }
411   
412   if (n==4) {
413     if (!strcmp(a[3], "do")) {
414       BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aF);  
415     }
416   }
417
418   return 0;
419 }
420   
421 //=======================================================================
422 //function : baddve
423 //purpose  : 
424 //=======================================================================
425 Standard_Integer baddve (Draw_Interpretor& di, Standard_Integer n, const char** a)
426 {
427   if (n<6) {
428     di << " Use baddve> E V1 V2 p1 p2\n";
429     return 1;
430   }
431
432   TopoDS_Shape S1 = DBRep::Get(a[1]);
433   TopoDS_Shape S2 = DBRep::Get(a[2]);
434   TopoDS_Shape S3 = DBRep::Get(a[3]);
435   if (S1.IsNull() || S2.IsNull() || S3.IsNull()) {
436     di << " Null shapes are not allowed \n";
437     return 1;
438   }
439
440   if (S1.ShapeType()!=TopAbs_EDGE || 
441       S2.ShapeType()!=TopAbs_VERTEX ||
442       S3.ShapeType()!=TopAbs_VERTEX ) {
443     di << " Type mismatch\n";
444     return 1;
445   }
446   const TopoDS_Edge& aE=TopoDS::Edge(S1);
447   const TopoDS_Vertex& aV1=TopoDS::Vertex(S2);
448   const TopoDS_Vertex& aV2=TopoDS::Vertex(S3);
449
450
451   Standard_Real p1, p2;
452   p1=atof(a[4]);
453   p2=atof(a[5]);
454   
455   TopoDS_Edge E=aE;
456   E.EmptyCopy();
457
458   BRep_Builder BB;
459   BB.Add  (E, aV1);
460   BB.Add  (E, aV2);
461   BB.Range(E, p1, p2);
462
463   DBRep::Set("ne", E);
464   return 0;
465 }
466
467 static Handle(Geom2d_Curve) nullPCurve;
468 //=======================================================================
469 //function : CurveOnSurface
470 //purpose  : 
471 //=======================================================================
472 Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
473                                     const TopoDS_Face& F,
474                                     Standard_Real& First,
475                                     Standard_Real& Last)
476 {
477   TopLoc_Location l;
478   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
479   TopoDS_Edge aLocalEdge = E;
480   if (F.Orientation() == TopAbs_REVERSED) {
481     aLocalEdge.Reverse();
482   }
483   return CurveOnSurface(aLocalEdge,S,l,First,Last);
484 }
485
486 //=======================================================================
487 //function : CurveOnSurface
488 //purpose  : 
489 //=======================================================================
490 Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
491                                     const Handle(Geom_Surface)& S,
492                                     const TopLoc_Location& L,
493                                     Standard_Real& First,
494                                     Standard_Real& Last)
495 {
496   TopLoc_Location l = L.Predivided(E.Location());
497   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
498
499   // find the representation
500   BRep_ListIteratorOfListOfCurveRepresentation itcr
501     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
502
503   while (itcr.More()) {
504     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
505     if (cr->IsCurveOnSurface(S,l)) {
506       const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
507       GC->Range(First,Last);
508       if (GC->IsCurveOnClosedSurface() && Eisreversed)
509         return GC->PCurve2();
510       else
511         return GC->PCurve();
512     }
513     itcr.Next();
514   }
515   return nullPCurve;
516 }
517
518 //=======================================================================
519 //function : bexplode
520 //purpose  : 
521 //=======================================================================
522 static Standard_Integer bexplode(Draw_Interpretor& di,
523                                  Standard_Integer n, 
524                                  const char** a)
525 {
526   if (n <= 1) return 1;
527   TopoDS_Shape S = DBRep::Get(a[1]);
528   if (S.IsNull()) return 0;
529   char newname[1024];
530   strcpy(newname,a[1]);
531   char* p = newname;
532   while (*p != '\0') p++;
533   *p = '_';
534   p++;
535   Standard_Integer i = 0;
536   if (n == 2) {
537     TopoDS_Iterator itr(S);
538     while (itr.More()) {
539       i++;
540       sprintf(p,"%d",i);
541       DBRep::Set(newname,itr.Value());
542       di.AppendElement(newname);
543       itr.Next();
544     }
545   }
546   else {
547     // explode a type
548     TopAbs_ShapeEnum typ;
549     switch (a[2][0]) {
550       
551     case 'C' :
552     case 'c' :
553       if ((a[2][1] == 'd')||(a[2][1] == 'D')) 
554         typ = TopAbs_COMPOUND;
555       else
556         typ = TopAbs_COMPSOLID;
557       break;
558       
559     case 'S' :
560     case 's' :
561       if ((a[2][1] == 'O')||(a[2][1] == 'o')) 
562         typ = TopAbs_SOLID;
563       else if ((a[2][1] == 'H')||(a[2][1] == 'h')) 
564         typ = TopAbs_SHELL;
565       else
566         return 1;
567       break;
568       
569     case 'F' :
570     case 'f' :
571       typ = TopAbs_FACE;
572       break;
573       
574     case 'W' :
575     case 'w' :
576       typ = TopAbs_WIRE;
577       break;
578       
579     case 'E' :
580     case 'e' :
581       typ = TopAbs_EDGE;
582       break;
583       
584     case 'V' :
585     case 'v' :
586       typ = TopAbs_VERTEX;
587       break;
588       
589       default :
590         return 1;
591     }
592     
593     
594     TopExp_Explorer ex(S,typ);
595     for (; ex.More(); ex.Next()) {
596       const TopoDS_Shape& aS = ex.Current();
597       i++;
598       sprintf(p,"%d",i);
599       DBRep::Set(newname,aS);
600       di.AppendElement(newname);
601     }
602   }
603   return 0;
604 }
605
606 //=======================================================================
607 //function : bclassify
608 //purpose  : 
609 //=======================================================================
610 Standard_Integer bclassify (Draw_Interpretor& aDI,
611                             Standard_Integer n, 
612                             const char** a)
613 {
614   char sbf[512];        
615   
616   if (n < 3) {
617     sprintf(sbf, " Use >bclassify Solid Point [Tolerance=1.e-7]\n");
618     aDI<<sbf;
619     return 1;
620   }
621   
622   TopoDS_Shape aS = DBRep::Get(a[1]);
623   if (aS.IsNull()) {
624     sprintf(sbf, " Null Shape is not allowed here\n");
625     aDI<<sbf;
626     return 1;
627   }
628   
629   if (aS.ShapeType()!=TopAbs_SOLID) {
630     sprintf(sbf, " Shape type must be SOLID\n");
631     aDI<<sbf;
632     return 1;
633   }
634   //
635   Standard_Real aTol=1.e-7;
636   TopAbs_State aState = TopAbs_UNKNOWN;
637   gp_Pnt aP(8., 9., 10.);
638   
639   DrawTrSurf::GetPoint(a[2], aP);
640   
641   aTol=1.e-7; 
642   if (n==4) {
643     aTol=atof(a[3]);
644   }
645   //
646   BRepClass3d_SolidClassifier aSC(aS);
647   aSC.Perform(aP,aTol);
648   //
649   aState = aSC.State();
650   //
651   PrintState (aDI, aState);
652   //
653   return 0;
654 }
655 //
656 //=======================================================================
657 //function : b2dclassify
658 //purpose  : 
659 //=======================================================================
660 Standard_Integer b2dclassify (Draw_Interpretor& aDI,
661                               Standard_Integer n, 
662                               const char** a)
663 {
664   char sbf[512];        
665   
666   if (n < 3) {
667     sprintf(sbf, " Use >bclassify Face Point2d [Tol2D=Tol(Face)]\n");
668     aDI<<sbf;
669     return 1;
670   }
671   
672   TopoDS_Shape aS = DBRep::Get(a[1]);
673   if (aS.IsNull()) {
674     sprintf(sbf, " Null Shape is not allowed here\n");
675     aDI<<sbf;
676     return 1;
677   }
678   
679   if (aS.ShapeType()!=TopAbs_FACE) {
680     sprintf(sbf, " Shape type must be FACE\n");
681     aDI<<sbf;
682     return 1;
683   }
684   //
685   Standard_Real aTol;
686   TopAbs_State aState = TopAbs_UNKNOWN;
687   gp_Pnt2d aP(8., 9.);
688   
689   DrawTrSurf::GetPoint2d(a[2], aP);
690   
691   const TopoDS_Face& aF=TopoDS::Face(aS);
692   aTol=BRep_Tool::Tolerance(aF); 
693   if (n==4) {
694     aTol=atof(a[3]);
695   }
696   //
697   BRepClass_FaceClassifier aClassifier;
698   aClassifier.Perform(aF, aP, aTol);
699   //
700   aState = aClassifier.State();
701   //
702   PrintState (aDI, aState);
703   //
704   return 0;
705 }
706 //=======================================================================
707 //function : PrintState
708 //purpose  : 
709 //=======================================================================
710 void PrintState (Draw_Interpretor& aDI,
711                  const TopAbs_State& aState)
712 {
713   char sbf[512];        
714   TCollection_AsciiString sIN("IN"), sOUT("OUT of"), sON("ON"), sUNKNOWN("UNKNOWN"); 
715   //
716   sprintf(sbf, "The point is "); aDI<<sbf;
717   //
718   switch (aState) {
719   case TopAbs_IN:               
720     sprintf(sbf, sIN.ToCString());
721     break;
722   case TopAbs_OUT:              
723     sprintf(sbf, sOUT.ToCString());
724     break;
725   case TopAbs_ON:               
726     sprintf(sbf, sON.ToCString());
727     break;
728   case TopAbs_UNKNOWN:          
729     sprintf(sbf, sUNKNOWN.ToCString());
730     break;
731   default:
732     sprintf(sbf, sUNKNOWN.ToCString()); 
733     break;
734   }
735   aDI<<sbf; 
736         //
737   sprintf(sbf, " shape\n");
738   aDI<<sbf;
739   
740 }
741 //
742 //=======================================================================
743 //function : bhole
744 //purpose  : 
745 //=======================================================================
746 Standard_Integer bhole (Draw_Interpretor& aDI,
747                         Standard_Integer n, 
748                         const char** a)
749 {
750   char sbf[512];        
751   
752   if (n!=2) {
753     sprintf(sbf, " Use bhole Face\n");
754     aDI<<sbf;
755     return 1;
756   }
757   
758   TopoDS_Shape aS = DBRep::Get(a[1]);
759   if (aS.IsNull()) {
760     sprintf(sbf, " Null Shape is not allowed here\n");
761     aDI<<sbf;
762     return 1;
763   }
764   
765   if (aS.ShapeType()!=TopAbs_FACE) {
766     sprintf(sbf, " Shape type must be FACE\n");
767     aDI<<sbf;
768     return 1;
769   }
770   //
771   Standard_Boolean bIsHole;
772   Standard_Real aTol=1.e-7;
773   IntTools_FClass2d aFClass2d;
774   //
775   const TopoDS_Face& aF=TopoDS::Face(aS);
776   aTol=BRep_Tool::Tolerance(aF); 
777   //
778   aFClass2d.Init(aF, aTol);
779   //
780   bIsHole=aFClass2d.IsHole();
781   printf(" bIsHole=%d\n", bIsHole);
782   //
783   return 0;
784 }
785 //
786
787
788 //
789 //=======================================================================
790 //class : X_Chr
791 //purpose  : 
792 //=======================================================================
793 class X_Chr {
794  public:
795 //  X_Chr::X_Chr() {
796   X_Chr() {
797     Reset();
798   }
799   void Reset() {
800     myTime=0.;
801     myCnt=0;
802   }
803   void Start() {
804     myChronometer.Reset();
805     myChronometer.Start();
806   }
807   void Stop() {
808     Standard_Real aTime;
809     //
810     myChronometer.Stop();
811     myChronometer.Show(aTime);
812     myTime=myTime+aTime;
813     ++myCnt;
814   }
815   void Show(const char *pComment) {
816     printf("  Tps: %7.2lf\tCnt: %d\tfor %s\n", myTime, myCnt, pComment);
817   }
818   
819  protected:
820   Standard_Real myTime;
821   Standard_Integer myCnt;
822   OSD_Chronometer myChronometer;
823   
824 };
825
826 //
827 //=======================================================================
828 //function : bxhole
829 //purpose  : 
830 //=======================================================================
831 Standard_Integer bxhole (Draw_Interpretor& aDI,
832                          Standard_Integer n, 
833                          const char** a)
834 {
835   char sbf[512];        
836   Standard_Integer aNbIter;
837   //
838   if (n!=3) {
839     sprintf(sbf, " Use bxhole Face NbIter\n");
840     aDI<<sbf;
841     return 1;
842   }
843   
844   TopoDS_Shape aS = DBRep::Get(a[1]);
845   if (aS.IsNull()) {
846     sprintf(sbf, " Null Shape is not allowed here\n");
847     aDI<<sbf;
848     return 1;
849   }
850   if (aS.ShapeType()!=TopAbs_FACE) {
851     sprintf(sbf, " Shape type must be FACE\n");
852     aDI<<sbf;
853     return 1;
854   }
855   //
856   aNbIter=atoi(a[2]);
857   if (aNbIter<1) {
858     aNbIter=1;
859   }
860   //
861   Standard_Integer i;
862   Standard_Boolean bIsHole;
863   Standard_Real aTol, aUMin, aUMax, aVMin, aVMax;
864   gp_Pnt2d aP2DInf;
865   TopAbs_State aState;
866   X_Chr aChr;
867   //
868   aTol=1.e-7;
869   const TopoDS_Face& aF=TopoDS::Face(aS);
870   aTol=BRep_Tool::Tolerance(aF); 
871   //
872   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
873   aP2DInf.SetCoord(aUMin, aVMin);
874   //
875   // 1. New
876   aChr.Reset();
877   aChr.Start();
878   for (i=1; i<=aNbIter; ++i) {
879     IntTools_FClass2d aFClass2d;
880     //
881     aFClass2d.Init(aF, aTol);
882     //
883     bIsHole=aFClass2d.IsHole();
884   }
885   aChr.Stop();
886   aChr.Show(" new");
887   printf(" new bIsHole=%d\n", bIsHole);
888   //``````````````````````````````````````````
889   aChr.Reset();
890   aChr.Start();
891   for (i=1; i<=aNbIter; ++i) {
892     IntTools_FClass2d aFClass2d;
893     //
894     aFClass2d.Init(aF, aTol);
895     //
896     aState=aFClass2d.Perform(aP2DInf);
897     bIsHole=(aState==TopAbs_IN);
898   }
899   aChr.Stop();
900   aChr.Show(" was");
901   printf(" was bIsHole=%d\n", bIsHole);
902   //
903   return 0;
904 }